Reputation: 7634
Note that I'm NOT talking about previous lines in the history. I'm talking about previous lines in the current multiline command.
When I type a multiline command in zsh, for instance (_
indicates the cursor):
$ for i in {1..5}; do
for> echo i_
At this point I might change my mind and want to let i
loop through {1..10}
instead, so I need to go back to the previous line. However, I can't figure out how to do this, as ⌫, or ←, or C-b
, or whatever I can think of all stops at the beginning of the second line. So, is it possible at all to move back? Thanks in advance.
In fact, this is not limited to zsh. For instance, I've never figured this out in bash either.
I've already spent a fair amount of time Googling without any findings, so please excuse me and blame my Google-fu if this is obvious.
For your reference, I'm using Emacs keybinding, and
$ bindkey | grep delete
"^D" delete-char-or-list
"^H" backward-delete-char
"^[[3~" delete-char
"^?" backward-delete-char
Not sure whether this will help.
Upvotes: 6
Views: 2774
Reputation: 4044
Actually this is possible.
While on that second line, pres Esc + X
in order to execute a command,
and type push-line-or-edit
(note that you can use Tab key for completion)
, then press return
.
The prompt will change to a traditional one ditching your for>
part from
continuation line, and you will have a new buffer filled with all your
previously typed lines, which of course now you can easily edit using well
known C-a
or C-b
keys.
Upvotes: 3
Reputation: 53644
I do not think this is possible, but here are other workarounds:
You can bind some key (e.g. <C-Enter>
if you can tell your terminal not to output <C-m>
in this case) to
function _-add-newline()
{
LBUFFER="$LBUFFER"$'\n'
}
zle -N add-newline _-add-newline
bindkey "\Ca" add-newline
. This way if you press <C-a>
newline will appear in the buffer, but it will not trigger accept-line widget and previous line will still be editable. You can e.g. use left/right arrows to move to it.
for x in y ; do<CR>echo foo<CR><C-c><Up>
you will see for x in y ; do\necho foo
in your buffer and all text will be editable. Note: you need <CR>
to preserve last line (line aborted by <C-c>
is not saved) and <C-c>
to abort input; this variant will not work if you have already typed done
(first <CR>
will run the cycle). In last case you may discard last line with <C-c>
and retype it.accept-line
widget with a code that parses your input and determines whether you have written command completely and if not then it will just append \n
to the buffer (like in the above function) and do not run original accept-line
, otherwise original accept-line
is run. This variant is much harder to implement though, so I am saying “theoretically”.Upvotes: 1
Reputation: 75585
Here is how you would visual
mode in bash
's vim
mode.
Inside .bashrc
put the following lines.
set -o vi
# I do not remember which one of these is used by `v`, so I set both
export VISUAL=/usr/bin/nano
export EDITOR=/usr/bin/nano
Reload bash
, and then push Esc
to go into normal
mode.
Type v
, and nano
should load. You can now enter your multiline command into nano
. When you save and exit, the multiline command will be executed.
For zsh
, the following lines in your rc
may do it. I stole the last three lines from this answer and tested it on my zsh
.
bindkey -v
autoload -U edit-command-line
zle -N edit-command-line
bindkey -M vicmd v edit-command-line
Upvotes: 5