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

PATCH: preexec sometimes gets wrong command

I just noticed that preexec gets passed the wrong command when the
current command is discarded from the history (as is often the case
when the user is ignoring functions, history commands, and/or lines
that start with a space).  In this case, preexec got passed the
previous command from the history buffer.  I couldn't think of any
other way to grab the actual text that the user typed, so I decided to
set the first parameter to an empty string when this happens.  Perhaps
a better solution would be to pass the current (expanded) command

Speaking of expanded commands, I was really hoping to have access to
the alias-expanded command string for my preexec processing, so I also
decided to pass this information to the preexec function as the second
parameter.  It would be very easy to tweak my patch to supply this
value as both parameters (instead of the empty string in the first)
when we don't have the history text for the first argument.

The following patch implements these two changes and tweaks the doc.

Let me know what you think.  If people approve, I'll be glad to check
the changes into CVS.

Index: Doc/Zsh/func.yo
@@ -172,8 +172,11 @@
 Executed just after a command has been read and is about to be
-executed.  If the history mechanism is active, the string to be
-executed is passed as an argument.
+executed.  If the history mechanism is active (and the line was not
+discarded from the history buffer), the string that the user typed is
+passed as the first argument, otherwise it is an empty string.  The
+actual command that will be executed (including expanded aliases) is
+passed as the second argument (and is always present).
 cindex(signals, trapping)
Index: Src/init.c
@@ -135,15 +135,22 @@
 	    if (toplevel && (preprog = getshfunc("preexec")) != &dummy_eprog) {
 		LinkList args;
 		int osc = sfcontext;
+		char *cmdstr = getpermtext(prog, NULL);
 		args = znewlinklist();
 		zaddlinknode(args, "preexec");
-		if (hist_ring)
+		/* If curline got dumped from the history, we don't know
+		 * what the user typed. */
+		if (hist_ring && curline.histnum == curhist)
 		    zaddlinknode(args, hist_ring->text);
+		else
+		    zaddlinknode(args, "");
+		zaddlinknode(args, cmdstr);
 		sfcontext = SFC_HOOK;
 		doshfunc("preexec", preprog, args, 0, 1);
 		sfcontext = osc;
+		zsfree(cmdstr);
 		freelinklist(args, (FreeFunc) NULL);
 		errflag = 0;

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