Bash

在通過鍵綁定使用 fzf 進行模糊搜尋後將選定的候選人填充到終端?

  • June 4, 2020

使用這個外掛,我們可以模糊搜尋 apt 包的候選者。

執行它的輸出如下:

# apt zzuf zziplib-bin zytrax

連結中的程式碼(我放入 if [[ "${BASH_<...> fi一個函式my-fuzzy-test):

#!/usr/bin/env bash
function insert_stdin {
   # if this wouldn't be an external script
   # we could use 'print -z' in zsh to edit the line buffer
   stty -echo
   perl -e 'ioctl(STDIN, 0x5412, $_) for split "", join " ", @ARGV;' \
       "$@"
}
function my-fuzzy-test() {
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
   packages="$(apt list --verbose 2>/dev/null | \
       # remove "Listing..."
       tail --lines +2 | \
       # place the description on the same line
       # separate the description and the other information
       # with a ^
       sd $'\n {2}([^ ])' $'^$1' | \
       # place the package information and the package description
       # in a table with two columns
       column -t -s^ | \
       # select packages with fzf
       fzf --multi | \
       # remove everything except the package name
       cut --delimiter '/' --fields 1 | \
       # escape selected packages (to avoid unwanted code execution)
       # and remove line breaks
       xargs --max-args 1 --no-run-if-empty printf "%q ")"

   if [[ -n "${packages}" ]]; then
       insert_stdin "# apt ${@}" "${packages}"
   fi
fi
}

我將上面的程式碼放入~/.zshrc並映射my-fuzzy-test到鍵綁定:

zle -N my-fuzzy-test
bindkey "^[k" my-fuzzy-test

作為按下alt-k觸發my-fuzzy-test功能,按下時什麼也不顯示alt-k。如果我刪除行if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; thenfi在最後,那麼它可以觸發該功能,但它不能像上面那樣顯示預期的輸出並回顯錯誤stty: 'standard input': Inappropriate ioctl for device

我知道我們可以將候選人填充到終端的提示符中,如下程式碼所示:

# 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 $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

那麼我怎樣才能正確地將候選人填充到終端的提示中my-fuzzy-test呢?

該 Ctrl-R 小元件用於zle vi-fetch-history插入歷史匹配,這不適用於您在此處執行的操作。

您需要做的是將您生成的匹配插入到編輯緩衝區中,正如此處相同程式碼中的另一個小元件所做的那樣:https ://github.com/junegunn/fzf/blob/master/shell/key -bindings.zsh#L62

echo該小元件將由函式編輯的匹配項插入__fsel緩衝區左側的右側(意思是,它將它們插入游標的目前位置,然後,游標將結束在插入內容的右側) :

LBUFFER="${LBUFFER}$(__fsel)"

引用自:https://unix.stackexchange.com/questions/590362