Vim custom keybinding conventions? - vim

In Emacs, key sequences beginning with C-c are, by convention, reserved for individual users to set. I think there is at least one more convention, too.
What, if any, are Vim's conventions for custom key bindings?

You can use commands prefixed with your <leader> key as a convention to separate your own individual keymaps from default ones.
Set your <leader> key with a like this in your .vimrc file:
let mapleader = "_"
Then you can create key mappings that are prefixed with whatever you set your leader to like this:
nnoremap <leader><space> :noh<cr>
For more info see here

In Emacs, I would't say it was so much of a a convention, as much of a popular choice.
In Vim there is not even that, and although Ctrl+something or the F keys are popular, it is far from being a wide spread "convention".
A lot of Vim users just use the default "letter operations" in normal mode, with which they accomplish in text editing, what a majority of Emacs users must depend on functions.

There is a backslash which does nothing by default, only being the default value of mapping leader (both mapleader and maplocalleader). This leader is used in plugins and I strongly suggest to leave it for them only, using keys that have default actions attached, but that are not much useful. Common keys are , (repeats t/T/f/F motion in the opposite direction) and _ (moves one line downward, on the first non-blank character), you can also check which ones you don’t use (I, for example, don’t use + and -, latter is good replacement for _). The reasons why I unlike #stonesam92 suggest not to set mapleader to them and instead put your own leader in your mappings directly are the following:
It makes plugins possibly add mappings conflicting with your own ones.
You get used to typing ,a, _a or whatever, not to <Leader>a.
It makes mapping commands work differently depending on their location in the vimrc (<Leader> is computed only once, if you change mapleader afterwards already defined mappings won’t change).
It obfuscates the reading: you have to always remember, what <Leader> is.
If you are writing plugin, always use <Leader> and also leave the user the better way to customize them, two common solutions are using global options and using hasmapto:
" Global option
if !exists('g:plugin_mapping_key')
let g:plugin_mapping_key='<Leader>a'
endif
execute 'nnoremap '.g:plugin_mapping_key.' :DoSomething<CR>'
" hasmapto
nnoremap <Plug>PluginDoSomething :DoSomething<CR>
if !hasmapto('<Plug>PluginDoSomething', 'n', 0)
nmap <Leader>a <Plug>PluginDoSomething
endif

Related

Conflict between remaps using plugins

I am currently using the NERD commenter plugin to define certain mappings that allow me to comment/uncomment blocks of code. One of the default mappings is:
[count]<leader>c<space> Toggles the comment state of the selected line(s). If the topmost selected line is commented, all selected lines are uncommented and vice versa.(NERDCommenterToggle)
I have remapped this options using nmap <C-_> <plug>NERDCommenterToggle and vmap <C-_> <plug>NERDCommenterToggle
My intention is to toggle between commented and uncommented in normal and visual mode using <C-_>.
The conflict arises because I have set the spacebar as my leader key and I have also set it up as a remap for folding: nnoremap <space> za.
When I put all of this together on my .vimrc pressing <C-_> folds the part of the document if it is "foldable", otherwise it toggles the comments.
The only reason that I can think of for this to happen is that, behind the scenes, <C-_> is still calling the default mapping of the plugin, which, because it contains the leader key, which is mapped to the spacebar is folding the code.
I am not that deep into vimscript, so I don't know if this is the intended behavior but it seems to me very weird that even though I have remapped the NERDCommenterToggle command, it still calls the default map. I was under the impression that the <plug> handles were used to avoid this kind of problems.
If this is indeed the intended behavior, is there a way to create a map to NERDCommenterToggle without it conflicting with the original mapping?
EDIT:
I removed the mapping of my leader key to space and the problem persists, which doesn't make any sense to me. Basically now I have the maps:
nmap <C-_> <plug>NERDCommenterToggle
nnoremap <space> za
and for some reason they interfere with each other and pressing "control + /" (<C-_>) triggers the folding maps.
Background
The whole point of <Plug> mappings is for plugin developers to provide a clean way for end users to make their own mappings without calling internal functions and such. Some of the benefits of that interface are:
ease of use for the end user,
possibility of changing the implementation without impacting the end user,
simplification of the documentation,
collision prevention,
etc.
Ideally, plugin developers should only expose <Plug> mappings, if only to prevent collision with other mappings, from other third-party plugins or by the end user. But that is entirely left to the developper: in no way does the use of a <Plug> mapping by the end user prevents the plugin developer from creating their own default mappings.
The problem
In this specific case, the author chose to create default mappings out of the box (g:NERDCreateDefaultMappings is set to 1) as well as their <Plug> equivalents. This leaves you with two mappings for the same feature (more, actually, because of modes, but let's keep it simple):
nnoremap <Plug>NERDCommenterToggle :call nerdcommenter#Comment("nx", "Toggle")'
nmap <Leader>c<Space> <Plug>NERDCommenterToggle
To which you add a third one:
nmap <C-_> <plug>NERDCommenterToggle
Since the default <Leader>c<Space> mapping is still there and your leader is <Space>, you are bound to find conflicts.
Plan A
Disable the plugin's ability to define default mappings with:
let g:NERDCreateDefaultMappings = 0
as per :help NERDCreateDefaultMappings. This puts you in control so you are free to build whatever mapping you need from the provided <Plug> mappings without the default mappings getting in the way.
Plan B
Note that it is also technically possible to "unmap" that pesky <Leader>c<Space> mapping with:
nunmap <Leader>c<Space>
But the plugin defines its default mappings after your vimrc is sourced so you can't simply add the line above to your vimrc as it will a) throw an error because the targeted mapping doesn't exist at that time, and b) not do anything useful anyway. Using that method efficiently opens quite the can of worms so I recommend plan A.

