zsh-workers
 help / color / mirror / code / Atom feed
From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: zsh-workers@zsh.org
Subject: Re: add-zle-hook-widget and multiple hooks
Date: Thu, 18 Jun 2020 11:42:19 +0000	[thread overview]
Message-ID: <20200618114219.7973f8c7@tarpaulin.shahaf.local2> (raw)
In-Reply-To: <20200610133452.025cfc54@tarpaulin.shahaf.local2>

Daniel Shahaf wrote on Wed, 10 Jun 2020 13:34 +0000:
> Over here the jury's still out.

In the absence of further feedback I've gone ahead completed the C patch
using the originally posted syntax.  Any comments, reservations, etc.,
speak up.

diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 0909cd4f5..6b0f99b63 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -347,7 +347,7 @@ as the var(hook) argument.
 var(widgetname) is the name of a ZLE widget.  If no options are given this
 is added to the array of widgets to be invoked in the given hook context.
 Widgets are invoked in the order they were added, with
-example(tt(zle )var(widgetname)tt( -Nw -- "$@"))
+example(tt(zle )var(widgetname)tt( -Nw -f "nolast" -- "$@"))
 
 vindex(WIDGET, in hooks)
 Note that this means that the `tt(WIDGET)' special parameter tracks the
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index c928b8ca2..5b84b3acf 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -415,7 +415,7 @@ xitem(tt(zle) tt(-K) var(keymap))
 xitem(tt(zle) tt(-F) [ tt(-L) | tt(-w) ] [ var(fd) [ var(handler) ] ])
 xitem(tt(zle) tt(-I))
 xitem(tt(zle) tt(-T) [ tt(tc) var(function) | tt(-r) tt(tc) | tt(-L) ] )
-item(tt(zle) var(widget) [ tt(-n) var(num) ] [ tt(-Nw) ] [ tt(-K) var(keymap) ] var(args) ...)(
+item(tt(zle) var(widget) [ tt(-n) var(num) ] [ tt(-f) var(flag) ] [ tt(-Nw) ] [ tt(-K) var(keymap) ] var(args) ...)(
 The tt(zle) builtin performs a number of different actions concerning
 ZLE.
 
@@ -683,7 +683,7 @@ optional argument for debugging or testing.  Note that this
 transformation is not applied to other non-printing characters such as
 carriage returns and newlines.
 )
-item(var(widget) [ tt(-n) var(num) ] [ tt(-Nw) ] [ tt(-K) var(keymap) ] var(args) ...)(
+item(var(widget) [ tt(-n) var(num) ] [ tt(-f) var(flag) ] [ tt(-Nw) ] [ tt(-K) var(keymap) ] var(args) ...)(
 Invoke the specified var(widget).  This can only be done when ZLE is
 active; normally this will be within a user-defined widget.
 
@@ -702,6 +702,9 @@ appears as if the top-level widget called by the user were still
 active.  With the option tt(-w), tt(WIDGET) and related parameters are set
 to reflect the widget being executed by the tt(zle) call.
 
+Normally, when var(widget) returns the special parameter tt(LASTWIDGET) will
+point to it.  This can be inhibited by passing the option tt(-f nolast).
+
 Any further arguments will be passed to the widget; note that as
 standard argument handling is performed, any general argument list
 should be preceded by tt(-)tt(-).  If it is a shell
diff --git a/Functions/Misc/add-zle-hook-widget b/Functions/Misc/add-zle-hook-widget
index 9cc35496f..4d8049083 100644
--- a/Functions/Misc/add-zle-hook-widget
+++ b/Functions/Misc/add-zle-hook-widget
@@ -47,9 +47,9 @@ function azhw:${^hooktypes} {
     for hook in "${(@)${(@on)hook_widgets[@]}#<->:}"; do
 	if [[ "$hook" = user:* ]]; then
 	    # Preserve $WIDGET within the renamed widget
-	    zle "$hook" -N -- "$@"
+	    zle "$hook" -f "nolast" -N -- "$@"
 	else
-	    zle "$hook" -Nw -- "$@"
+	    zle "$hook" -f "nolast" -Nw -- "$@"
 	fi || return
     done
     return 0
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index ce61db27b..63bd45c8d 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -678,6 +678,7 @@ bin_zle_flags(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		else if (!strcmp(*flag, "keepsuffix"))
 		    w->flags |= ZLE_KEEPSUFFIX;
 		*/
+		/* If you add magic strings here, be consistent with bin_zle_call() */
 	        else if (!strcmp(*flag, "vichange")) {
 		    if (invicmdmode()) {
 			startvichange(-1);
@@ -703,7 +704,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     Thingy t;
     struct modifier modsave = zmod;
-    int ret, saveflag = 0, setbindk = 0, setlbindk, remetafy;
+    int ret, saveflag = 0, setbindk = 0, setlbindk = 0, remetafy;
     char *wname = *args++, *keymap_restore = NULL, *keymap_tmp;
 
     if (!wname)
@@ -727,12 +728,24 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     while (*args && **args == '-') {
 	char skip_this_arg[2] = "x";
 	char *num;
+	char *flag;
 	if (!args[0][1] || args[0][1] == '-') {
 	    args++;
 	    break;
 	}
 	while (*++(*args)) {
 	    switch (**args) {
+	    case 'f':
+		flag = args[0][1] ? args[0]+1 : args[1];
+		if (strcmp(flag, "nolast")) {
+		    zwarnnam(name, "%s", "'nolast' expected after -f");
+		    if (remetafy)
+			metafy_line();
+		    return 1;
+		}
+		/* If you add magic strings here, be consistent with bin_zle_flags() */
+		setlbindk = 1;
+		break;
 	    case 'n':
 		num = args[0][1] ? args[0]+1 : args[1];
 		if (!num) {
@@ -787,7 +800,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
      * a vi range to detect a repeated key */
     setbindk = setbindk ||
 	(t->widget && (t->widget->flags & (WIDGET_INT | ZLE_VIOPER)) == WIDGET_INT);
-    setlbindk = t->widget && (t->widget->flags & ZLE_NOLAST) == ZLE_NOLAST;
+    setlbindk |= t->widget && (t->widget->flags & ZLE_NOLAST) == ZLE_NOLAST;
     ret = execzlefunc(t, args, setbindk, setlbindk);
     unrefthingy(t);
     if (saveflag)
diff --git a/Test/X04zlehighlight.ztst b/Test/X04zlehighlight.ztst
index 475a2e309..dadd1c0aa 100644
--- a/Test/X04zlehighlight.ztst
+++ b/Test/X04zlehighlight.ztst
@@ -154,6 +154,17 @@
 0:overlapping region_highlight with near-color (hex-triplets at input)
 >0m27m24mCDE|340|tCDE|3160|rCDE|39|CDE|340|ueCDE|39|
 
+  zpty_start
+  zpty_input 'f () { zle clear-screen; zle g -f nolast; BUFFER=": ${(q)LASTWIDGET}" }; zle -N f'
+  zpty_input 'g () { }; zle -N g'
+  zpty_input 'bindkey "\C-a" f'
+  zpty_enable_zle
+  zpty_input $'\C-a'
+  zpty_line 1 p
+  zpty_stop
+0:zle $widgetname -f nolast
+>0m27m24m0m27m24m: clear-screen
+
 %clean
 
   zmodload -ui zsh/zpty

  reply	other threads:[~2020-06-18 11:43 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-06  8:40 Daniel Shahaf
2020-06-06 11:58 ` Mikael Magnusson
2020-06-08  6:14   ` Daniel Shahaf
2020-06-08 17:52     ` Mikael Magnusson
2020-06-10 13:34       ` Daniel Shahaf
2020-06-18 11:42         ` Daniel Shahaf [this message]
2020-06-27  2:54           ` Daniel Shahaf
2020-06-27  3:02             ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200618114219.7973f8c7@tarpaulin.shahaf.local2 \
    --to=d.s@daniel.shahaf.name \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).