我使用 oh-my-zsh,并且有很多我不记得的别名和函数,所以我用它alias ag="alias | grep"
来找出别名的作用。我也用别名提示。但我不想只获取别名的命令,而是希望有一种方法grep 别名和函数的描述以及别名的命令。不过如果能把所有功能都显示出来那就更好了。
我想过使用 grep 来获取上一行,如果它是注释,我可以显示它。但我通常把注释放在同一行,除非别名太长。因此,我必须检查前一行和同一行的注释才能获取描述。
我还考虑过将所有别名和函数及其描述放在一个由某个字符分隔的文件中,并使用该文件进行 grep。但这样我就不得不重复很多代码。
答案1
我使用 fzf 作为我的函数查找器。您也许可以扩展它以包含别名?
看https://gist.github.com/tg0h/e301584f435023fae66c77675bdb6e4d完整注释的代码。
在左侧,fzf 交互式查找器列出了我的所有函数以及该函数的简短描述。右侧,fzf 预览窗口显示我的函数的预览。
不幸的是,我正在进行重构,所以我的函数查找器目前已损坏。
食谱
弗兹夫
- 使用 fzf 模糊查找您的函数 fzf 的交互式查找器显示您的所有函数,而 fzf 的预览窗口可用于详细显示您的函数
蝙蝠
- 使用bat通过语法高亮显示您的函数
功能定义
- 使用特定格式和描述函数功能的注释行来定义函数。这将有助于您稍后使用 ripgrep 查找函数。
ripgrep
- 使用 ripgrep 做 2 件事
对于 中的每个函数
<function folder>
,提供其 a。文件名,b.函数名称,c.功能评论。作为 fzf 的单行。这将显示在 fzf 的交互式文件查找器中(在我的屏幕截图的左侧)对于每个函数,找到其文件名及其起始行号和结束行号,以便您可以将其提供给 bat。然后可以使用bat来预览文件中的函数。 (如我的屏幕截图右侧所示)
这将涉及一些正则表达式巫术,但如果您统一定义函数,则会变得更简单,请参阅下文了解更多详细信息。
细节
1. 使用标准格式编写函数
以这种格式编写函数可以更轻松地进行 ripgrepping。
# I do not omit the function keyword
function hello(){
# this function says hello (only the first comment line after the function will be used to be shown in fzf)
# this comment will not be shown in fzf's interactive finder (left of screenshot) later
echo hello world
}
2. 如何找到所有函数(稍后提供给 fzf)
假设我的函数遵循上述格式,我使用 ripgrep 解析函数文件夹中的所有文件以提取
- 文件名
- 函数名
- 功能说明
使用这个:
_fzf_home_getFunctions(){
# -e '^\s*function\s+(?P<fname>[^\s(]+)'
# [^\s(] - anything that is not a space or a (
# the regex searches for function, whitespace, and then uses a named capturing
# group of a word character
# exclude commented functions
rg \
--follow \
--type zsh \
--color always \
--field-context-separator '' \
--no-context-separator \
--only-matching -e '^\s*function\s+(?P<fname>([^\s(]+))' -r '$fname' -A 1 \
--field-match-separator ' ' \
$_fzf_homeFn_dir \
| gsed -E 's!(\s*)(#)!\2!' \
| gsed "s!$_fzf_homeFn_dir!!" \
| gsed 'N;s/\n/ /' \
| gawk '{$3="-"; print}'
}
注意:我使用 gsed 和 gawk 而不是 sed 和 awk
3. 如何设置 fzf 函数预览器
_fzf_home_displayFunction(){
# given inputFile and inputFunc, use bat to display function body
#
# reads file and func
# outputs file funcStartLineNumber funcEndLineNumber
local inputFile=$1
local inputFunc=$2
local file=$_fzf_homeFn_dir$inputFile
rg --only-matching \
--multiline \
-nH \
-e '\s*function\s+'$inputFunc'\s*\(''(?s:.)*?(^\s*}$)' $file \
| gsed '1b;$!d' | gsed 'N;s/\n/ /' \
| rg '(?::)(\d+)(?::)' -or '$1' | join-lines | read -r funcStart funcEnd _
bat --color=always $_fzf_homeFn_dir$inputFile -r $funcStart:$funcEnd
}
4. 最后,向 fzf 提供您的函数并设置预览器
作为奖励,我还设置了一个键盘映射来直接从 nvim 编辑功能。请参阅我的要点以了解血淋淋的细节。
fzf-search-home-function-widget(){
local result=$(
_fzf_home_getFunctions | fzf --ansi \
--preview="_fzf_home_displayFunction {1} {2}" \
--bind "ctrl-e:execute(_fzf_home-function_nvim_edit {1} {2} < /dev/tty > /dev/tty 2>&1)"
)
zle reset-prompt;
LBUFFER+=$result
}