kevin
kevin

Reputation: 785

Regarding the recursive mapping of Vim

Here is the code that is a practice for writing vim plugin. I write it as per the vim docs: :help usr_41.txt section 41.11 write a plugin.

let s:save_cpo = &cpo
set cpo&vim

if exists("g:loaded_echoplugin")
  finish
endif

function s:EchoWord()
  echo expand('<cword>')
endfunction

if !exists(":EchoWord")
  command -nargs=0 EchoWord :call s:EchoWord()
endif

if !hasmapto('<Plug>EchoWord')
  map <F8> <Plug>EchoWord
endif

noremap <script> <Plug>EchoWord <SID>EchoWord
noremap <SID>EchoWord :call <SID>EchoWord()<CR>

let g:loaded_echoplugin = 1

let &cpo = s:save_cpo
unlet s:save_cpo

The code is for displaying the word under the cursor when clicking <F8>. Here is the mapping sequence: <F8> -> <Plug>EchoWord -> <SID>EchoWord -> :call <SID>Echoword() and it works.

Here, however, I have 2 questions:
1. I have used the noremap here, why it is still able to remap or recursive mapping?
2. If I change the mapping from map <F8> <Plug>EchoWord to noremap <F8> <Plug>EchoWord, it will do NOT work.

Could anybody please help to figure it out? thanks!

Upvotes: 1

Views: 626

Answers (2)

romainl
romainl

Reputation: 196546

<Plug>Foo is a mapping. Whether it is itself recursive or not doesn't matter.

When you do a recursive mapping, Vim uses whatever is the current meaning of the commands in the right hand side:

map b B
map <key> db        " works like dB

When you do a non-recursive mapping, Vim uses the original meaning of the commands in the right hand side:

map b B
noremap <key> db    " works like db

<Plug>Foo doesn't mean anything by default so there's no point mapping it non-recursively.

You want recursiveness, here, so you are supposed to use map, imap, nmap, etc.

Upvotes: 7

kevin
kevin

Reputation: 785

I have read the vim docs for the related command carefully, and I have found the root cause. I add it here just for anybody who may concern.

Type the command :help :map-<script> and here is the reason:

Note: ":map <script>" and ":noremap <script>" do the same thing.  The
"<script>" overrules the command name.  Using ":noremap <script>" is
preferred, because it's clearer that remapping is (mostly) disabled.

Upvotes: 1

Related Questions