Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Conflict between *:foo:_files and -o:bar:_files



On Fri, 7 Mar 2008 14:33:23 +0100
Haakon Riiser <haakon.riiser@xxxxxxxxxx> wrote:
> For this, I've tried
> 
>   _arguments -S \
>     '-o:output file:_files' \
>     '*:input file:_files'
> 
> For some reason, calling the app as
> 
>   $ app input -o <PRESS-TAB-HERE>
> 
> and then using ZSH's completion system to generate alternatives
> for -o, the _files completer is called twice with two different
> descriptions:
> 
>   output file
>   file1 file2 file3 (etc)
>   input file
>   file1 file2 file3 (etc)

(Posting this to zsh-users as a help request rather than zsh-workers as a
bug report earns you the award "optimist of the week".)

I tracked this down through the uncommented mess of shell functions to
the uncommented mess of C support files below that.  I've put in quite a
specific fix: if there are similar cases where _arguments is completing
too much it should be possible to change the code again without the
two-hour battle I had this time.

The appropriate test, Y03arguments.ztst, still passes, but you'll
appreciate I can't guarantee this has no side effects.

Index: Src/Zle/computil.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/computil.c,v
retrieving revision 1.105
diff -u -r1.105 computil.c
--- Src/Zle/computil.c	6 Jul 2007 21:52:40 -0000	1.105
+++ Src/Zle/computil.c	7 Mar 2008 22:37:13 -0000
@@ -1612,7 +1612,16 @@
     return new;
 }
 
-/* Get the option used in a word from the line, if any. */
+/*
+ * Get the option used in a word from the line, if any.
+ *
+ * "d" is a complete set of argument/option definitions to scan.
+ * "line" is the word we are scanning.
+ * "full" indicates that the option must match a full word; otherwise
+ *   we look for "=" arguments or prefixes.
+ * *"end" is set to point to the end of the option, in some cases
+ *   leaving an option argument after it.
+ */
 
 static Caopt
 ca_get_opt(Cadef d, char *line, int full, char **end)
@@ -1785,6 +1794,12 @@
 
 typedef struct castate *Castate;
 
+/*
+ *           **** DOCUMENT ME ****
+ *
+ * This structure and its use are a nightmare.
+ */
+
 struct castate {
     Castate snext;
     Cadef d;
@@ -2244,9 +2259,18 @@
 	return ztrdup("");
 }
 
+/*
+ * This function adds the current set of descriptions, actions,
+ * and subcontext descriptions to the given linked list for passing
+ * up in comparguments -D and comparguments -L.  opt is the
+ * option string (may be NULL if this isn't an option argument) and arg the
+ * argument structure (either an option argument or a normal argument
+ * as determined by arg->type).
+ */
+
 static void
 ca_set_data(LinkList descr, LinkList act, LinkList subc,
-	    char *opt, Caarg arg, int single)
+	    char *opt, Caarg arg, Caopt optdef, int single)
 {
     LinkNode dnode, anode;
     char nbuf[40], *buf;
@@ -2297,6 +2321,19 @@
 
 	    addlinknode(subc, buf);
 	}
+	/*
+	 * If this is an argument to an option, and the option definition says
+	 * the argument to the option is required and in the following
+	 * (i.e. this) word, then it must match what we've just told it to
+	 * match---don't try to match normal arguments.
+	 *
+	 * This test may be too stringent for what we need, or it
+	 * may be too loose; I've simply tweaked it until it gets
+	 * the case above right.
+	 */
+	if (arg->type == CAA_NORMAL &&
+	    opt && optdef && optdef->type == CAO_NEXT)
+	    return;
 	if (single)
 	    break;
 
@@ -2467,7 +2504,7 @@
 			ignore_prefix(lstate->doff);
 		    }
 		    ca_set_data(descr, act, subc, arg->opt, arg,
-				(lstate->doff > 0));
+				lstate->curopt, (lstate->doff > 0));
 		}
 		lstate = lstate->snext;
 	    }
@@ -2565,7 +2602,7 @@
 
 		if (opt && opt->args) {
 		    ret = 0;
-		    ca_set_data(descr, act, subc, opt->name, opt->args, 1);
+		    ca_set_data(descr, act, subc, opt->name, opt->args, opt, 1);
 		}
 		lstate = lstate->snext;
 	    }


-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author