답변:
history-incremental-multi-search
을위한zsh
디렉토리를 작성하여 디렉토리에 포함하십시오. $fpath
예를 들어, 디렉토리를 작성하고 my ~/.zsh/functions
행 fpath=($HOME/.zsh/functions $fpath)
을 작성하십시오 .zshrc
.
history-incremental-multi-search
해당 디렉토리에 이름이 지정된 파일에 다음을 입력하십시오 .
emulate -L zsh
setopt extended_glob
local oldbuffer=$BUFFER
local -i oldcursor=$CURSOR
local dir # search direction
local chars # input buffer
local -a words # search terms
local -a found # all history items that match first term
local -i hindex=$HISTNO # current
local -i lmatch # last matched history item (for prev/next)
if [[ $WIDGET == *forward* ]]; then
dir=fwd
else
dir=bck
fi
function find-next {
# split the input buffer on spaces to get search terms
words=(${(s: :)chars})
# if we have at least one search term
if (( $#words )); then
# get all keys of history items that match the first
found=(${(k)history[(R)*$words[1]*]})
if (( $#found )); then
# search in widget direction by default
# but accept exception in $1 for "prev match"
search-${1:-$dir}
else
# no matches
lmatch=$HISTNO
fi
else
# no search terms
lmatch=$HISTNO
BUFFER=$oldbuffer
CURSOR=$oldcursor
fi
}
function search-fwd {
# search forward through matches
local -i i
for (( i = $#found; i > 0; i-- )); do
# but not before hindex as we're searching forward
if [[ $found[$i] -gt $hindex ]]; then
set-match $found[$i]
fi
done
}
function search-bck {
# search backward through matches
local -i i
for (( i = 1; i <= $#found; i++ )); do
# but not beyond hindex as we're searching backward
if [[ $found[$i] -lt $hindex ]]; then
set-match $found[$i]
fi
done
}
function set-match {
# match history item against all terms and select it if successful
local match=1
local -i i
for (( i = 2; i <= $#words; i++ )); do
if [[ $history[$1] != *$words[$i]* ]]; then
match=0
break
fi
done
if [[ $match -ne 0 ]]; then
lmatch=$1
BUFFER=$history[$1]
CURSOR=$#BUFFER
break
fi
}
# display sub prompt
zle -R "${dir}-i-search-multi:"
# handle input keys
while read -k; do
case $REPLY in
# next
$'\C-n' )
hindex=$lmatch
find-next
;;
# prev
$'\C-p' )
hindex=$lmatch
if [[ $dir == fwd ]]; then
find-next bck
else
find-next fwd
fi
;;
# break
$'\e' | $'\C-g' )
BUFFER=$oldbuffer
CURSOR=$oldcursor
break
;;
# accept
$'\C-m' | $'\C-j' )
if [[ $lmatch -eq $HISTNO ]]; then
BUFFER=$oldbuffer
CURSOR=$oldcursor
else
HISTNO=$lmatch
fi
break
;;
# erase char
$'\C-h' | $'\C-?' )
chars=$chars[1,-2]
hindex=$HISTNO
find-next
;;
# erase word
$'\C-w' )
if [[ $chars =~ \ ]]; then
chars=${chars% *}
else
chars=
fi
hindex=$HISTNO
find-next
;;
# kill line
$'\C-u' )
chars=
hindex=$HISTNO
find-next
;;
# add unhandled chars to buffer
* )
chars=${chars}${REPLY}
hindex=$HISTNO
find-next
;;
esac
zle -R "${dir}-i-search-multi: $words"
done
이것을 넣거나 당신의 출처에서 찾으십시오 .zshrc
:
autoload -U history-incremental-multi-search
# make new widgets from function
zle -N history-incremental-multi-search-backward history-incremental-multi-search
zle -N history-incremental-multi-search-forward history-incremental-multi-search
# bind the widgets to keys
bindkey '^Xr' history-incremental-multi-search-backward
bindkey '^Xs' history-incremental-multi-search-forward
이제와 역방향 증분 검색을 시작할 수 있어야 Ctrl+X, r앞으로와를 Ctrl+X, s.
검색어를 공백으로 구분하여 입력하십시오. 다음 키를 사용하여 제어 할 수 있습니다.
← Backspace: 문자 지우기
Ctrl+W: 단어 지우기
Ctrl+U: 킬 라인
Ctrl+N: 다음 경기
Ctrl+P: 이전 경기
Ctrl+G/ Esc: 검색 취소
Enter: 동의하기
이 솔루션은 아마도 상당히 단순화 될 수 있습니다. 개선의 여지가 많은 기능적인 개념 증명입니다.
@peth의 답변을 바탕으로 :
Zsh와 함께 제공 history-incremental-pattern-search-backward
되므로 직접 정의 할 필요가 없습니다. 키 바인딩을 추가하십시오. ^R
다음 줄을 추가하여 재정의하는 것을 선호 합니다 .zshrc
.
bindkey '^R' history-incremental-pattern-search-backward
이제 검색에 glob (exex가 아닌 sic!) 연산자를 사용할 수 있습니다.