zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] User-defined widgets can continue past push-line-or-edit
@ 2023-09-17 21:55 Bart Schaefer
  2023-09-18 14:20 ` Bart Schaefer
  0 siblings, 1 reply; 2+ messages in thread
From: Bart Schaefer @ 2023-09-17 21:55 UTC (permalink / raw)
  To: Zsh hackers list

[-- Attachment #1: Type: text/plain, Size: 1537 bytes --]

This one is going to need some real-life testing.

Before the appended patch, either "zle push-line-or-edit" had to be
last thing done by any user-defined widget, or it had to be
special-cased for PREBUFFER because at the PS2 prompt it effectively
executed a send-break to force the parser to return to the PS1 prompt.

With this patch, the current user-defined widget may continue
executing through to either normal return or until another widget that
ends the ZLE session (such as accept-line) is called.  However, this
is not transitive, that is, if user-defined widget X uses "zle Y" and
Y is a user-defined widget that calls push-line-or-edit, then X will
stop immediately after Y returns.  It may be possible to change that,
but: one thing at a time.

Although push-line-or-edit clears the current BUFFER, the
already-parsed PREBUFFER won't be discarded (from the parser state)
until ZLE finishes.  This means that if a widget such as accept-line
is called in this circumstance (e.g., at PS2 prompt) the entire parser
state up to that point is accepted.  This has the probably-unwanted
effect of restarting the parser at the end of "$PREBUFFER$BUFFFER"
instead of at PS1, thereby potentially duplicating what was just
pushed (with anything new in BUFFER in between).  Of course, you can
stuff something into BUFFER that finishes the expression represented
by PREBUFFER, which will then execute that and restart with the pushed
state.

The foregoing all applies to "zle push-input" which is implemented by
call to pushlineoredit().

[-- Attachment #2: pushlineoredit.txt --]
[-- Type: text/plain, Size: 1657 bytes --]

diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index 0fdad70d9..38f2e0fcc 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -871,8 +871,11 @@ pushlineoredit(char **args)
     }
     ret = pushline(args);
     if (!isfirstln) {
-	errflag |= ERRFLAG_ERROR|ERRFLAG_INT;
-	done = 1;
+	if (sfcontext != SFC_WIDGET) {
+	    errflag |= ERRFLAG_EDIT;
+	    done = 1;
+	} else
+	    done = 2;
     }
     clearlist = 1;
     return ret;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 1afb1bf58..69008bbbd 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1532,6 +1532,10 @@ execzlefunc(Thingy func, char **args, int set_bindk, int set_lbindk)
 	    sfcontext = SFC_WIDGET;
 	    opts[XTRACE] = 0;
 	    ret = doshfunc(shf, largs, 1);
+	    if (done == 2) {
+		errflag |= ERRFLAG_EDIT;
+		done = 1;
+	    }
 	    opts[XTRACE] = oxt;
 	    sfcontext = osc;
 	    endparamscope();
diff --git a/Src/input.c b/Src/input.c
index 8d7f44d7c..cfff586e3 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -430,7 +430,8 @@ inputline(void)
     }
     if (errflag) {
 	free(ingetcline);
-	errflag |= ERRFLAG_ERROR;
+	if (errflag != ERRFLAG_EDIT)
+	    errflag |= ERRFLAG_ERROR;
 	return lexstop = 1;
     }
     if (isset(VERBOSE)) {
diff --git a/Src/zsh.h b/Src/zsh.h
index a0243e98e..09e656d99 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2977,7 +2977,11 @@ enum errflag_bits {
      * have exited.  This is reset by "errflag = 0" in
      * loop(toplevel = 1, ...).
      */
-    ERRFLAG_HARD = 4
+    ERRFLAG_HARD = 4,
+    /*
+     * Editing error.  Like user interrupt, but less violent.
+     */
+    ERRFLAG_EDIT = 8
 };
 
 /***********/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] User-defined widgets can continue past push-line-or-edit
  2023-09-17 21:55 [PATCH] User-defined widgets can continue past push-line-or-edit Bart Schaefer
@ 2023-09-18 14:20 ` Bart Schaefer
  0 siblings, 0 replies; 2+ messages in thread
From: Bart Schaefer @ 2023-09-18 14:20 UTC (permalink / raw)
  To: Zsh hackers list

On Sun, Sep 17, 2023 at 2:55 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> With this patch, the current user-defined widget may continue
> executing through to either normal return or until another widget that
> ends the ZLE session (such as accept-line) is called.  However, this
> is not transitive, that is, if user-defined widget X uses "zle Y" and
> Y is a user-defined widget that calls push-line-or-edit, then X will
> stop immediately after Y returns.

Evidently I fooled myself with my test case on this one.  I thought
that errflag nonzero would prevent any further commands from executing
in the calling function X, but the use of a new flag value avoids
that, so X proceeds.

However, the accept-* family are not the only other widgets that can
have confusing side-effects if run after push-line-or-edit, most
obviously get-line.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-09-18 14:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-17 21:55 [PATCH] User-defined widgets can continue past push-line-or-edit Bart Schaefer
2023-09-18 14:20 ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).