1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| | # Lets you implement widgets that can execute arbitrary commands without losing
# the current command line, in a fashion similar to 'run-help' and
# 'which-command' widgets. See the manual for examples.
zmodload -F zsh/zutil b:zparseopts
autoload -Uz add-zle-hook-widget
case $CONTEXT in
( start ) # PS1
;;
( cont ) # PS2
# Add a one-time hook that will re-run this widget at the top-level prompt.
local hook=line-init
local func=${(q):-:${(%):-%N}:$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
# Use -w to ensure \$WIDGET is set to our original widget, not the hook.
# This doesn't matter at present, but might matter in future or if this
# code gets copy-pasted elsewhere.
zle ${(q)WIDGET} -w
}"
add-zle-hook-widget $hook ${(Q)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.
# We don't use .push-input here, because that would result in a blank
# buffer afterwards.
zle .push-line-or-edit
return # Command flow never actually gets here. See above.
;;
( * )
# We don't want this to be used in a select loop or in vared:
# * At a select prompt, the command wouldn't be "executed"; it'd be fed to
# select as the value of the selection.
# * In vared, it would replace the contents of the variable with the
# command string and then exit vared.
return 75 # EX_TEMPFAIL; see `man 3 sysexits`.
;;
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
zparseopts -D - # Remove - or -- argument.
BUFFER="$1"
zle .accept-line
|