如何在 zsh 中使用 fzf 获得模糊 xdg-open?

pes*_*der 6 shell zsh fzf

问题

我一直在尝试使用fzf绑定快捷方式(最好是Ctrl+ o)以交互方式搜索文件并将其通过管道传输到xdg-openzsh 中。fzf只要您获取位于fzf/shell/key-bindings.zsh中的文件,许多快捷方式就已经是该实用程序的一部分。在那里,您将找到用于绑定Ctrl+r模糊搜索命令历史记录和Ctrl+t模糊完成当前命令行的片段。这是 fzf 源代码中第一个快捷方式的样子:

# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
  local selected num
  setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
  selected=( $(fc -rl 1 | perl -ne 'print if !$seen{(/^\s*[0-9]+\**\s+(.*)/, $1)}++' |
    FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
  local ret=$?
  if [ -n "$selected" ]; then
    num=$selected[1]
    if [ -n "$num" ]; then
      zle vi-fetch-history -n $num
    fi
  fi
  zle reset-prompt
  return $ret
}
zle     -N   fzf-history-widget
bindkey '^R' fzf-history-widget
Run Code Online (Sandbox Code Playgroud)

当然,它的行为与我想要的行为有点不同,因为它将选定的结果粘贴到命令行,而不是直接通过管道将其传递到命令。不过,下面的 bash 脚本恰恰具有我所期望的行为,并且运行它比我自己在解释它方面做得更好。

bind -x '"\C-o": file="$(fzf --height 40% --reverse)" && [ -f "$file" ] && xdg-open "$file"'
Run Code Online (Sandbox Code Playgroud)

我还发现这个Fish 函数具有相同的行为,但 Fish 的语法与 zsh 和 bash 等符合 POSIX 的 shell 有很大不同,所以我不知道它的参考作用有多大。

那么,有谁知道将Ctrl+绑定o到交互式 fzf 搜索,并将其结果直接通过管道传输到xdg-openzsh 中?

提前致谢!


答案

这是一个工作脚本,是我根据 Stack Overflow 答案编写

fuzzy-xdg-open() {
  local output
  output=$(fzf --height 40% --reverse </dev/tty) && xdg-open ${(q-)output}
  zle reset-prompt
}

zle -N fuzzy-xdg-open
bindkey '^o' fuzzy-xdg-open
Run Code Online (Sandbox Code Playgroud)

Mar*_*ert 0

这种键绑定在普通中不能直接实现。但是,如果您安装了zsh-edit插件,则可以使用以下命令:

bind '^O' 'file="$(fzf --height 40% --reverse)" && [ -f "$file" ] && xdg-open "$file"'
Run Code Online (Sandbox Code Playgroud)