From: Marlon Richert <marlon.richert@gmail.com>
To: Bart Schaefer <schaefer@brasslantern.com>,
Daniel Shahaf <d.s@daniel.shahaf.name>
Cc: Zsh hackers list <zsh-workers@zsh.org>
Subject: [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function)
Date: Wed, 21 Apr 2021 14:37:28 +0300 [thread overview]
Message-ID: <AEC92FEA-6216-4952-818E-9DC7C584698A@gmail.com> (raw)
In-Reply-To: <CAH+w=7ZCzG-BGZuU-rLoZJX=3zcA74NK+TNVDP-CWF-9b-BfrA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 984 bytes --]
On 21 Apr 2021, at 00:32, Bart Schaefer <schaefer@brasslantern.com> wrote:
> My only remark about this as-is, is that it would have potentially
> dangerous side-effects if invoked at a PS2 or PS3 prompt.
>
> Potential fixes - begin the widget function with:
> [[ ${(%):-%_} = select ]] && return 1
> [[ -n "$PREBUFFER$BUFFER" ]] && zle push-input
On 21 Apr 2021, at 06:46, Bart Schaefer <schaefer@brasslantern.com> wrote:
> Oh, I missed this:
>
>> On Tue, Apr 20, 2021 at 1:13 PM Marlon Richert <marlon.richert@gmail.com> wrote:
>>> @@ -0,0 +1,29 @@
>>> +zle .push-line-or-edit
>
> That's still wrong, because in the event there's a PS2 prompt, you'll
> never get past this line. You need .push-input here. My suggested
> test for $PREBUFFER is probably not actually needed.
Thank you both (Bart & Daniel) for your input. I added better safeguards against the non-PS1 cases, rewrote the function to be more generic and added comments. New patch attached.
[-- Attachment #2: 0001-Add-execute-command-widget-function.txt --]
[-- Type: text/plain, Size: 4064 bytes --]
From 83da04aba0d07112f650a98fafc3f28daf75dcd1 Mon Sep 17 00:00:00 2001
From: Marlon Richert <marlon.richert@gmail.com>
Date: Wed, 21 Apr 2021 14:33:27 +0300
Subject: [PATCH] Add execute-command() widget function
---
Doc/Zsh/contrib.yo | 26 +++++++++++++++++
Functions/Zle/execute-command | 54 +++++++++++++++++++++++++++++++++++
2 files changed, 80 insertions(+)
create mode 100644 Functions/Zle/execute-command
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 8bf1a208e..df02fc4d9 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -2502,6 +2502,32 @@ arguments:
example(zstyle :zle:edit-command-line editor gvim -f)
)
+tindex(execute-command)
+item(tt(execute-command))(
+This function lets you implement widgets that can execute arbitrary commands
+without losing the current command line, in a fashion similar to the
+tt(run-help) and tt(which-command) widgets (see
+ifzman(the subsection Miscellaneous in zmanref(zshzle))\
+ifnzman(noderef(Miscellaneous))). More precisely, it
+enumeration(
+myeit() pushes the buffer onto the buffer stack,
+myeit() executes the supplied arguments, then
+myeit() lets the ZLE pop the buffer off the top of the buffer stack and load
+ it into the editing buffer.
+)
+
+You can use this, for example, to create key bindings that let you instantly
+change directories, even while in the middle of typing another command:
+
+example(autoload -Uz execute-command
+setopt autopushd pushdminus pushdsilent
+zle -N cd-upward ; cd-upward() { execute-command cd .. }
+zle -N cd-backward; cd-backward() { execute-command pushd -1 }
+zle -N cd-forward ; cd-forward() { execute-command pushd +0 }
+bindkey '^[^[[A' cd-upward; bindkey '^[^[OA' cd-upward
+bindkey '^[-' cd-backward
+bindkey '^[=' cd-forward)
+)
tindex(expand-absolute-path)
item(tt(expand-absolute-path))(
Expand the file name under the cursor to an absolute path, resolving
diff --git a/Functions/Zle/execute-command b/Functions/Zle/execute-command
new file mode 100644
index 000000000..04fccf176
--- /dev/null
+++ b/Functions/Zle/execute-command
@@ -0,0 +1,54 @@
+# This function lets you implement widgets that can execute arbitrary commands
+# without losing the current command line, in a fashion similar to the
+# 'run-help' and 'which-command' widgets. You can use this, for example, to
+# create key bindings that let you instantly change directories, even while in
+# the middle of typing another command:
+#
+# autoload -Uz execute-command
+# setopt autopushd pushdminus pushdsilent
+# zle -N cd-upward ; cd-upward() { execute-command cd .. }
+# zle -N cd-backward; cd-backward() { execute-command pushd -1 }
+# zle -N cd-forward ; cd-forward() { execute-command pushd +0 }
+# bindkey '^[^[[A' cd-upward; bindkey '^[^[OA' cd-upward
+# bindkey '^[-' cd-backward
+# bindkey '^[=' cd-forward
+#
+
+case $CONTEXT in
+ ( start ) # PS1
+ ;;
+ ( cont ) # PS2
+ # Add a one-time hook that will re-run this widget at the top-level prompt.
+ autoload -Uz add-zle-hook-widget
+ local hook=line-init
+ local func=:$hook:$WIDGET
+ eval "$func() {
+ # Make sure we don't run twice.
+ add-zle-hook-widget -d $hook $func
+
+ # Don't leave anything behind.
+ zle -D $func
+ unfunction $func
+
+ zle $WIDGET
+ }"
+ add-zle-hook-widget $hook $func
+
+ # Move the entire current multiline construct into the editor buffer. This
+ # function is then aborted and we return to the top-level prompt, which
+ # triggers the hook above.
+ zle .push-line-or-edit
+ return # Not actually necessary, but for clarity's sake
+ ;;
+ ( * )
+ # We don't want this to be used in a select loop or in vared.
+ return 1
+ ;;
+esac
+
+# Push the current buffer onto the buffer stack and clear the buffer. The ZLE
+# will auto-restore it at the next top-level prompt.
+zle .push-line
+
+BUFFER="$*"
+zle .accept-line
--
2.31.1
[-- Attachment #3: Type: text/plain, Size: 2 bytes --]
next prev parent reply other threads:[~2021-04-21 11:38 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-20 13:36 [RFC][PATCH] Add change-directory() widget function Marlon Richert
2021-04-20 19:43 ` Bart Schaefer
2021-04-20 20:13 ` Marlon Richert
2021-04-20 21:32 ` Bart Schaefer
2021-04-21 3:46 ` Bart Schaefer
2021-04-21 11:37 ` Marlon Richert [this message]
2021-04-21 20:40 ` [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function) Bart Schaefer
2021-04-21 21:27 ` Daniel Shahaf
2021-04-21 21:58 ` Bart Schaefer
2021-04-22 10:55 ` Marlon Richert
2021-04-22 20:25 ` Daniel Shahaf
2021-04-22 23:27 ` Bart Schaefer
2021-04-24 20:06 ` Marlon Richert
2021-04-24 21:49 ` Bart Schaefer
2021-04-24 21:58 ` Bart Schaefer
2021-04-26 18:08 ` Marlon Richert
2021-04-26 21:39 ` Bart Schaefer
2021-04-27 10:46 ` Marlon Richert
2021-04-27 19:27 ` Bart Schaefer
2021-04-30 19:16 ` Marlon Richert
2021-04-30 20:25 ` Bart Schaefer
2021-05-01 13:30 ` Marlon Richert
2021-05-31 17:55 ` Marlon Richert
2021-04-25 17:02 ` Hard-wrapping emails (Was: [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function)) Lawrence Velázquez
2021-04-20 21:57 ` [RFC][PATCH] Add change-directory() widget function Daniel Shahaf
2021-04-20 22:14 ` Daniel Shahaf
2021-04-21 0:09 ` Bart Schaefer
2021-04-21 3:18 ` Bart Schaefer
2021-04-21 20:11 ` Daniel Shahaf
2021-04-21 20:29 ` Bart Schaefer
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=AEC92FEA-6216-4952-818E-9DC7C584698A@gmail.com \
--to=marlon.richert@gmail.com \
--cc=d.s@daniel.shahaf.name \
--cc=schaefer@brasslantern.com \
--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).