1## 2# The "keeper" function suite originally appeared in several zsh-users 3# posts in the fall of 2004. It was published in summary form in the 4# Shell Corner column on UnixReview.com in January 2005 at the URL 5# <http://www.unixreview.com/documents/s=9513/ur0501a/ur0501a.htm> 6# 7# Article still available on the Wayback Machine: 8# <http://web.archive.org/web/20050207041146/http://www.unixreview.com/documents/s=9513/ur0501a/ur0501a.htm> 9# 10# A few minor edits have been made to those functions for this file. Key 11# bindings are commented out to avoid clashes with any existing bindings. 12## 13 14declare -a kept 15 16# The "keep" function accepts a set of file patterns as the positional 17# parameters or a series of lines (expected to represent file names) on 18# standard input. It stores the expansion of those patterns, or the input 19# lines, in the global variable $kept, and then displays the result 20# formatted in columns, similar to an "ls" listing. Its alias, also named 21# "keep", prevents the file patterns from being expanded when the command 22# line is executed; they're expanded in the assignment to $kept instead, 23# so that the local settings of nonomatch etc. are applied. 24 25function keep { 26 setopt localoptions nomarkdirs nonomatch nocshnullglob nullglob 27 setopt noksharrays noshwordsplit 28 kept=($~*) 29 if [[ ! -t 0 ]]; then 30 local line 31 while read -r line; do 32 kept+=( $line ) 33 done 34 fi 35 print -Rc - ${^kept%/}(T) 36} 37alias keep='noglob keep' 38 39# The function "_insert_kept" copies the value of $kept to the cursor 40# position. If a prefix of a name is immediately to the left of the 41# cursor, then only the subset of $kept that matches that prefix is 42# copied, as is usual for completion. The examples bind it to two 43# different widgets, "insert-kept-result" and "expand-kept-result". If 44# invoked via the "expand-kept-result" widget, it replaces a pattern on 45# the command line with the matching words from the $kept array. 46 47_insert_kept() { 48 (( $#kept )) || return 1 49 local action 50 zstyle -s :completion:$curcontext insert-kept action 51 if [[ -n $action ]] 52 then compstate[insert]=$action 53 elif [[ $WIDGET = *expand* ]] 54 then compstate[insert]=all 55 fi 56 if [[ $WIDGET = *expand* ]] 57 then compadd -U ${(M)kept:#${~words[CURRENT]}} 58 else compadd -a kept 59 fi 60} 61 62zle -C insert-kept-result complete-word _generic 63zstyle ':completion:insert-kept-result:*' completer _insert_kept 64# bindkey '^Xk' insert-kept-result 65 66zle -C expand-kept-result complete-word _generic 67zstyle ':completion:expand-kept-result:*' completer _insert_kept 68# bindkey '^XK' expand-kept-result 69 70# The "_expand_word_and_keep" function stores the expansions computed by 71# the "_expand" completer in the global $kept for later retrieval by 72# "_insert_kept". 73 74_expand_word_and_keep() { 75 { 76 function compadd { 77 local -A args 78 zparseopts -E -A args J: 79 if [[ $args[-J] == all-expansions ]] 80 then 81 builtin compadd -A kept "$@" 82 kept=( ${(Q)${(z)kept}} ) 83 fi 84 builtin compadd "$@" 85 } 86 _expand_word 87 } always { 88 unfunction compadd 89 } 90} 91 92zle -C _expand_word complete-word _expand_word_and_keep 93 94# This style is required to segregate the all-expansions group for 95# purposes of _expand_word_and_keep. 96zstyle ':completion:expand-word:expand:::all-expansions' group-name '' 97