我正在尝试以下列方式使用 fzf,我希望能够在我的代码库中搜索一个术语,然后在预览窗口中能够看到包含我正在搜索的字符串的文件 在该行在哪里找到字符串.
到目前为止,我已经设法通过管道对目录及目录下的所有文件进行 ripgrep 搜索,在代码库中模糊搜索各种术语。而且我已经使用 cut 解析出 cat 或 tail 的文件名以读取并打印到预览窗口。这是用于此的命令。
rg . -n | fzf --preview-"cut -d":" -f1 <<< {} | xargs cat"
注意{}表示的字符串格式如下:
myfile.c:72:The string I am fuzzy searching
我的问题是我无法解析出文件名和行号。
我尝试在预览命令中传递 bashscript,并在以下示例中使用 $()。 (请注意,这里我使用带
--lines+N
参数的tail来打印第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]}"
这是因为预览确实在找到字符串的行显示了文件,但是当我循环浏览其他模糊发现的建议时它不会更新。
所以我最终想出了一个可行的解决方案。
它涉及从我在 --preview 中运行的子进程中调用一个单独的脚本。我使用以下脚本获取 fzf 传递给 --preview 的字符串(格式为文件名:行号:found_string),然后使用 bat 渲染带有语法高亮的预览窗口。
这个方法很不错,但有点耗费资源。我希望通过添加到 ignore glob 并使用 ripgrep 而不是 find 来减轻负载,因为它看起来更有效。
我调用的 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 会话中。希望它能帮助别人!
截图以更好地说明用例。
fzf
命令可以为您拆分所选项目:
-d, --delimiter=STR Field delimiter regex (default: AWK-style)
另外,您可以在寻呼机上设置偏移量,在您的情况下是
bat
,
--preview-window=OPT Preview window layout (default: right:50%)
对于您的用例,带有额外选项的命令将是:
$ rg . -n | fzf --ansi --border --reverse --delimiter=: \
--preview 'bat --color always {1} -n -H {2}' \
--preview-window 'top,80%,border-bottom,+{2}+3/3'
输出将是这样的:
README.md:119:
合并它们我自己做了如下:
# nff nvim find files
# usage:
# nff file_ext content
#
# example:
# to find `install` in md files:
# nff md install
# and then hit enter on the fzf list will open nvim on the line number in selected list
function nff() {
file_line=`rg "$2" -i --no-ignore --no-heading --column --color ansi -g \*.$1 |
fzf --ansi --border --reverse --delimiter=: \
--preview 'bat --color always {1} -n -H {2}' \
--preview-window 'top,80%,border-bottom,+{2}+3/3'`
file=`echo "$file_line" | gawk -F: '{print $1}'`
line=`echo "$file_line" | gawk -F: '{print $2}'`
if [[ -n $file ]]; then
nvim +"$line" "$file"
fi
}
你可以把上面的代码放在你的
.bashrc
,.zshrc
,或者你用来启动你的shell
的任何文件中。