#autoload # This completer function is intended to be used as the first completer # function and allows one to say more explicitly when and how the word # from the line should be expanded than expand-or-complete. # This function will allow other completer functions to be called if # the expansions done produce no result or do not change the original # word from the line. # # Configuration keys: # # expand_substitute # If this is unset or set to the empty string, the code will first # try to expand all substitutions in the string (such as $(...) and # ${...}). If this is set to an non-empty string it should be # an expression usable inside a $[...] arithmetical expression. # In this case, expansion of substitutions will be done if the # expression evaluates to `1'. For example, with # # compconf expand_substitute='NUMERIC != 1' # # substitution will be performed only if given an explicit numeric # argument other than `1', as by typing ESC 2 TAB. # # expand_glob # If this is unset or set to an empty string, globbing will be # attempted on the word resulting from substitution or the # original string. The values accepted for this key are the same # as for expand_substitute. # # expand_menu # If this is unset or set to the empty string, the words resulting # from expansion (if any) will simply be inserted in the ommand line, # replacing the original string. However, if this key is set to an # non-empty string, the user can cycle through the expansion as in # a menucompletion. Unless the value contains the sub-string `only', # the user will still be offered all expansions at once as one of # the strings to insert in the command line. Also, if the value # contains the sub-string `last', the string with all expansion will # be offered first, whereas normally it is offered as the last string # to insert. Finally, if the value contains the sub-string `sort', # the expansions will be sorted alphabetically, normally they are # kept in the order the expansion produced them in. # # expand_original # If this is set to an non-empty string, the original string from the # line will be included in the list of strings the user can cycle # through as in a menucompletion. If the value contains the sub-string # `last', the original string will appear as the last string, with # other values it is inserted as the first one (so that the command # line does not change immediatly). # # expand_prompt # This may be set to a string that should be displayed before the # possible expansions. This is given to the -X option and thus may # contain the control sequences `%n', `%B', etc. Also, the sequence # `%o' in this string will be replaced by the original string. local exp word="$PREFIX$SUFFIX" group=-V # Do this only for the first global matcher. [[ "$compstate[matcher]" -le 1 ]] || return 1 # In exp we will collect the expansion. exp=("$word") # First try substitution. That weird thing spanning multiple lines # changes quoted spaces, tabs, and newlines into spaces. [[ -z "$compconfig[expand_substitute]" || "${(e):-\$[$compconfig[expand_substitute]]}" -eq 1 ]] && exp=( "${(e)exp//\\[ ]/ }" ) # If the array is empty, store the original string again. [[ -z "$exp" ]] && exp=("$word") # Now try globbing. [[ -z "$compconfig[expand_glob]" || "${(e):-\$[$compconfig[expand_glob]]}" -eq 1 ]] && exp=( ${~exp}(N) ) # If we don't have any expansions or only one and that is the same # as the original string, we let other completers run. [[ $#exp -eq 0 || ( $#exp -eq 1 && "$exp[1]" = "$word" ) ]] && return 1 # We have expansions, should we menucomplete them? if [[ -z "$compconfig[expand_menu]" ]]; then # No, so if the user only wants a list, we add the strings # separately. Otherwise we add the whole array as one string, # probably also adding the original string. if [[ -z "$compstate[insert]" ]]; then compadd -U -V _expand -Q - "$exp[@]" else [[ -n "$compconfig[expand_original]" && "$compconfig[expand_original]" != *last* ]] && compadd -UnQ -V _expand_original - "$word" compadd -UQ -V _expand - "$exp" [[ -n "$compconfig[expand_original]" && "$compconfig[expand_original]" = *last* ]] && compadd -UnQ -V _expand_original - "$word" compstate[insert]=menu fi else # Sorting? We just use a different group type then. [[ "$compconfig[expand_menu]" = *sort* ]] && group=-J # Now add the expansion string, probably also adding the original # and/or the string containing all expanded string. [[ -n "$compconfig[expand_original]" && "$compconfig[expand_original]" != *last* ]] && compadd -UnQ -V _expand_original - "$word" [[ "$compconfig[expand_menu]" = *last* && "$compconfig[expand_menu]" != *only* ]] && compadd -UnQ -V _expand_all - "$exp" if [[ -z "$compconfig[expand_prompt]" ]]; then compadd -UQ $group _expand - "$exp[@]" else compadd -UQ -X "${compconfig[expand_prompt]//\%o/$word}" \ $group _expand - "$exp[@]" fi [[ "$compconfig[expand_menu]" != *last* && "$compconfig[expand_menu]" != *only* ]] && compadd -UnQ -V _expand_all - "$exp" [[ -n "$compconfig[expand_original]" && "$compconfig[expand_original]" = *last* ]] && compadd -UnQ -V _expand_original - "$word" compstate[insert]=menu fi return 0