From 6785dcb5c920b6be812b4d1a70ce53ed47ff2f30 Mon Sep 17 00:00:00 2001 From: Tanaka Akira Date: Thu, 24 Feb 2000 14:44:28 +0000 Subject: zsh-workers/9865 --- Completion/Builtins/_zstyle | 1 + Completion/Core/_main_complete | 15 +++++++++++---- Completion/Core/_setup | 2 +- Doc/Zsh/compsys.yo | 17 +++++++++++++++++ Src/Zle/compcore.c | 15 +++++++++------ Src/Zle/compresult.c | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Completion/Builtins/_zstyle b/Completion/Builtins/_zstyle index 10f624ed3..9d77612fc 100644 --- a/Completion/Builtins/_zstyle +++ b/Completion/Builtins/_zstyle @@ -50,6 +50,7 @@ styles=( packageset c:packageset path 'c:_path_files -/' ports c:_ports + prefer-ignored c:bool prefix-hidden c:bool prefix-needed c:bool prompt c: diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete index 739ce2898..a5acb36f7 100644 --- a/Completion/Core/_main_complete +++ b/Completion/Core/_main_complete @@ -19,7 +19,7 @@ setopt localoptions nullglob rcexpandparam extendedglob unsetopt markdirs globsubst shwordsplit nounset ksharrays -local comp post ret=1 tmp _compskip format _comp_ignore \ +local ctxt post ret=1 tmp _compskip format _comp_ignore \ _completers _completer _completer_num \ _matchers _matcher _matcher_num \ context state line opt_args val_args curcontext="$curcontext" \ @@ -66,7 +66,14 @@ _completers=( "$@" ) _completer_num=1 for _completer; do - zstyle -a ":completion:${curcontext/::/:${_completer[2,-1]}-${(M)#_completers[1,_completer_num]:#$_completer}:}:" matcher-list _matchers || + ctxt=":completion:${curcontext/::/:${_completer[2,-1]}-${(M)#_completers[1,_completer_num]:#$_completer}:}:" + + if zstyle -t "$ctxt" prefer-ignored && (( $compstate[alternate_nmatches] )); then + ret=0 + break; + fi + + zstyle -a "$ctxt" matcher-list _matchers || _matchers=( '' ) _matcher_num=1 @@ -82,7 +89,6 @@ done if zstyle -s ":completion:${curcontext}:" single-ignored tmp && [[ $compstate[old_list] != shown && - $compstate[nmatches] = 0 && $compstate[alternate_nmatches] = 1 ]]; then case "$tmp" in show) compstate[insert]='' compstate[list]='list force' tmp='' ;; @@ -99,7 +105,8 @@ fi if [[ -n "$tmp" || $compstate[old_list] = keep || $compstate[nmatches]+$compstate[alternate_nmatches] -gt 1 ]]; then - [[ _last_nmatches -ge 0 && _last_nmatches -ne compstate[nmatches] ]] && + [[ _last_nmatches -ge 0 && + _last_nmatches -ne $compstate[nmatches]+$compstate[alternate_nmatches ]] && _menu_style=( "$_last_menu_style[@]" "$_menu_style[@]" ) if [[ "$compstate[insert]" = "$_saved_insert" ]]; then diff --git a/Completion/Core/_setup b/Completion/Core/_setup index 408b5abfe..5d63b97ce 100644 --- a/Completion/Core/_setup +++ b/Completion/Core/_setup @@ -62,7 +62,7 @@ fi _menu_style=( "$_last_menu_style[@]" "$_menu_style[@]" ) if zstyle -a ":completion:${curcontext}:$1" menu val; then - _last_nmatches="$nm" + _last_nmatches=$(( $nm + $compstate[alternate_nmatches] )) _last_menu_style=( "$val[@]" ) else _last_nmatches=-1 diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 65c850c9c..0f4fac35f 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -1267,6 +1267,23 @@ A style holding the service names of ports to complete. If this is not set by the user, the service names from `tt(/etc/services)' will be used. ) +item(tt(prefer-ignored))( +This style is tested by the main completion function before calling a +completer. The context name is formed in the same way as for the +tt(matcher-list) style, i.e. it contains the name of the completer +that will be called plus a hyphen and the number of the call to that +completer. + +If the style is set to true and completion did not generate any normal +matches yet, but there are matches that were ignored because they +matched one of the patterns given with the tt(fignore) array or the +tt(ignored-patterns) style, these ignored matches are used immediatly +and no other completer will be called. + +It is sometimes useful to set this style for the tt(correct) or +tt(approximate) completer so that ignored matches are prefered over +corrections. +) item(tt(prefix-hidden))( This is used when matches with a common prefix are added (e.g. option names). If it is `true', this prefix will not be shown in the list of diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 3e4d4c93c..b0ee2b1d0 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -163,10 +163,10 @@ mod_export struct cldata listdat; /**/ mod_export int ispattern, haspattern; -/* Non-zero if at least one match was added without -U. */ +/* Non-zero if at least one match was added without/with -U. */ /**/ -mod_export int hasmatched; +mod_export int hasmatched, hasunmatched; /* The current group of matches. */ @@ -304,7 +304,7 @@ do_completion(Hookdef dummy, Compldat dat) startauto = isset(AUTOMENU); movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1); showinglist = 0; - hasmatched = 0; + hasmatched = hasunmatched = 0; minmlen = 1000000; maxmlen = -1; @@ -1522,9 +1522,12 @@ addmatches(Cadata dat, char **argv) /* Switch back to the heap that was used when the completion widget * was invoked. */ SWITCHHEAPS(compheap) { - if ((doadd = (!dat->apar && !dat->opar && !dat->dpar)) && - (dat->aflags & CAF_MATCH)) - hasmatched = 1; + if ((doadd = (!dat->apar && !dat->opar && !dat->dpar))) { + if (dat->aflags & CAF_MATCH) + hasmatched = 1; + else + hasunmatched = 1; + } if (dat->apar) aparl = newlinklist(); if (dat->opar) diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index e5d0617ef..64de5c744 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -610,6 +610,7 @@ do_ambiguous(void) do_ambig_menu(); } else if (ainfo) { int atend = (cs == we), la, eq, tcs; + VARARR(char, old, we - wb); minfo.cur = NULL; minfo.asked = 0; @@ -617,11 +618,25 @@ do_ambiguous(void) fixsuffix(); /* First remove the old string from the line. */ + tcs = cs; cs = wb; + memcpy(old, (char *) line + wb, we - wb); foredel(we - wb); /* Now get the unambiguous string and insert it into the line. */ cline_str(ainfo->line, 1, NULL); + + /* Sometimes the different match specs used may result in a cline + * that is shorter than the original string. If that happened, we + * re-insert the old string. Unless there were matches added with + * -U, that is. */ + if (lastend - wb < we - wb && !hasunmatched) { + cs = wb; + foredel(lastend - wb); + inststrlen(old, 0, we - wb); + lastend = we; + cs = tcs; + } if (eparq) { tcs = cs; cs = lastend; -- cgit 1.4.1