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-cis an operator andhis a motion. It deletes a char before the cursor then start the insert mode. Read:h operatorforc. Read:h left-right-motionforh.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 ainoremapcommand that echoshi.
Extra 2: Per pervious extra. You can also use
<Ctrl-O>to switch to normal mode. Read:help i_CTRL-Oand use it in yourinoremapcommand.
Extra 3: You can use a special key
<Cmd>to enter a hidden command mode. Read:help <Cmd>and use it in yourinoremapcommand.
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
nnoremapcommand 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'.