fzf 中的多进程 bash -- 预览功能

问题描述 投票:0回答:2

我正在尝试以下列方式使用 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]}"

这是因为预览确实在找到字符串的行显示了文件,但是当我循环浏览其他模糊发现的建议时它不会更新。

bash cut xargs fzf
2个回答
9
投票

所以我最终想出了一个可行的解决方案。

它涉及从我在 --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 会话中。希望它能帮助别人!

截图以更好地说明用例。


0
投票

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
的任何文件中。

© www.soinside.com 2019 - 2024. All rights reserved.