I just completed the tutorial - Learn Vimscript the Hard Way by Steve Losh - and found that I'm still unfamiliar with map
, normal
, and execute
. After searching and testing, I made this quiz.
By answering these questions, you will fully understand how to use map
, normal
, and execute
all together.
Put following code in your vimrc:
nnoremap <F6> :echo 'hi'<CR>
What do you get when triggering the hotkey?
VIM echos hi
when you press <F6>
.
Put following code in your vimrc:
nnoremap <F6> echo 'hi'<CR>
What do you get when triggering the hotkey? Someone said that you don't need colons for commands in VIM scripts. Why it doesn't work here?
It presses 10 keys:
e
- move forward to the end of a word.ch
-c
is an operator andh
is a motion. It deletes a char before the cursor then start the insert mode. Read:h operator
forc
. Read:h left-right-motion
forh
.o 'hi'
- these are inserted to your document.<CR>
- press enter, which insert a new line.
map
/noremap
commands process these chars as a series of key press. :
is required since we want to switch to the command mode before typing echo 'hi'
. In this situation, :
is not part of the command but a key to switch to command mode from the normal mode.
Extra: You can press
<Esc>
to switch to normal mode from insert mode. Try building ainoremap
command that echoshi
.
Extra 2: Per pervious extra. You can also use
<Ctrl-O>
to switch to normal mode. Read:help i_CTRL-O
and use it in yourinoremap
command.
Extra 3: You can use a special key
<Cmd>
to enter a hidden command mode. Read:help <Cmd>
and use it in yourinoremap
command.
Put following code in your vimrc:
nnoremap <F6> :echo 'hi'
Does it echo hi
? why not?
Without <CR>
a.k.a. the enter key, the command typed in the command mode won't be executed. Your cursor results in the command mode with the command echo 'hi'
.
You will see lots of sample code on the net that forget to <CR>
after entering the command mode. They are wrong.
Extra: Try
nnoremap <F6> :echo 'h<Left>i<Right><Right>'<CR>
. What do you get? Read:h <>
.
Extra 2: Build a
nnoremap
command that echos'<CR>'
literally. Hint:<lt>
.
Run the following command:
normal echo 'hi'
Does it work?
Nope.
Per Q4. Add the missing colon. You should know why the colon is needed after Q2. Does it work? Hint: it doesn't. Why not?
It doesn't work since it doesn't press enter. Similar to Q3.
normal
is like map
/remap
but is more limited. It processes the following chars as a series of key type without parsing special keys in <>
.
Extra: What will you get with
normal i<CR>
? Predict the result before trying it.
Run the following command:
execute "echo 'hi'"
Does it work?
Yes.
execute
takes a string as the argument and evaluate the string as a command. It doesn't switch VIM mode. It doesn't type in the command line. Hence you don't have to tell it to press enter to execute the command.
Run the following command:
execute "normal :echo 'hi'"
Does it work?
No.
This executes a normal command that switches to the command mode with :
and type echo 'hi'
, without pressing the enter key.
Run the following command:
execute "normal echo 'hi'\r"
Does it work?
Yes.
By adding a "\r"
in the string, we actually feed an enter key to normal
, which is impossible without the execute
command.
Extra: Read
:h expr-string
. How do we feed<Esc>
tonormal
?
Extra 2: Run
echo "\e" ==# "\x1b"
.
Extra 3: Run
echo "\e" ==# "\<Esc>"
.
Extra 4: Do you remember
<Cmd>
in Q2 extra? Runexecute "normal \<Cmd>echo 'hi'\r"
.
Put following code in your vimrc:
nnoremap <F6> :execute "normal :echo 'hi'\r"<CR>
Are those colons necessary?
Yes. We use them to switch to the command mode from the normal mode.
<CR>
is handled by which command? What will happen if we remove it?
<CR>
is handled by nnoremap
. If we remove <CR>
, the cursor will stay in the command mode and you will see :execute "normal :echo 'hi'\r"
in the command line.
\r
is handled by which command? What will happen if we remove it?
\r
is handled by normal
. Without \r
, the normal
command won't press enter after typing :echo 'hi'
.