和这个插件我们可以通过 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}" ]]; then
和fi
,那么它可以触发该函数,但它无法显示上面的预期输出并回显错误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
?
答案1
该 Ctrl-R 小部件用于zle vi-fetch-history
插入历史匹配项,这不适用于您在这里所做的事情。
您需要做的是将生成的匹配插入到编辑缓冲区中,就像此处相同代码中的另一个小部件所做的那样:https://github.com/junegunn/fzf/blob/master/shell/key-bindings.zsh#L62
echo
该小部件将函数插入的匹配项__fsel
插入到缓冲区左侧部分的右侧(也就是说,它将它们插入到光标的当前位置,然后,光标将最终到达插入内容的右侧) :
LBUFFER="${LBUFFER}$(__fsel)"