How to manage the vim Mappings - vim

How to manage Vim Mappings, since each plugins (Pathogen is a great tool used to manage to manage Vim plugins) come with its own mappings. Collisions occur regularly.

Each plugin should come with a description (ideally accessible via the built-in :help) that includes the commands and mappings it defines. You need to read that anyway, in order to find out about the new functionality. You should also remember if one of the plugin's mappings clashes with an existing mapping of yours. :verbose map ... is a simple and great way to investigate your existing mappings.
In case of clashes, plugins using :map <unique> will fail noticeably, but most plugins will just silently overwrite a taken mapping. To fix that, a plugin should define <Plug>... mappings (see :help using-<Plug>; if it doesn't, complain to the author), which allow you to redefine the mappings (according to your tastes or to avoid a clash) in your ~/.vimrc. For example:
:nmap <C-o> <Plug>EnhancedJumpsOlder
The same can also be used to disable a mapping altogether:
:nmap <Plug>DisableEnhancedJumpsNewer <Plug>EnhancedJumpsNewer
Unless you have a lot of custom mappings (e.g. to emulate a different editor's feel in Vim, which you shouldn't do), or you're using lots of plugins, clashes should not be that frequent.

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.

Define persistent abbreviations in Vim

Vim does not seem able to create global abbreviations. So I created an
abbreviations file (called autocorrect.vim) with the following line in
my .vimrc file:
:source ~/autocorrect.vim
I then manually added my abbreviations to this file. If I work in any
document these abbreviations are available to me.
However, if I am working in a new document and try to add new
abbreviations to this list or remove abbreviations, it last only for
the session. Once I quit vim I lose all changes. To make abbreviations
permanent I have to manually edit the autocorrect.vim file directly.
The thing is that if I work in a new document and add abbreviations I
can see that they have been added to my abbreviations list (by calling
:ab). However, when I exit they are lost. How can I make these changes
global and permanent?
I am hoping to find a solution that does not require a plugin.
In order to persist configuration in Vim, it has to be saved in a configuration file, with :help vimrc as the most prominent one. This has both pros (no matter what you do interactively in Vim, any screw-up can be fixed by restarting Vim) and cons (what you want is difficult to do). I see the following options:
Instead of defining abbreviations on the fly with :ab et al, you need to put the command into a separate configuration file, either in your ~/.vimrc, or in a separate config (e.g. ~/.vim/plugin/myabbreviations.vim). This ensures that the abbreviation is persisted for new Vim sessions. You also need to :source the config to import the new abbreviation into your current session. (With the separate config, reloading shouldn't be an issue; it might if your .vimrc is poorly written.) This may sound tedious, but you can define custom :commands to quickly locate, and an :autocmd BufWritePost to automatically :source it. On the other hand, this is a path towards a "plugin solution" that you don't want.
Vim supports sessions (:help session-file) that (with the default 'sessionoptions') store mappings and abbreviations. So if you :mksession after defining a new abbreviation (or just before quitting Vim) and load that session (via :source) in another Vim instance, you'll get to keep your abbreviations, too. Unfortunately, without a plugin, session handling also is a manual process and easy to forget. Also, the granularity of what gets persistent cannot be controlled; it's mostly all-or-nothing.
As already mentioned in the comments, there are plugins that make this straightforward. If this is only about abbreviations for you (and you're happy with the other configuration handling in general), it might be worth a try.
I personally use the first option, with custom commands (:Abbreviate, :SnippetEdit, etc.) that open dedicated scripts.

How does <Plug> work in Vim?

I didn't understand what <Plug> does and how to use it. I read the documentation but it is not clear to me.
<Plug> is just a special, synthetic key that is never actually sent by the keyboard; i.e. you cannot type it.
With this, the :map functionality that comes from old vi can be used as an abstraction layer for plugins.
Instead of directly mapping plugin functionality to a fixed key, plugins define a <Plug>PluginNameFunctionName mapping, which can then be freely remapped to the desired key by the user. As Vim allows to check for existing mappings (via hasmapto()), plugins can also define a default mapping if none was specified by the user.
TL;DR
for your own personal mappings, you can ignore <Plug>
if you use a plugin and need to customize its mappings, :map your own left-hand side to the <Plug>-mapping(s) provided by the plugin
if you write a plugin, enable user customization as described in :help using-<Plug>

Changing default key bindings in vim

After attempting to use vim a number of times, I'm always been put off by its default key bindings. After some research, I decided to remap the default keys to more sane ones (at least for my tastes). I have a few questions about changing bindings that I could not find answers to through Google.
Is there a way to map a key to an action rather than another key. For example:
:noremap a h
will bind the a key to move the cursor left. Is there something along the lines of
:noremap a move-cursor-left
or
:noremap a :move-cursor-left<Enter>
so I can read my config file afterwards?
Is there a way to unbind all of the default key bindings? I've tried :mapclear but it doesn't seem to work, although it might just be clearing non-default bindings. Unmapping every key manually is not an option. If possible, I would like to export the defaults to a file so I can edit them as I need.
Is there another language I can use to write my own commands for vim other than vim-script? I haven't actually looked into this one so much though. If I can bind an external executable to a command, that would be good enough.
I haven't given up on vim although I would like to ask if there are any vim-like alternatives out there. My Google searches came up with nothing actively developed. If the above cannot be done, or reasonably hacked together, I would like to find a fully configurable, modal, command line text editor that can.
The command set of vi / Vim has 40 years of wisdom encoded into it; completely changing it is a bad idea. I can only repeat the reference to this answer from the comments; that should convince you (to accept this, or choose another editor).
Give the default commands another try. It'll take some time to get used to, but most Vim users swear by these. It's fine to make minor adjustments "for personal style": careful evolution, but not revolution. Also, some people with odd keyboard layouts (like Dvorak or Colemak) swap several keys for convenience.
The move-cursor-left is just h; aided by the excellent :help, you should be able to "read" your remappings just fine.
In general, even though it's possible to write extensions / plugins in integrated languages like Perl, Python, Ruby, etc. (based on support for them compiled into the Vim binary), you won't get around learning some key Vim internals and parts of Vimscript. If you don't feel comfortable at all about this, I'd suggest to use another editor. Unfortunately, with your requirements of full extensibility (and probably broad acceptance and platform support), there's only one serious alternative: Emacs (which cannot only be turned into everything but a kitchen sink, but also into a modal editor, too).
(i know this question is old)
you can reset the binds by just over-writing them
on vim you can use many <things> (idk the name)
e.g.
<Up> = Up-arrow-key
<C-f> = Ctrl, f
<A-Down> = Alt, Down-arrow-key
<Esc> = Escape-key
it's possible to remap the hjkl keys to wasd like this:
nmap w <Up>
nmap a <Left>
nmap s <Down>
nmap d <Right>

How to figure out key map redefined in vim plugin?

I installed many plugins by vundle.
I found there maybe multiple plugins use the same hotkey.
Is there smart way to figure out which plugin contains such hotkey?
There are some tutorial about key map. But I still haven't any idea.
A warning
Don't just install many plugins; you'll end up with a complex, slow, and indecipherable mess over time. Especially with plugin managers like Vundle, it's very easy to check out plugins. That benefit can turn bad if you forget to remove plugins that don't turn out to be useful for you.
How to check
In general, the plugin should advertise its features and defaults mappings (and hopefully provides configuration to change those!)
If you indeed have overlapping mappings, you should check:
The plugin's documentation.
The plugin's source code; look for :*[nore]map commands in the plugin/pluginname.vim script.
The actual existing mappings; the :map command lists those. You can restrict the command by modes (e.g. :imap for insert mode mappings) and starting keys (e.g. :map <Leader> lists all mappings that begin with the (configurable) Leader key).
How to change mappings
The canonical way to change plugin mappings is by defining your own mapping to <Plug>... targets that the plugin provides, e.g. :nmap <F1> <Plug>PluginNameMapping, in your ~/.vimrc. Some plugins also use global variables; refrain from modifying the plugin script itself; rather, complain to its author!
Yes, there is.
Use :verbose map <YOURKEY>. It will show you which file was the latest to modify this mapping.
You can always try reading the plugins documentation or source... Till then:
:map <YOURKEY><CR>
will show what was <YOURKEY> mapped to (in normal mode, so you can try it with :cmap, :vmap, etc.). Sometimes it helps if it's mapped to a function which relates to the plugins' name.
And you can issue a single (c|v...) :map to dump the mapping table.
But assuming you might want to know about mapping which used in two (or more plugins), there is no easy way for that. Again, look at the plugins' documentation and/or source code.

Resources