about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2015-03-22 18:44:56 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2015-03-22 18:44:56 +0000
commit4fb669a72deb547b6ec1c9298373e3b78384983d (patch)
tree77aa39005413303b640a0c63d8e0c91f8e8e8001
parent8254c9c071bff087c3d52a5ac2811b5b7fc367ce (diff)
downloadzsh-4fb669a72deb547b6ec1c9298373e3b78384983d.tar.gz
zsh-4fb669a72deb547b6ec1c9298373e3b78384983d.tar.xz
zsh-4fb669a72deb547b6ec1c9298373e3b78384983d.zip
34758: fix yet more history / command subst interaction.
In general we need to wind back over the history text input
inside command substitution because there's no level of
the input mechanism between history and the lexer.
-rw-r--r--ChangeLog6
-rw-r--r--Src/hist.c14
-rw-r--r--Src/lex.c19
3 files changed, 38 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index bc7ac80d3..cd9393fdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-22  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 34758: Src/hist.c, Src/lex.c: more problems with history
+	interaction with command substitution: rewind over input history
+	text when necessary.
+
 2015-03-21  Barton E. Schaefer  <schaefer@zsh.org>
 
 	* users/20034: Completion/Base/Core/_main_complete: adjust
diff --git a/Src/hist.c b/Src/hist.c
index b7ef52230..70dfac036 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -527,10 +527,20 @@ histsubchar(int c)
     static int marg = -1;
     static zlong mev = -1;
     char *buf, *ptr;
-    char *sline;
+    char *sline, *lexraw_mark;
     Histent ehist;
     size_t buflen;
 
+    /*
+     * If accumulating raw input for use in command substitution,
+     * we don't want the history text, so mark it for later removal.
+     * It would be better to do this at a level above the history
+     * and below the lexer --- but there isn't one.
+     *
+     * Include the character we are attempting to substitute.
+     */
+    lexraw_mark = zshlex_raw_mark(-1); 
+
     /* look, no goto's */
     if (isfirstch && c == hatchar) {
 	int gbal = 0;
@@ -864,6 +874,8 @@ histsubchar(int c)
 	}
     }
 
+    zshlex_raw_back_to_mark(lexraw_mark);
+
     /*
      * Push the expanded value onto the input stack,
      * marking this as a history word for purposes of the alias stack.
diff --git a/Src/lex.c b/Src/lex.c
index 1eb0bc7d7..6b9e94289 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -1871,6 +1871,25 @@ zshlex_raw_back(void)
     lexbuf_raw.len--;
 }
 
+/**/
+char *
+zshlex_raw_mark(int offset)
+{
+    if (!lex_add_raw)
+	return NULL;
+    return lexbuf_raw.ptr + offset;
+}
+
+/**/
+void
+zshlex_raw_back_to_mark(char *mark)
+{
+    if (!lex_add_raw)
+	return;
+    lexbuf_raw.len -= lexbuf_raw.ptr - mark;
+    lexbuf_raw.ptr = mark;
+}
+
 /*
  * Skip (...) for command-style substitutions: $(...), <(...), >(...)
  *