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.
You can go back to your previous location with the Go > Back command or Ctrl+Alt+-. You can also see the type definition if you press Ctrl (Cmd on macOS) when you are hovering over the type.
Using a Backslash. The backslash (\) is an escape character that instructs the shell not to interpret the next character. If the next character is a newline, the shell will read the statement as not having reached its end. This allows a statement to span multiple lines.
The Zsh Line Editor (ZLE) is simply your command prompt. It's your interface to the shell interpreter, allowing you to write and edit your mind-blowing commands. It also allows you to use keystrokes to execute ZLE commands, more commonly called widgets.
Move Cursor on The Command Line Ctrl+A or Home – moves the cursor to the start of a line. Ctrl+E or End – moves the cursor to the end of the line. Ctrl+B or Left Arrow – moves the cursor back one character at a time. Ctrl+F or Right Arrow – moves the cursor forward one character at a time.
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
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.
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”.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With