ZSH_FZF_HISTORY_SEARCH_FZF_ARGS and
ZSH_FZF_HISTORY_SEARCH_FZF_EXTRA_ARGS may contain multiple arguments
separated by spaces that need to be expanded to build the command line
for fzf. This is currently done by calling a subshell and letting
echo handle it.
Unlike other shells, zsh does not do word splitting by default.
According to zshexpn(1) you can perform word splitting using the rules
for SH_WORD_SPLIT by using the ${=spec} construct. Avoid creating a
subshell and just expand the spaces.
41 lines
1.1 KiB
Bash
41 lines
1.1 KiB
Bash
# do nothing if fzf is not installed
|
|
(( ! $+commands[fzf] )) && return
|
|
|
|
# Bind for fzf history search
|
|
(( ! ${+ZSH_FZF_HISTORY_SEARCH_BIND} )) &&
|
|
typeset -g ZSH_FZF_HISTORY_SEARCH_BIND='^r'
|
|
|
|
# Args for fzf
|
|
(( ! ${+ZSH_FZF_HISTORY_SEARCH_FZF_ARGS} )) &&
|
|
typeset -g ZSH_FZF_HISTORY_SEARCH_FZF_ARGS='+s +m -x -e'
|
|
|
|
# Extra args for fzf
|
|
(( ! ${+ZSH_FZF_HISTORY_SEARCH_FZF_EXTRA_ARGS} )) &&
|
|
typeset -g ZSH_FZF_HISTORY_SEARCH_FZF_EXTRA_ARGS=''
|
|
|
|
# Cursor to end-of-line
|
|
(( ! ${+ZSH_FZF_HISTORY_SEARCH_END_OF_LINE} )) &&
|
|
typeset -g ZSH_FZF_HISTORY_SEARCH_END_OF_LINE=''
|
|
|
|
fzf_history_search() {
|
|
setopt extendedglob
|
|
candidates=(${(f)"$(fc -li -1 0 | fzf ${=ZSH_FZF_HISTORY_SEARCH_FZF_ARGS} ${=ZSH_FZF_HISTORY_SEARCH_FZF_EXTRA_ARGS} -q "$BUFFER")"})
|
|
local ret=$?
|
|
if [ -n "$candidates" ]; then
|
|
BUFFER="${candidates[@]/(#m)*/${${(As: :)MATCH}[4,-1]}}"
|
|
BUFFER="${BUFFER[@]/(#b)(?)\\n/$match[1]
|
|
}"
|
|
zle vi-fetch-history -n $BUFFER
|
|
if [ -n "${ZSH_FZF_HISTORY_SEARCH_END_OF_LINE}" ]; then
|
|
zle end-of-line
|
|
fi
|
|
fi
|
|
zle reset-prompt
|
|
return $ret
|
|
}
|
|
|
|
autoload fzf_history_search
|
|
zle -N fzf_history_search
|
|
|
|
bindkey $ZSH_FZF_HISTORY_SEARCH_BIND fzf_history_search
|