#compdef -K _history-complete-older complete-word \e/ _history-complete-newer complete-word \e, # # Complete words from the history # # by Adam Spiers, with help gratefully received from # Sven Wischnowsky and Bart Schaefer # # Available styles: # # list -- display lists of available matches # stop -- prevent looping at beginning and end of matches during # menu-completion # sort -- sort matches lexically (default is to sort by age) # remove-all-dups -- # remove /all/ duplicate matches rather than just consecutives # range -- range of history words to complete _history_complete_word () { setopt localoptions ${_comp_options[@]} local expl direction stop curcontext="$curcontext" local max slice hmax=$#historywords if [[ -z "$curcontext" ]]; then curcontext=history-words::: else curcontext="history-words${curcontext#*:}" fi if [[ $WIDGET = *newer ]]; then direction=newer else direction=older fi zstyle -s ":completion:${curcontext}:history-words" stop stop zstyle -t ":completion:${curcontext}:history-words" list || compstate[list]='' if zstyle -s ":completion:${curcontext}:history-words" range max; then if [[ $max = *:* ]]; then slice=${max#*:} max=${max%:*} else slice=$max fi [[ max -gt hmax ]] && max=$hmax else max=$hmax slice=$max fi if [[ ( -n "$compstate[old_list]" || ( $LASTWIDGET = _history-complete-* && -n $_hist_stop ) ) && ( -n "$stop" || "$compstate[insert]" = menu ) ]]; then if [[ "$direction" == older ]]; then if [[ $_hist_stop = new ]]; then PREFIX=$_hist_old_prefix _history_complete_word_gen_matches compstate[insert]=2 _hist_stop= elif [[ $_hist_stop = old ]]; then PREFIX=$_hist_old_prefix _history_complete_word_gen_matches compstate[insert]=1 _hist_stop= elif [[ compstate[old_insert] -lt _hist_menu_length ]]; then compstate[old_list]=keep (( compstate[insert] = compstate[old_insert] + 1 )) else _hist_stop=old _message 'beginning of history reached' return 1 fi elif [[ "$direction" == 'newer' ]]; then if [[ $_hist_stop = old ]]; then PREFIX=$_hist_old_prefix _history_complete_word_gen_matches compstate[insert]=$(( $compstate[nmatches] - 1 )) _hist_stop= elif [[ $_hist_stop = new ]]; then PREFIX=$_hist_old_prefix _history_complete_word_gen_matches compstate[insert]=$compstate[nmatches] _hist_stop= elif [[ compstate[old_insert] -gt 1 ]]; then compstate[old_list]=keep (( compstate[insert] = compstate[old_insert] - 1 )) else _hist_stop=new _message 'end of history reached' return 1 fi fi return 0 else _hist_stop= _hist_old_prefix="$PREFIX" _history_complete_word_gen_matches fi (( $compstate[nmatches] )) } _history_complete_word_gen_matches () { local opt beg=2 [[ -n "$_hist_stop" ]] && PREFIX="$_hist_old_prefix" if zstyle -t ":completion:${curcontext}:history-words" remove-all-dups; then opt=- else opt=-1 fi if zstyle -t ":completion:${curcontext}:history-words" sort; then opt="${opt}J" else opt="${opt}V" fi PREFIX="$IPREFIX$PREFIX" IPREFIX= SUFFIX="$SUFFIX$ISUFFIX" ISUFFIX= while [[ $compstate[nmatches] -eq 0 && beg -lt max ]]; do _main_complete - history _wanted "$opt" history-words expl 'history word' \ compadd -Q -a 'historywords[beg,beg+slice]' (( beg+=slice )) done zstyle -t ":completion:${curcontext}:history-words" list || compstate[list]= _hist_menu_length="$compstate[nmatches]" case "$direction" in newer) compstate[insert]=$_hist_menu_length [[ -n "$_hist_stop" ]] && (( compstate[insert]-- )) ;; older) compstate[insert]=1 [[ -n "$_hist_stop" ]] && (( compstate[insert]++ )) ;; esac [[ -n "$_hist_stop" ]] && _hist_stop='' } _history_complete_word "$@"