Recommended vim keymap "namespaces" for custom keymaps?

Vim seems to have bound every key on the keyboard with actions. If I wanted to create some custom keymaps for often-executed commands, are there any keys that are recommended that I use or that are intended to be overridden?
You're right, for often-invoked mappings, the default <Leader> of \ isn't optimal. Some people reassign via mapleader, but if you use many plugins, that again leads to contention and long <Leader>abc... mappings.
My approach is to keep the leader, and start the few quick and often-used mappings with , instead. The original functionality of , isn't that important, but I've reassigned it to ' (for which I can alternatively use `; I don't usually need line-only jumps):
:noremap ' ,
In addition, you have the function keys for very quick access (though you have to lift the hand from the home row). If you're mainly in GVIM, you can also map all Shift / Ctrl / Alt combinations; in the terminal, these might not work.
Finally, there are some unused combinations. For example, yr (though there's yank and replace, there's no r motion), or q followed by any non-(writable-) register: q., q#, ...
I'll assume you don't want to use a <leader> mapping.
There are an infinite number of possible mappings, you can check if one you are thinking of is in use by a plugin via::map, :nmap and :imap.
You can check default mappings using :help
You may also be interested in Tim Pope's thought on the subject:
leader maps are pretty lame

Keys and key combinations in Vim with no function

In Vim I (of course) use keymappings to make my life easier, but when making a key mapping of my own I would really know if that key (or key combination) had some purpose before I potentially remap it.
So my question is: which keys/key combinations in Vim does not have a function? and is there by any chance a way to get Vim to list which?
You can generally use :help <key> to see if it's taken in normal mode and :help i_<key> to see if it's used in insert mode. Furthermore, you can use :map <key> to check if anything is mapped by your vimrc or plugins. This also works for imap, nmap, etc.
For example:
:help j
:help i_CTRL-N
:imap <Tab>
As far as a list goes, all of the capital and lowercase letters from A-Z have some meaning assigned to them. Most CTRL+<key> keys have meaning in all modes but some don't. The default <leader> key is \, but many people set that to ,; however, , has a special meaning in normal mode (opposite of ;). I suspect that most people map custom keys to <leader><key> or an <F#>. Often times keys that do have a default meaning aren't ones you actually desire, so looking up :help is a good practice since it not only increases your understanding of vim but also lets you make a judgment call on whether you need that functionality or not.

How to remap <C> (control) modifier key in vim?

