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

Re: ${(z)} parsing of multiple array assignments



On Sun, 2019-12-29 at 20:55 +0000, Peter Stephenson wrote:
> Unless I'm missing some trick, bufferwords() is the function where we
> need to update any parser state --- ctxtlex() is too low level for that,
> it just handles the next token given the current state.  So it's
> probably something like this.  Will need a new test adding.

We also need to do something similar for completion, otherwise

  foo=(stuff) bar=(...

looks like a glob qualifier.

In this case it's already half handled, so there's a variable to hook
into.

pws


diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 2b25d6b2e..fdd168763 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1236,8 +1236,10 @@ get_comp_string(void)
 	else if (tok == OUTPAR) {
 	    if (parct)
 		parct--;
-	    else
+	    else if (linarr) {
 		linarr = 0;
+		incmdpos = 1;
+	    }
 	}
 	if (inredir && IS_REDIROP(tok)) {
             rdstr = rdstrbuf;
diff --git a/Src/hist.c b/Src/hist.c
index 74116e82f..5281e8718 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -3321,6 +3321,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
     int owb = wb, owe = we, oadx = addedx, onc = nocomments;
     int ona = noaliases, ocs = zlemetacs, oll = zlemetall;
     int forloop = 0, rcquotes = opts[RCQUOTES];
+    int envarray = 0;
     char *p, *addedspaceptr;
 
     if (!list)
@@ -3404,6 +3405,14 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
 	ctxtlex();
 	if (tok == ENDINPUT || tok == LEXERR)
 	    break;
+	/*
+	 * After an array assignment, return to the initial
+	 * start-of-command state.  There could be a second ENVARRAY.
+	 */
+	if (tok == OUTPAR && envarray) {
+	    incmdpos = 1;
+	    envarray = 0;
+	}
 	if (tok == FOR) {
 	    /*
 	     * The way for (( expr1 ; expr2; expr3 )) is parsed is:
@@ -3441,6 +3450,7 @@ bufferwords(LinkList list, char *buf, int *index, int flags)
 	    switch (tok) {
 	    case ENVARRAY:
 		p = dyncat(tokstr, "=(");
+		envarray = 1;
 		break;
 
 	    case DINPAR:



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