Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function)
- X-seq: zsh-workers 48754
- From: Marlon Richert <marlon.richert@xxxxxxxxx>
- To: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- Cc: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function)
- Date: Fri, 30 Apr 2021 22:16:37 +0300
- Archived-at: <https://zsh.org/workers/48754>
- In-reply-to: <CAH+w=7ZYcM4Su47bPX4Yh2dRG3K69O72Y6HBYdhdfJqLFO-yeg@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <95CDA630-4EE5-4003-8D9C-CCCB9A47F109@gmail.com> <CAH+w=7bpkYktd4UN5DtUS45MMNdWYr7c-OG7DHOX21QXG4LMUA@mail.gmail.com> <4D587C0C-EB5F-4A58-A0AE-D45E43F432CD@gmail.com> <CAH+w=7bQLq43JChP7PmaqT_wHMwgs4Nk_-0grrtQXEhQJcfrbA@mail.gmail.com> <CAH+w=7ZCzG-BGZuU-rLoZJX=3zcA74NK+TNVDP-CWF-9b-BfrA@mail.gmail.com> <AEC92FEA-6216-4952-818E-9DC7C584698A@gmail.com> <20210421212717.GE21343@tarpaulin.shahaf.local2> <CAH+w=7bFfZucFRj9OZvzTnvxd+QUW7tZHAJiMLi+O0PNjz=wyA@mail.gmail.com> <214AC3E9-FFA5-4F39-A918-562682FE3A3B@gmail.com> <CAH+w=7ZSWhyogP=rn_O40Lc96jTnM4rAKkHaXLn5iOsS7F76Vg@mail.gmail.com> <CAHLkEDspzutwPTAqC7HqdAJDqF0FncsWH6NsHk5Z=bt+Jww8vg@mail.gmail.com> <CAH+w=7ZhNyZypwtMvgBcCkUwCLRzB1+XtccdYG14A1zVJsSTrg@mail.gmail.com> <CAH+w=7YTPm_5=8cPSydgte_Ti7UaihR4s+fOz0H97_4dZwCeiw@mail.gmail.com> <CAHLkEDu4Ac_gRWCuZs24GW84djZ1t7tyVKroAxXrtvWBqUVWqg@mail.gmail.com> <CAH+w=7ZDorYi2C+0ycysL=99nh_6Mw865H4kB6ZYaHmMZr9tNA@mail.gmail.com> <CAHLkEDtgMYYVdtHBiPDYbhdhwRH9Ha3T1ix+G_q_=-miNgo=PA@mail.gmail.com> <CAH+w=7ZYcM4Su47bPX4Yh2dRG3K69O72Y6HBYdhdfJqLFO-yeg@mail.gmail.com>
Thanks for the explanations. Here's a new patch.
From c6036cecbedc414e024049e1da3f66dadebd497f Mon Sep 17 00:00:00 2001
From: Marlon Richert <marlon.richert@xxxxxxxxx>
Date: Fri, 30 Apr 2021 21:59:07 +0300
Subject: [PATCH] Add `execute-commands` widget function
---
Doc/Zsh/contrib.yo | 57 +++++++++++++++++++++++++++++++++++
Functions/Zle/execute-command | 41 +++++++++++++++++++++++++
2 files changed, 98 insertions(+)
create mode 100644 Functions/Zle/execute-command
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 8bf1a208e..7d0acc10a 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -2502,6 +2502,58 @@ arguments:
example(zstyle :zle:edit-command-line editor gvim -f)
)
+tindex(execute-commands)
+tindex(cd-upward)
+tindex(cd-backward)
+tindex(cd-forward)
+item(tt(execute-commands) [ var(options) ] [--] var(command) ...)(
+This function helps you implement widgets that execute commands (passed to the
+function as string arguments) without losing the current command line, in a
+fashion similar to the tt(run-help) and tt(which-command) widgets (see
+ifzman(the subsection bf(Miscellaneous) in zmanref(zshzle))\
+ifnzman(noderef(ZLE widgets standard Miscellaneous))). 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-commands
+zle -N cd-parent; cd-parent+LPAR()+RPAR() {
+ execute-commands -- 'cd ..'
+}
+zle -N pushd-prev; pushd-prev+LPAR()+RPAR() {
+ local sign='+'; [[ -o pushdminus ]] && sign='-'
+ execute-commands -- "pushd ${sign}1 > /dev/null"
+}
+zle -N pushd-next; pushd-next+LPAR()+RPAR() {
+ local sign='-'; [[ -o pushdminus ]] && sign='+'
+ execute-commands -- "pushd ${sign}0 > /dev/null"
+}
+bindkey "^[$terminfo[cuu1]" cd-parent # Alt-Up in raw mode
+bindkey "^[$terminfo[kcuu1]" cd-parent # Alt-Up in app mode
+bindkey '^[-' pushd-prev # Alt-Minus
+bindkey '^[=' pushd-next # Alt-Equals)
+
+By default, tt(execute-commands) executes the supplied commands quietly and
+without saving them to history. Its behavior can be modified by setting the
+following options:
+startsitem()
+sitem(tt(-e))(
+Echo the commands to the command line before executing them.
+)
+sitem(tt(-s))(
+Save the commands to history.
+)
+sitem(tt(-v) var(name))(
+Store the last command's exit code in parameter var(name).
+)
+endsitem()
+
+Note that calling tt(execute-commands) should always be the only or last
+statement you execute in your widget, because (after executing the supplied
+commands) tt(execute-commands) causes execution of the current widget to be
+aborted. Also note that tt(execute-commands) cannot be used when inside a
+tt(select) loop or tt(vared). Under those circumstances, it does nothing and
+returns non-zero.
+)
tindex(expand-absolute-path)
item(tt(expand-absolute-path))(
Expand the file name under the cursor to an absolute path, resolving
@@ -4649,6 +4701,11 @@ See `Recompiling Functions'
ifzman(above)\
ifnzman((noderef(Utilities))).
)
+findex(zrestart)
+item(tt(zrestart))(
+This function tests whether the shell is able to restart without error and, if
+so, restarts the shell.
+)
findex(zstyle+)
item(tt(zstyle+) var(context) var(style) var(value) [ tt(+) var(subcontext) var(style) var(value) ... ])(
This makes defining styles a bit simpler by using a single `tt(+)' as a
diff --git a/Functions/Zle/execute-command b/Functions/Zle/execute-command
new file mode 100644
index 000000000..f8e25f54e
--- /dev/null
+++ b/Functions/Zle/execute-command
@@ -0,0 +1,41 @@
+# 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. See the manual for more details.
+
+zmodload -F zsh/zutil b:zparseopts
+local -A opts
+zparseopts -D -A opts - e s v:
+
+local -a err
+zle ||
+ err+=( "${0}: can only be called from zle widgets" )
+(( # )) ||
+ err+=( "${0}: not enough arguments" )
+if [[ -n $err ]]; then
+ print -lu2 -- $err[@] \
+$'Usage: execute-commands [ <options> ] [--] <command> ...
+Execute commands from zle widget, without mangling prompt or buffer.
+Options:
+ -e echo commands before executing
+ -s save commands to history
+ -v <name> store last command\'s exit status in param <name>'
+ return 1
+fi
+
+case $CONTEXT in
+ ( cont | start )
+ print -rz -- "$PREBUFFER$BUFFER" # Push all lines to buffer stack.
+ [[ -v opts[-e] ]] &&
+ BUFFER="${(F)@}" # Echo commands to buffer.
+ [[ -v opts[-s] ]] &&
+ print -rS -- "${(F)@}" # Save commands to history.
+ eval "${(F)@}" # Execute commands.
+ local -i ret=$?
+ [[ -v opts[-v] ]] &&
+ eval "$opts[-v]=$ret" # Store exit status.
+ ;;
+ ( * )
+ return 75 # EX_TEMPFAIL; see `man 3 sysexits`.
+ ;;
+esac
+zle .send-break
--
2.31.1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author