zsh-workers
 help / color / mirror / code / Atom feed
From: Marlon Richert <marlon.richert@gmail.com>
To: Bart Schaefer <schaefer@brasslantern.com>
Cc: Zsh hackers list <zsh-workers@zsh.org>
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	[thread overview]
Message-ID: <CAHLkEDt_-WZ4B8T0yh8g3OFASBa2nBsHsdDMc3xYVXGds7G5ag@mail.gmail.com> (raw)
In-Reply-To: <CAH+w=7ZYcM4Su47bPX4Yh2dRG3K69O72Y6HBYdhdfJqLFO-yeg@mail.gmail.com>

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

Thanks for the explanations. Here's a new patch.

[-- Attachment #2: 0001-Add-execute-commands-widget-function.txt --]
[-- Type: text/plain, Size: 4944 bytes --]

From c6036cecbedc414e024049e1da3f66dadebd497f Mon Sep 17 00:00:00 2001
From: Marlon Richert <marlon.richert@gmail.com>
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


  reply	other threads:[~2021-04-30 19:17 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         ` [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function) Marlon Richert
2021-04-21 20:40           ` 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 [this message]
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=CAHLkEDt_-WZ4B8T0yh8g3OFASBa2nBsHsdDMc3xYVXGds7G5ag@mail.gmail.com \
    --to=marlon.richert@gmail.com \
    --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).