本文档介绍了 fzf 动态重载输入数据和与外部命令集成的功能。这些功能使用户能够创建交互式工作流,其中项目列表可以按需或自动刷新,并且 fzf 可以根据用户的选择执行外部命令。
fzf 提供了多种机制与外部命令交互并动态更新其输入
这些功能使得 fzf 能够成为其他命令行工具的交互式界面,从而实现强大的工作流。
来源: ADVANCED.md162-164 src/actiontype_string.go123-136
reload 操作允许 fzf 通过执行任意命令来动态更新其候选列表。这使得创建交互式界面成为可能,这些界面可以在不重启 fzf 的情况下刷新其数据。
reload 操作可以使用 --bind 选项绑定到按键或事件。触发时,fzf 将执行指定的命令,并将其输出作为新的候选列表。
示例
fzf --bind 'ctrl-r:reload(ls)'
这会将 Ctrl-R 绑定到使用 ls 命令的输出来重载列表。
除了按键绑定之外,reload 还可以绑定到 fzf 事件,例如 start 和 change。
启动事件 (Start Event):fzf 启动时执行命令
fzf --bind 'start:reload(ls)'
更改事件 (Change Event):查询字符串更改时执行命令
fzf --bind 'change:reload(find . -name "{q}*")'
命令中的 {q} 占位符会被当前查询字符串替换,从而允许基于用户输入进行动态过滤。
来源: ADVANCED.md346-356 ADVANCED.md402-405
当将 reload 绑定到 change 事件时,通常需要添加一个小的延迟来减少键入时的命令执行次数。
fzf --bind 'change:reload:sleep 0.1; find . -name "{q}*" || true'
sleep 0.1 在执行命令前添加 100 毫秒的延迟,而 || true 确保即使命令失败 fzf 也会继续执行。
fzf 提供了多个用于集成外部命令的操作,允许用户根据其选择执行命令。
fzf 提供了三种用于执行外部命令的操作:
execute:执行命令并显示其输出execute-silent:执行命令而不显示其输出execute-multi:为每个选定的项目执行命令这些操作可以使用 --bind 选项绑定到按键。
fzf --bind 'enter:execute(echo {})'
在命令字符串中,可以使用以下占位符:
{}:当前选定的项目{+}:所有选定的项目,空格分隔{q}:当前查询字符串来源: ADVANCED.md572-577 src/actiontype_string.go117-119
become 操作(fzf 0.38.0 中引入)允许 fzf 将自身转换为另一个进程。这对于创建无缝工作流非常有用,其中 fzf 用于选择,然后将其交接给另一个程序。
fzf --bind 'enter:become(vim {})'
当触发 become 操作时,fzf 将以一个特殊退出码退出,并由指定的命令代替它执行,该命令继承 fzf 的终端会话。
内部而言,become 操作的工作方式如下:
.become 后缀的临时文件。ExitBecome)退出。来源: src/proxy.go20-161 ADVANCED.md338-341
一个常见的用例是创建一个交互式的进程查看器,该查看器可以按需刷新。
(date; ps -ef) |
fzf --bind='ctrl-r:reload(date; ps -ef)' \
--header='Press CTRL-R to reload' --header-lines=2 \
--preview='echo {}' --preview-window=down,3,wrap
这会显示一个进程列表,可以通过按 Ctrl-R 来刷新。
您可以设置多个重载绑定来在不同数据源之间切换。
find * | fzf --prompt 'All> ' \
--header 'CTRL-D: Directories / CTRL-F: Files' \
--bind 'ctrl-d:change-prompt(Directories> )+reload(find * -type d)' \
--bind 'ctrl-f:change-prompt(Files> )+reload(find * -type f)'
这允许在列出所有文件、仅列出目录或仅列出常规文件之间进行切换。
一个强大的应用是使用 fzf 作为 Ripgrep 的交互式接口。
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case "
fzf --ansi --disabled --query "$INITIAL_QUERY" \
--bind "start:reload:$RG_PREFIX {q}" \
--bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
--bind 'enter:become(vim {1} +{2})'
这创建了一个交互式 grep 界面,其中:
来源: ADVANCED.md357-371 ADVANCED.md400-412
预览窗口可以显示外部命令的输出,为选定的项目提供上下文。
--preview 选项指定一个为每个选定项目运行的命令。
fzf --preview 'cat {}'
这会在预览窗口中显示选定文件的内容。
预览窗口可以使用 follow 标志显示长时间运行命令的实时更新。
fzf --preview-window follow --preview 'tail -f {}'
这对于监控日志文件或其他持续更新的内容特别有用。
来源: ADVANCED.md547-558 ADVANCED.md575-576
一个实用的例子是创建一个交互式 Kubernetes Pod 查看器。
fzf --info=inline --layout=reverse --header-lines=1 \
--prompt "$(kubectl config current-context)> " \
--header 'Enter (kubectl exec) / CTRL-O (open log in editor) / CTRL-R (reload)' \
--bind 'start,ctrl-r:reload:kubectl get pods --all-namespaces' \
--bind 'enter:execute:kubectl exec -it --namespace {1} {2} -- bash' \
--bind 'ctrl-o:execute:${EDITOR:-vim} <(kubectl logs --all-containers --namespace {1} {2})' \
--preview-window up:follow \
--preview 'kubectl logs --follow --all-containers --tail=10000 --namespace {1} {2}'
这创建了一个交互式界面,用于:
fzf 使用事件驱动的架构来处理用户输入和触发重载、执行等操作。
来源: test/test_core.rb123-136 src/actiontype_string.go117-136
fzf 的终端处理和外部命令执行实现了跨平台支持。
实现包括特定于平台的代码,用于:
来源: src/tui/light_unix.go1-134 src/tui/light_windows.go1-166 src/tui/ttyname_unix.go1-55 src/tui/ttyname_windows.go1-22
become 操作通过特殊的退出码和临时文件来实现。
.become 后缀的临时文件。ExitBecome) 退出。这使得从 fzf 到另一个进程的无缝过渡成为可能。
sleep 来绑定到 change 事件,以减少命令执行次数。|| true 处理命令失败,以确保即使命令失败,fzf 也能继续运行。操作可以使用 + 操作符组合,以创建复杂行为。
fzf --bind 'ctrl-r:change-prompt(Ripgrep> )+reload(rg {q})'
这会更改提示符,并使用单个按键绑定重新加载列表。
对于更复杂的工作流程,您可以使用临时文件来维护命令之间的状态。
fzf --bind 'ctrl-t:transform-query:echo {q} > /tmp/state; cat /tmp/other-state'
这允许复杂的状态转换和模式切换。
来源: ADVANCED.md460-463 ADVANCED.md486-502
fzf 的动态重新加载和外部命令集成功能使其成为创建交互式命令行界面的强大工具。通过将这些功能与 fzf 的模糊查找能力相结合,用户可以构建复杂的、提高生产力的工作流程,并简化复杂的任务。
有关相关功能的更多信息,请参阅