From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 27964 invoked from network); 6 Jun 2020 08:41:38 -0000 Received: from ns1.primenet.com.au (HELO primenet.com.au) (203.24.36.2) by inbox.vuxu.org with ESMTPUTF8; 6 Jun 2020 08:41:38 -0000 Received: (qmail 20319 invoked by alias); 6 Jun 2020 08:41:31 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 46004 Received: (qmail 15819 invoked by uid 1010); 6 Jun 2020 08:41:31 -0000 X-Qmail-Scanner-Diagnostics: from out2-smtp.messagingengine.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.3/25828. spamassassin: 3.4.4. Clear:RC:0(66.111.4.26):SA:0(-2.6/5.0):. Processed in 0.77449 secs); 06 Jun 2020 08:41:31 -0000 X-Envelope-From: d.s@daniel.shahaf.name X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: none (ns1.primenet.com.au: domain at daniel.shahaf.name does not designate permitted sender hosts) X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrudeghedgtdeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvffukfggtggugfgfsehmkedtredtredunecuhfhrohhmpeffrghnihgv lhcuufhhrghhrghfuceougdrshesuggrnhhivghlrdhshhgrhhgrfhdrnhgrmhgvqeenuc ggtffrrghtthgvrhhnpeekhfeljeduhfdvueduudelhfefjeeuffehveeukeejueejhfff gfelfeegteefveenucffohhmrghinhepghhithhhuhgsrdgtohhmnecukfhppeejledrud ejiedrfeelrdeileenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhl fhhrohhmpegurdhssegurghnihgvlhdrshhhrghhrghfrdhnrghmvg X-ME-Proxy: Date: Sat, 6 Jun 2020 08:40:54 +0000 From: Daniel Shahaf To: zsh-workers@zsh.org Cc: Eric Freese Subject: add-zle-hook-widget and multiple hooks Message-ID: <20200606084054.GA31628@tarpaulin.shahaf.local2> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="qDbXVdCdHGoSgWSk" Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.10.1 (2018-07-13) --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit When two or more zle-line-pre-redraw hooks are registered using add-zle-hook-widget, the value of $LASTWIDGET when the each hook is called is the name of the former hook: [Eric Freese wrote in https://github.com/zsh-users/zsh-autosuggestions/issues/529#issuecomment-632113840] $ zsh -df % autoload add-zle-hook-widget % f() {} % g() { zle -M "$(typeset -p LASTWIDGET)" } % add-zle-hook-widget line-pre-redraw f % add-zle-hook-widget line-pre-redraw g % x typeset -r LASTWIDGET=f The issue here is that g would like to to know what widget was invoked immediately before the redraw. In the example, that'd be self-insert. I've attached two proofs of concept. WDYT? I'll add docs, etc, once an approach is chosen. Cheers, Daniel P.S. For the latter patch, note that «zle $widget -f» is distinct from «zle -f». --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="azhw-LASTWIDGET-shell-v1.txt" diff --git a/Functions/Misc/add-zle-hook-widget b/Functions/Misc/add-zle-hook-widget index 9cc35496f..f5f9b615d 100644 --- a/Functions/Misc/add-zle-hook-widget +++ b/Functions/Misc/add-zle-hook-widget @@ -41,6 +41,7 @@ zstyle zle-hook types ${hooktypes#zle-} function azhw:${^hooktypes} { local -a hook_widgets local hook + readonly LAST_NONHOOK_WIDGET=$LASTWIDGET # Values of these styles look like number:name # and we run them in number order zstyle -a $WIDGET widgets hook_widgets --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="azhw-LASTWIDGET-C-v1.txt" 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..7604d5251 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; */ + /* "nolast" is used in 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,23 @@ 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; + } + setlbindk = 1; + break; case 'n': num = args[0][1] ? args[0]+1 : args[1]; if (!num) { @@ -787,7 +799,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) --qDbXVdCdHGoSgWSk--