diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Src/Zle/zle_params.c | 13 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 16 | ||||
-rw-r--r-- | Src/hist.c | 16 | ||||
-rw-r--r-- | Src/lex.c | 12 |
5 files changed, 55 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog index a06769f53..222789bc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-03-22 Peter Stephenson <pws@csr.com> + + * 27822: Src/hist.c, Src/lex.c, Src/zle_params.c, + Src/zle_tricky.c: Fix ZLE access to current history line if pushed + onto lexical stack. + 2010-03-19 Peter Stephenson <p.w.stephenson@ntlworld.com> * unposted: Etc/FAQ.yo: update section on coloured prompts and @@ -12943,5 +12949,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.4940 $ +* $Revision: 1.4941 $ ***************************************************** diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c index f384753e2..2883c0fbd 100644 --- a/Src/Zle/zle_params.c +++ b/Src/Zle/zle_params.c @@ -334,8 +334,19 @@ get_rbuffer(UNUSED(Param pm)) static char * get_prebuffer(UNUSED(Param pm)) { - if (chline) + /* + * Use the editing current history line, not necessarily the + * history line that's currently in the history mechanism + * since our line may have been stacked. + */ + if (zle_chline) { + /* zle_chline was NULL terminated when pushed onto the stack */ + return dupstring(zle_chline); + } + if (chline) { + /* hptr is valid */ return dupstrpfx(chline, hptr - chline); + } return dupstring(""); } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index dce7fb700..3e2a35171 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -632,16 +632,16 @@ docomplete(int lst) origline = dupstring(zlemetaline); origcs = zlemetacs; origll = zlemetall; - if (!isfirstln && chline != NULL) { - /* If we are completing in a multi-line buffer (which was not * - * taken from the history), we have to prepend the stuff saved * - * in chline to the contents of line. */ - + if (!isfirstln && (chline != NULL || zle_chline != NULL)) { ol = dupstring(zlemetaline); - /* Make sure that chline is zero-terminated. */ - *hptr = '\0'; + /* + * Make sure that chline is zero-terminated. + * zle_chline always is and hptr doesn't point into it anyway. + */ + if (!zle_chline) + *hptr = '\0'; zlemetacs = 0; - inststr(chline); + inststr(zle_chline ? zle_chline : chline); chl = zlemetacs; zlemetacs += ocs; } else diff --git a/Src/hist.c b/Src/hist.c index b1e4e82c4..08a613d4c 100644 --- a/Src/hist.c +++ b/Src/hist.c @@ -164,6 +164,22 @@ mod_export char *hptr; /**/ mod_export char *chline; +/* + * The current history line as seen by ZLE. + * We modify chline for use in other contexts while ZLE may + * still be running; ZLE should see only the top-level value. + * + * To avoid having to modify this every time we modify chline, + * we set it when we push the stack, and unset it when we pop + * the appropriate value off the stack. As it's never modified + * on the stack this is the only maintainance we ever do on it. + * In return, ZLE has to check both zle_chline and (if that's + * NULL) chline to get the current value. + */ + +/**/ +mod_export char *zle_chline; + /* true if the last character returned by hgetc was an escaped bangchar * * if it is set and NOBANGHIST is unset hwaddc escapes bangchars */ diff --git a/Src/lex.c b/Src/lex.c index f25bd3eca..8f432515c 100644 --- a/Src/lex.c +++ b/Src/lex.c @@ -249,6 +249,13 @@ lexsave(void) ls->histdone = histdone; ls->stophist = stophist; stophist = 0; + if (!lstack) { + /* top level, make this version visible to ZLE */ + zle_chline = chline; + /* ensure line stored is NULL-terminated */ + if (hptr) + *hptr = '\0'; + } ls->hline = chline; chline = NULL; ls->hptr = hptr; @@ -355,6 +362,11 @@ lexrestore(void) errflag = 0; ln = lstack->next; + if (!ln) { + /* Back to top level: don't need special ZLE value */ + DPUTS(chline != zle_chline, "BUG: Ouch, wrong chline for ZLE"); + zle_chline = NULL; + } free(lstack); lstack = ln; } |