24581: Fix array assignments in shell word splitting and completion.

Assignments after the first were not recognised as such as without
the full parser the state didn't return to command position.
Fix this in bufferwords() and the completion miniparser.
This commit is contained in:
Peter Stephenson 2019-12-31 18:35:06 +00:00
parent f3d18c3fb5
commit c557cee1a6
3 changed files with 19 additions and 1 deletions

View file

@ -1,3 +1,9 @@
2019-12-30 Peter Stephenson <p.w.stephenson@ntlworld.com>
* users/24581: Src/Zle/zle_tricky.c, Src/hist.c: Array assignments
after the first weren't parsed correctly by ${(z)...} or by
completion.
2019-12-31 Daniel Shahaf <d.s@daniel.shahaf.name>
* 45160: Doc/Zsh/expn.yo: zshexpn: Expand documentation

View file

@ -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;

View file

@ -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: