我正在尝试以以下方式使用fzf,我希望能够在我的代码库中搜索一个词,然后在预览窗口中能够查看包含我正在搜索的字符串的文件在找到该字符串的行上。
到目前为止,我已经通过管道对目录及以下目录中的所有文件进行ripgrep搜索来设法模糊搜索整个代码库中的各种术语。而且我使用cut来解析出cat或tail的文件名,以读取并打印到预览窗口。这是用于此的命令。
rg . -n | fzf --preview-"cut -d":" -f1 <<< {} | xargs cat"
请注意,用{}表示的字符串具有以下格式:
myfile.c:72:The string I am fuzzy searching
我的问题是我无法解析文件名和行号。
我尝试在预览命令中传递bashscript以及在以下示例中使用$()。 (请注意,这里我将tail与--lines+N
参数一起使用以在N行之后打印文件)
rg . -n | fzf --preview-"tail $(cut -d":" -f1 <<< {}) --lines=+$(cut -d":" -f2 <<< {})"
这不起作用,此尝试也没有多种变体。感谢您的任何帮助或反馈。
编辑(1):
我试图像这样将其拆分为一个数组
rg . -n | fzf --preview="IFS=":" read -r -a arr <<< {}| xargs tail ${arr[0]} --lines=+${arr[1]}"
这是因为预览确实会在找到字符串的行显示文件,但是当我循环浏览其他模糊的建议时,文件不会更新。
答案 0 :(得分:2)
所以我最终找到了一个可行的解决方案。
它涉及从在--preview内部运行的子进程中调用单独的脚本。我使用以下脚本获取fzf传递给--preview的字符串(格式为filename:linenumber:found_string),然后使用bat来渲染突出显示语法的预览窗口。
此方法非常好,但是会占用大量资源。我希望通过添加到ignore glob并使用ripgrep来减轻负担,而不是发现它似乎更有效。
我称之为bashscript的string2arg.sh
#!/bin/bash
string2arg() {
export arg_filename=$(cut -d":" -f1 <<< $1);
export arg_linenum=$(cut -d":" -f2 <<< $1);
min_offset=25
let max_offset="min_offset*3"
min=0
if (($min_offset < $arg_linenum)); then
let min="arg_linenum-$min_offset"
fi
let max="arg_linenum+$max_offset"
bat --color=always --highlight-line $arg_linenum --style=header,grid,numbers --line-range $min:$max $arg_filename;
}
然后从我的fzf别名中调用它,以进行如下搜索:
alias fsearch='rg . -n -g "!*.html" | fzf --preview="source $SC/string2arg.sh; string2arg {}"'
其中$ SC是我的bashscript string2arg.sh的路径。
如果我要搜索一个旨在打开其找到的文件的术语,则使用以下bash别名。
alias vfsearch='export vfile=$(fsearch);vim +$(cut -d":" -f2 <<< $vfile) $(cut -d":" -f1 <<< $vfile)'
我也碰巧将以下默认值用于 fzf并找到它们为我工作,尽管自从我移到tmux以来,我发现有时最好在上方而不是侧面显示预览窗口。
export FZF_DEFAULT_COMMAND="fd --type file --color=always"
export FZF_DEFAULT_OPTS="--reverse --inline-info --ansi"
export FZF_COMPLETION_TRIGGER=']]'
我发现这非常有用,并且正计划在我的vim会话中移动它。希望对别人有帮助!
截屏以更好地说明用例。