22

I came across <Plug> in this command of easy-motion

nmap <Leader>w <Plug>(easymotion-overwin-w)

I tried to search for the definition of but no luck. What does it mean?

Does it have anything related with sourcing init.vim(I am using nvim)? I am asking because I found this mapping won't work initially, and I have to source $MYVIMRC manaually to make it work.

2
  • 3
    Have you tried :h <Plug>? How do I navigate to topics in Vim's documentation?
    – statox
    Apr 19, 2021 at 8:20
  • Thank you for reminding me that. I have just looked it up and it said: ` The special key name "<Plug>" can be used for an internal mapping, which is not to be matched with any key sequence. This is useful in plugins using-<Plug>. ` I guess it is used by the plugin itself internally, preventing users from modifying it? Apr 19, 2021 at 8:25

2 Answers 2

28

This is used by plugin authors to make complex mappings available to the user. In a plugin code you define a mapping with <plug>... which is not a real key sequence but which can be used as a right hand side expression in a mapping by your users.

As an example take this line of code from vim-subversive:

nnoremap <silent> <plug>(SubversiveSubstitute) :<c-u>call subversive#singleMotion#preSubstitute(v:register, 0, '')<cr>:set opfunc=subversive#singleMotion#substituteMotion<cr>g@

The right hand side calls the plugin functions and a bunch of other vim commands to change a text object without modifying the unnamed register. The author wanted to let the user decide which key should execute this action. Also they don't want to decide on a particular key sequence as it could have already been used by another plugin. In the doc they could have said to use:

nnoremap <silent> <your-favorite-key> :<c-u>call subversive#singleMotion#preSubstitute(v:register, 0, '')<cr>:set opfunc=subversive#singleMotion#substituteMotion<cr>g@

And that would have worked but the users would have to copy this long command in their vimrc, it's not convenient or easy to read.

So instead the users created the mapping with <plug>(SubversiveSubstitute) which means that you can use this expression as the right hand side of a mapping now. In their config users can simply add:

nmap gc <plug>(SubversiveSubstitute)

To remap gc to the long expression.

Note that here the user had to create a recursive mapping, otherwise <plug>(SubserviceSubstitute) is interpreted as a built-in list of command which will fail.

The help :h using-<Plug> does a great job at describing how this feature works.

7
  • 8
    "the users would have to copy this long command in their vimrc, it's not convenient or easy to read." it also doesn't cope well with possible evolutions of the plugin. The author may decide to change the {rhs} part (I did that a few times already). Plug-mapping act as public interface, meant to be stable as well. Apr 19, 2021 at 9:36
  • @LucHermitte That's definitely a good point.
    – statox
    Apr 19, 2021 at 10:19
  • To be fair, just autoload (and possibly map-expr) can do all this even better.
    – Matt
    Apr 19, 2021 at 11:33
  • 1
    @Matt. Not necessarily as a map-expr could be something quite complex as well (i.e. more than a single function call, but several may be). In the end we are back to the stable API provided by plug-mappings. It also has to be a string, which complicates sequences. BTW I remember map-expr has a few limitations regarding cursor movements: they have to be returned. Apr 19, 2021 at 12:28
  • 1
    Thank you so much for your answer. I get the point now Apr 19, 2021 at 12:30
8

<plug> mappings are meant as customization points. Not everyone will want to use the same shortcut/keybinding as the one chosen by the author of a plugin.

That's where <plug> mappings come in handy. The plugin author can provide a default keybinding (for a given feature of his/her plugin) and still permit end users of the plugin to use another keybinding (for personal taste or to avoid name collisions).

The line you've shown us is typical of what an end-user will put in his/her .vimrc to override the plugin default shortcut associated to <Plug>(easymotion-overwin-w) -- in a plugin this line would have been protected by at least a test on hasmapto('<Plug>(easymotion-overwin-w)').

The old vim tip on wikia(/fandom now) may explain it in better terms: Mapping keys in Vim - Tutorial (Part 3)

Now regarding why it doesn't work in our case. Well, 3 things:

  1. first as you are using <leader> you'll need to set the leader key before the mapping is defined
  2. the mapping needs to be defined -- if it's in your .vimrc or equivalent (init.vim), it should be automatical. Check :scriptname in doubt.
  3. the plugin, the plug-mapping refers to, needs to be loaded
9
  • Thank you so much for your explanation. I found out that my mapping was overridden by the plugin's own mapping. Are plugins source before or after init.vim is completed? Apr 19, 2021 at 13:13
  • Usually plugins are loaded after: :h startup -- we can also load them manually in the .vimrc/init.vim (bad practice), but they'll still be loaded after in step 4. as per Vim documentation) Apr 19, 2021 at 13:22
  • Just checked out :h vimrc and I get the idea now. Is autocmd VimEnter and remap the keybinding there the solution? Apr 19, 2021 at 13:25
  • Now, it's strange that your plugin is overriding your mapping. Plugin authors, that provide <plug>-mappings, usually know how to provide default mapping (w/ hasmapto() + <unique> or a test on maparg()). I remember statox has written a really nice and complete Q/A regarding mapping debugging. Apr 19, 2021 at 13:25
  • Found this question but now sure if it is the proper way of remapping: vi.stackexchange.com/questions/756/… Apr 19, 2021 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.