Localizing Mappings

Because our mappings are going to be specific to our plugin, what are some ways in which we can distinguish them from the mappings a user might already have? And I did say that we were going to see how a user could reconfigure our mappings to his own liking. Let’s see that.

Mapping <SID> Functions

Remember those two variables back in Constructing a Statusline, that were using that special scope? That was the script scope, and we were using that for variables—we had s:count and s:settings. We can use the script scope for function definitions, too:

mappings/map.vim
 
function​! s:ColorfulCuteAnimals()
 
let​ animals = [​"Phil"​, ​"Tom"​, ​"Barb"​, ​"Bob"​, ​"Stacy"​, ​"Peary"​, ​"Mark"​,
 
"Michael"​]
 
for​ a in animals
 
echom​ a . ​" is a tiny animal."
 
endfor
 
endfunction

Now, the whole point of script-local variables or functions is that they’re available only in the script itself. And for script-local variables, there’s no way we can get ahold of them outside of this file, but for functions, we can add a mapping to the file:

mappings/map.vim
 
nnoremap​ ​<leader>​a :​call​ ​<SID>​ColorfulCuteAnimals()​<cr>

We can’t just use s: in the mapping. We have to use a special Vim code, <SID>, to access the function. When Vim comes across <SID>, it replaces it with the script ID, a random number that acts as a special identifier for just that script. We can see this in action by removing that closing <cr> from the mapping and then running the mapping:

mappings/map.vim
 
nnoremap​ ​<leader>​a :​call​ ​<SID>​ColorfulCuteAnimals()​
 
 
" When we run the mapping, the command line is populated with something like:
 
 
:​call​ ​<SNR>​45_ColorfulCuteAnimals()

The <SID> trick works only if the mapping is in the same file as the function, but if the two are in the same script, this is a way for us to keep our functions in script scope and allow for them to have mappings. This approach can even be combined with the next one we’ll look at, so as to allow users to write their own mappings to script-local functions.

Using <plug>

Vim gives us a way to create mappings to keys that can’t be typed, or rather, to key codes that can’t be typed. <plug> is a special key for which we can write a mapping. For example, we can create a mapping from <plug> to one of our plugin’s commands:

mappings/map.vim
 
nnoremap​ ​<silent>​ ​<buffer>​ ​<plug>​MpcPlayselectedsong :PlaySelectedSong​<cr>

This defines something for our user to map to: <plug>PlaySelectedSong. It’s mainly useful in a case where we want our user to be able to write his own mappings for our commands. For example, with our mapping here, our user could add this to his own .vimrc:

mappings/map.vim
 
nmap​ ​<leader>​p ​<plug>​MpcPlayselectedsong

We name the <plug> mapping by the script name Mpc and command name Playselectedsong. By convention, only the first letter of the script name and the first letter of the command name are uppercase—thus the odd capitalization.

We’re going to use one <plug> mapping for our plugin. We’ll have :TogglePlayback be a <plug> mapping so that our user can map that command to whatever key or key combination he wants. The other mappings will be buffer-specific.

In ftplugin/mpdv.vim, add these lines:

mappings/mpc/ftplugin/mpdv.vim
 
nnoremap​ ​<silent>​ ​<plug>​MpcToggleplayback :TogglePlayback​<cr>
 
nnoremap​ ​<silent>​ ​<buffer>​ ​<c-x>​ :PlaySelectedSong​<cr>
 
nnoremap​ ​<silent>​ ​<buffer>​ ​<c-a>​ :ToggleRandom​<cr>
 
nnoremap​ ​<silent>​ ​<buffer>​ ​<c-e>​ :ToggleRepeat​<cr>

We’ve mapped the last three commands to Ctrl sequences. Toggling playback is one function that our user might very well want to use outside of the plugin window, and because :TogglePlayback is not a <buffer> command, it will work from anywhere within Vim. In our playlist window, and only in our playlist window, the user should be able to hit Ctrl-x to play the song that the cursor is on. To turn repeat and random on and off, he can use Ctrl-e and Ctrl-a…and what about :TogglePlayback? Let’s just add a default mapping of our own to <plug>MpcToggleplayback. We’ll use <leader>p.

This is where we learn about the hasmapto function. Vim provides it to help with the issue of conflicting mappings between plugin setups and user setups. Using this function, we can include a check when we define a new mapping, and make it defined only if the user doesn’t already have a mapping in place that’s mapped to the same thing:

mappings/mpc/ftplugin/mpdv.vim
 
if​ !hasmapto(​"<plug>MpcToggleplayback"​)
 
nmap​ ​<leader>​p ​<plug>​MpcToggleplayback
 
endif
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.152.87