I avoid the "control" key, AKA <C> in vim parlance, on my laptop; I hate where Apple put it. I would really like to remap all of the vim commands using control to instead use "command", but this does not seem possible on a Mac, despite what I have read. I have read that I should use <Leader> to set such mappings, but I want to avoid remapping every single <C> mapping that I can find or think of in my .vimrc, just to forget some and bloat my .vimrc.
I want to avoid xmodmap or solutions beyond the scope of .vimrc, as I want to maintain compatibility of my config files that I sync across systems.
What I really want to do is specify an alternate key (probably ,) as a modifier key equivalent to <C>.
There is definitely no vim-only solution for this; vim simply does not have this capability. Map <CapsLock> to <Ctrl> in System Preferences -> Keyboard -> Modifier Keys..., take a few minutes to adjust, and repeat for every MacBook you ever lay hands on (even if it's not yours). The world will be a better place for it.

VIM: Mappable (unused) shortcut letters?

I'm trying to create two mappings which are efficient for myself:
map X ddp
Which I'd use to delete and paste in one go.
map X "_dw
Which would delete a word without yanking into a register.
However I don't want to break any existing, useful shortcuts so I'm wondering what keys I could use - any suggestions? Am I being too uptidy?
vim help has a section :he map-which-keys
1.7 WHAT KEYS TO MAP *map-which-keys*
If you are going to map something, you will need to choose which key(s) to use
for the {lhs}. You will have to avoid keys that are used for Vim commands,
otherwise you would not be able to use those commands anymore. Here are a few
suggestions:
- Function keys <F2>, <F3>, etc.. Also the shifted function keys <S-F1>,
<S-F2>, etc. Note that <F1> is already used for the help command.
- Meta-keys (with the ALT key pressed). |:map-alt-keys|
- Use the '_' or ',' character and then any other character. The "_" and ","
commands do exist in Vim (see |_| and |,|), but you probably never use them.
- Use a key that is a synonym for another command. For example: CTRL-P and
CTRL-N. Use an extra character to allow more mappings.
See the file "index" for keys that are not used and thus can be mapped without
losing any builtin function. You can also use ":help {key}^D" to find out if
a key is used for some command. ({key} is the specific key you want to find
out about, ^D is CTRL-D).
Many Vim plugins use an initial <Leader> to start their key sequences; this is an (otherwise normally) unused key that is configurable by the user.
*<Leader>* *mapleader*
To define a mapping which uses the "mapleader" variable, the special string
"<Leader>" can be used. It is replaced with the string value of "mapleader".
If "mapleader" is not set or empty, a backslash is used instead. Example:
:map <Leader>A oanother line<Esc>
Works like:
:map \A oanother line<Esc>
But after:
:let mapleader = ","
It works like:
:map ,A oanother line<Esc>
Note that the value of "mapleader" is used at the moment the mapping is
defined. Changing "mapleader" after that has no effect for already defined
mappings.
Every single ASCII character, upper and lower case, is used for something in Vim. So you're going to wind up overwriting something--just pick something that you don't use. It may help to use a common idiom for your own extensions. I use a leading comma, for example:
map ,w :w!<CR>
map ,e :e #<CR>
imap ,, <ESC>
(The last is particularly useful for me, since I pretty much never need to write two consecutive commas in insert mode, and it's nice not to have to go all the way to the Esc key.)
Typically I use control + [letter] or alt + [letter] for most mappings and it's safe, but watch out for 'w' since that's needed for window commands. You might also be interested in arpeggio.vim which lets you create mappings to simultaneously pressed groups of keys - it will massively expand the possibilities for your mappings with no danger of over-mapping something. For example, you could map "dp" (pressed simultaneously) to execute "ddp" to delete and paste in one command.
Uhmm, no, don't. When creating your mappings try not to overwrite anything ... not so much because you don't use the command you're overmapping, but because some plugin which you have/or will have maybe using it.
And then you overmap it, and then you have to worry.
Personally, for commands such as you gave as an example, I like Ctrl+some key combinations. There are a lot of free ones in vim, and the letters on the left side near Ctrl make a nice pair then.
Btw, what are you trying to do with those mappings ... I understand the second one (delete word by word), but the first doesn't make sense to me. What is it supposed to do ? Transpose lines ?

Resources