I'm writing a simple ZLE widget to quickly create subshells with <C-j>
. Here's what I have:
function zle_subshell {
zle -U '$()'
zle .backward-char
}
# register as widget
zle -N zle_subshell
# create kbd
bindkey '^j' zle_subshell
However, it appears that zle .backward-char
isn't working. What makes matters more confusing is that if I modify the script to be:
function zle_subshell {
zle -U '$('
zle -U ')'
zle .backward-char
}
I get output like )$(
...
It appears that zle_subshell
function is being evaluated in reverse. Are there some obvious gotchas with ZLE widgets that I'm unaware of?
The zle -U
usage is the pecial case. It seems that the behavior is intended:
zle -U string
...
This pushes the characters in thestring
onto the input stack of ZLE. After the widget currently executed finishes ZLE will behave as if the characters in thestring
were typed by the user.As ZLE uses a stack, if this option is used repeatedly the last string pushed onto the stack will be processed first. However, the characters in each
string
will be processed in the order in which they appear in the string.
So, zsh will behave as if )
and $(
were typed after the zle_subshell
finishes.
We could modify the (R)BUFFER
to change the editor buffer directly like this:
function zle_subshell {
RBUFFER='$()'"$RBUFFER"
repeat 2 do zle .forward-char; done
# ((CURSOR=CURSOR+2)) # We could do this instead.
}