With this plugin we can fuzzy search through candidates of apt packages.
the output of running it as below:
# apt zzuf zziplib-bin zytrax
The code in the link (I put if [[ "${BASH_<...> fi
to a function 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
}
I put above code in ~/.zshrc
and map my-fuzzy-test
to a keybinding:
zle -N my-fuzzy-test
bindkey "^[k" my-fuzzy-test
as press alt-k
to trigger my-fuzzy-test
function, it showed nothing when press alt-k
.
If I remove line if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
and fi
at the end, then it can trigger the function but it can't display expected output as above and echoes error stty: 'standard input': Inappropriate ioctl for device
I know we can populate candidates into terminal's prompt as in this code as below:
# 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
So how can I correctly populate candidate to terminal's prompt with my-fuzzy-test
?
Best Answer
That Ctrl-R widget uses
zle vi-fetch-history
to insert history matches, which is not applicable to what you're doing here.What you need to do is insert the matches you've generated into the editing buffer, as is done by another widget in the same code over here: https://github.com/junegunn/fzf/blob/master/shell/key-bindings.zsh#L62
That widget inserts the matches
echo
ed by the function__fsel
into the right side of the left part of the buffer (meaning, it inserts them into the current position of the cursor and then, afterwards, the cursor will end up to the right of what's inserted):