diff options
-rw-r--r-- | Completion/Commands/_verbose_list | 75 | ||||
-rw-r--r-- | Completion/Core/_oldlist | 20 | ||||
-rw-r--r-- | Doc/Zsh/compsys.yo | 48 |
3 files changed, 137 insertions, 6 deletions
diff --git a/Completion/Commands/_verbose_list b/Completion/Commands/_verbose_list new file mode 100644 index 000000000..b3d762ecc --- /dev/null +++ b/Completion/Commands/_verbose_list @@ -0,0 +1,75 @@ +#compdef -k delete-char-or-list \C-xv + +# You probably want to bind this to Control-D. + +local odf="$compconfig[description_format]" +local omf="$compconfig[message_format]" +local ogm="$compconfig[group_matches]" +local oop="$compconfig[option_prefix]" +local odo="$compconfig[describe_options]" +local odv="$compconfig[describe_values]" +local what nm + +(( $# )) || set -- ${(s.:.)compconfig[verboselist_stages]} + +if [[ "$BUFFER" != "$_vl_buffer" || "$*" != "$_vl_config" ]]; then + _vl_buffer="$BUFFER" + _vl_config="$*" + _vl_array=( "$@" ) + _vl_index=1 + if (( ! $#_vl_array )); then + [[ -n "$compconfig[option_prefix]" ]] && _vl_array=(options) + [[ -z "$compconfig[describe_options]" || + -z "$compconfig[describe_options]" ]] && + _vl_array=( "$_vl_array[@]" options-describe ) + + _vl_array=( "$_vl_array[@]" normal ) + fi + if [[ -z "$compstate[old_list]" ]]; then + if (( $_vl_array[(I)normal] )); then + _vl_index="$_vl_array[(I)normal]" + else + _vl_array=( normal "$_vl_array[@]" ) + fi + fi +fi + +# If we had a possibility to say `ignore all matches added up to now', +# we could de-comment these thigs and wouldn't have the problem that +# if the options were already the stage `options' is a somewhat +# irritating no-op. +# Or maybe we make the completion functions report if they added +# options/description one day. + +# while true; do + what="$_vl_array[_vl_index++]" + [[ _vl_index -gt $#_vl_array ]] && _vl_index=1 + + if [[ "$what" != normal ]]; then + [[ -z "$odf" ]] && compconfig[description_format]='---- %d' + [[ -z "$omf" ]] && compconfig[message_format]='---- %d' + [[ -z "$ogm" ]] && compconfig[group_matches]=yes + [[ "$what" = *options* ]] && compconfig[option_prefix]='' + if [[ "$what" = *describe* ]]; then + compconfig[describe_options]=yes + compconfig[describe_values]=yes + fi + fi + + if [[ -n "$compstate[old_list]" ]]; then + nm="$_lastcomp[nmatches]" + else + nm=-1 + fi + + _main_complete + +# [[ "$what" != options || compstate[nmatches] -ne nm ]] && break +# done + +compconfig[description_format]="$odf" +compconfig[message_format]="$omf" +compconfig[group_matches]="$ogm" +compconfig[option_prefix]="$oop" +compconfig[describe_options]="$odo" +compconfig[describe_values]="$odv" diff --git a/Completion/Core/_oldlist b/Completion/Core/_oldlist index bdf12f90c..2efc08119 100644 --- a/Completion/Core/_oldlist +++ b/Completion/Core/_oldlist @@ -27,13 +27,23 @@ fi # If this is a completion widget, and we have a completion inserted already, # and the compconfig key oldlist_menu is not never, then we cycle through the # existing list (even if it was generated by another widget). -if [[ -n $compstate[old_insert] && $WIDGET = *complete(|-prefix|-word) && - $compconfig[oldlist_menu] != never ]]; then + +if [[ $compconfig[oldlist_menu] = verbose && + $LASTWIDGET = _verbose_list && $WIDGET != _verbose_list && + -z $compstate[old_insert] && + -n $compstate[old_list] ]]; then compstate[old_list]=keep - if [[ $WIDGET = *reverse* ]]; then - compstate[insert]=$(( compstate[old_insert] - 1 )) +elif [[ $WIDGET = *complete(|-prefix|-word) && + $compconfig[oldlist_menu] != (never|verbose) ]]; then + if [[ -n $compstate[old_insert] ]]; then + compstate[old_list]=keep + if [[ $WIDGET = *reverse* ]]; then + compstate[insert]=$(( compstate[old_insert] - 1 )) + else + compstate[insert]=$(( compstate[old_insert] + 1 )) + fi else - compstate[insert]=$(( compstate[old_insert] + 1 )) + return 1 fi return 0 fi diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index f904dbe47..f14ab4799 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1075,6 +1075,22 @@ Once a string has been read, the next call to tt(_read_comp) will use the existing string instead of reading a new one. To force a new string to be read, call tt(_read_comp) with a numeric argument. ) +item(tt(_verbose_list) (^Xv))( +This widget behaves like the builtin tt(delete-char-or-list) widget +but if called repeatedly with the same command line, it will make the +completion list more and more verbose. The default behavior is to +first show options even if the tt(option_prefix) configuration key is +set and to show option and value descriptions, too, on the next +invocation. Using the tt(verboselist_stages) configuration key it is +possible to change this default behavior, see +ifzman(the section `Completion System Configuration' below)\ +ifnzman(noderef(Completion System Configuration)). Also, the +tt(_oldlist) completer has support for this command, which is +described in the entry for the tt(oldlist_menu) configuration key. + +Since this widget normally behaves like tt(delete-char-or-list) you +may find it convenient to bind it to tt(^D). +) enditem() texinode(Completion System Configuration)()(Bindable Commands)(Completion System) @@ -1339,7 +1355,37 @@ For example, suppose you type tt(^Xc) to generate a list of corrections, and menu completion is started in one of the usual ways. Usually, typing tt(TAB) at this point would start trying to complete the line as it now appears. With tt(_oldlist), it will instead continue to cycle through the -list of completions. +list of completions. + +With this key, the tt(_oldlist) completer also has additional support +for the tt(_verbose_list) bindable command: when it is set to +tt(verbose), invoking the tt(_oldlist) completer after a different +list has been shown by calling the tt(_verbose_list) command will make +completion re-use this list, so that, for example, menu completion +will be started when the tt(AUTO_LIST) option is set. +) +item(tt(verboselist_stages))( +This key is used by the tt(_verbose_list) bindable command to find out +when options or descriptions should be shown. It is a colon-separated +list of the keywords tt(normal), tt(options) and tt(describe). The +keywords are used in the order in which they appear to describe what +should be listed on the next call to the widget (with an unchanged +command line). The value tt(normal) says that the list should be +generated as defined by the normal settings of the configuration +keys, the value tt(options) says that options should be listed even if +the tt(option_prefix) configuration key is set, and tt(describe) says +that options and values should be described. The last two can be +combined as in tt(describe-options) to make both options being listed +and options and values being described. + +For example, if tt(option_prefix) is set to any non-empty value, +tt(describe_options) is not set and tt(verboselist_stages) is set to +tt(describe:normal) invoking the tt(_verbose_list) widget with a list +being shown will replace this list with a list containing also option +names that are possible matches and will also make these options be +described if possible. Consecutively invoking the tt(_verbose_list) +widget will then toggle between the normal list form and the extra +verbose one. ) item(tt(path_expand))( This is used by the tt(_path_files) function which is used throughout |