about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-02-24 14:44:28 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-02-24 14:44:28 +0000
commit6785dcb5c920b6be812b4d1a70ce53ed47ff2f30 (patch)
tree332ee00c91dbd07c7982465fb61dd6dbebe95cc5
parent01ffe47e012deb204dc74a3fff794f8b4a3ec795 (diff)
downloadzsh-6785dcb5c920b6be812b4d1a70ce53ed47ff2f30.tar.gz
zsh-6785dcb5c920b6be812b4d1a70ce53ed47ff2f30.tar.xz
zsh-6785dcb5c920b6be812b4d1a70ce53ed47ff2f30.zip
zsh-workers/9865
-rw-r--r--Completion/Builtins/_zstyle1
-rw-r--r--Completion/Core/_main_complete15
-rw-r--r--Completion/Core/_setup2
-rw-r--r--Doc/Zsh/compsys.yo17
-rw-r--r--Src/Zle/compcore.c15
-rw-r--r--Src/Zle/compresult.c15
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;