There are so many hotkeys in Vim - then how to choose a hotkey for your custom action? - vim

In Vim you often need to assign a key for your own custom action. But there are so many key combinations that already have an action mapped to them by default. How do you choose free key combinations when you need to assign you custom action to one?
In these situations I usually get lost and just assign my action to a custom command instead of a key, like :docoolstuff instead of a simple keypress.
And, by the way, do you often remap a default action to use a custom action on this key combination instead?

Personally, I bind custom command to leader - {key}. For example:
let mapleader = ','
nnoremap <leader>s : so $MYVIMRC<CR>
nnoremap <leader>v : tabe $MYVIMRC<CR>
I can press ,v to open vimrc in a new tab.

I use F1-F12 which work reliably enough for me. That's more keys than most would ever need. The higher keys are in my static setup, the lower ones are used for throw-away bindings.

Don't forget alt-gr+key, which gives you a whole new set of characters to bind to. But mapleader, as suggested in the accepted answer, is the most standard practice.

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.

Translucent Vim map for short manual about keys after it

In (Neo)Vim, I want to configure a key as if it passed through one-way mirror.
For example, in normal mode, when I type <Leader>, the command :echo "w: Separate Window f: Open File c: Configure Settings" run (so I can get help from at the bottom of the screen), but the <Leader> still has influence on following keys --- such as w, f, c, and so on --- and <Leader><KEY> works properly.
I mapped lots keys with <Leader>, so it will be very helpful for me to display a short manual about keys follow <Leader> at the bottom of the screen when I type <Leader>.
Thanks.
First, <leader> is not a special key at all. It's a placeholder expanded by Vim to the current value of mapleader whenever it is used. Assuming your mapleader is , (as instructed in :help mapleader), the mapping below:
nnoremap <leader>f :find *
will be registered as:
nnoremap ,f :find *
Second, when Vim detects that the key you just pressed is part of several custom or built-in commands it waits a bit for you to press more keys in order to decide what to do. With , as your mapleader, pressing , will always puzzle Vim because , is an actual command in its own right and you have a bunch of custom mappings starting with ,. In this situation, Vim waits for a full second before deciding you actually wanted , and not ,f.
Third, you would almost certainly need to write a completely separate mapping mechanism for achieving you idea. A mechanism that would:
listen to key presses,
trigger a specific function when you press <leader>,
that prints something helpful in the command-line,
and waits indefinitely for another key to be pressed.
This doesn't sound trivial at all. Did you take a look at the "scripts" section of http://www.vim.org?
Four, the whole point of a mapping is to map a common action to an easy to remember shortcut. You definitely have too many mappings if you can't remember all of them. Maybe it's time to reconsider the root issue instead of looking for a workaround?
You can do that with the following mapping:
:nnoremap <Leader> :echo "w: Separate Window f: Open File c: Configure Settings"<Bar>call feedkeys((exists('g:mapleader') ? g:mapleader : '\'), 't')<CR>
This uses feedkeys() to send the <Leader> again after the help has been shown. However, this solution has the key timeout downsides already mentioned by #romainl: The message will only appear after the 'timeoutlen' delay, and then you have to press the correct mapping key within 'timeoutlen'.
alternative
I would rather print the help on <Leader><Leader>. There are no timeout issues here. If you have pressed <Leader> and then fail to remember what's the next key, just press <Leader> again, read the help, and then start again with the (now memorized) full mapping!

How to map keys for IdeaVim's normal mode to editor's action?

I am using JetBrains' phpstorm with the IdeaVim plugin.
I am wondering if I can bind keys in normal mode to editor actions.
For example, I used to have mapped Ctrl+B to Navigate > Declaration. Yet Ctrl+B is a vi motion to go one page backwards and that is ok.
I know I can configure a keyboard shortcut to a different one, e.g. Ctrl+Shift+B , yet to keep things simpler I want to have a key in ideavim's command mode mapped to that functionality, e.g. ;.
So that pressing ; in command mode would trigger the action of Declaration witin phpstorm.
How can I achieve this?
To give a specific answer for exactly what you asked to map: put this into your ~/.ideavimrc:
nnoremap ; :action VimGotoDeclaration<CR>
To find the action name, I typed :actionlist declaration which gives a subset of action names that include the word "declaration" in the action name.
As others have noted, you might also prefer to use one of the existing mappings rather than adding a new one.
what you wanted go to declaration is built in command in vim. You don't have to use IDEA's actions.
gd (goto declaration) is the thing you are looking for.
So you just press (normal mode) gd, to see what is gonna happen.
In a normal vim, do :h gd to check details.
You can use <C-]> (Ctrl+]) for following references (jumping to the declaration is an example of a reference) and <C-O> for going back. You can also map these Vim-style shortcuts using the map commands similar to the original Vim.

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

Vim custom keybinding conventions?

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

Resources