I have been working with vim and nvim for the last three month and I have build a good amount of mappings, after profiling my startup time I have realised the creation of all this mappings has slow down, ~40ms, my startuptime.
I would like to know if there is a way to load mappings on demand, sort of { 'on': 'Mappings' } with vim-plug, or using an if statement and load them after vinEnter?
You might find what you seek in :help autocmd or :help augroup
as sergioaraujoh pointed out in his [comment]: Load mappings on demand any time you create a autocmd you should consider wrapping it with an augroup to be able to prevent multiple execution in case of douplicate autocmds.
For example, you could create a function
function SetMappings()
nnoremap <key-binding> <command>
... more mappings
endfunction
and then you would setup an autocmd to load those mappings when needed.
autocmd FileType php call SetMappings()
In this case the mappings would be set on opening a PHP file. The autocmd does not have to rely on a FileType though, :help autocmd really is your friend here since you are basically only limited by your imagination.
Related
I want to create a plugin which maps a certain localleader mapping to a function call.
I have a ftplugin/javascript.vim file with the following content:
augroup javascript_pluginName
au!
echom "The plugin is loaded for JS"
au FileType javascript nnoremap <buffer> <localleader>j :call pluginName#pluginName#funName()<cr>
augroup END
When I open a javascript file, the message is printed, but then checking the mapped combinations shows that there is no such mapping.
I understand, that nnoremap is simply not going to map on top of other mappings. However, if I only leave the nnoremap command, without putting it in an autocmd, it would map properly.
Simply executing the call in command mode also works fine.
I looked into the vim help to see how to use autocmd, and I can't see any difference between the way I use it and what is explained there. The "Learn Vim the Hard Way" book also didn't help.
Is there something I'm missing? Should I frame the autocmd somehow differently?
I finally found out what the problem is!
Apparently, according to this article: https://vimways.org/2018/from-vimrc-to-vim/ if you put a filetype specific code into a filetype plugin, there is no need to create an autocmd for it.
The boilerplate is all made redundant by the general behaviour of vim setting the filetype on open and then running the ftplugin scripts, which are relevant for the file.
This means that in my ftplugin/javascript.vim file I only need the mapping:
nnoremap <buffer> <localleader>j :call pluginName#pluginName#funName()<cr>
I've recently installed the VimWiki plug-in, and am learning about Vim's plugin architecture in general (and better using directories like after/ftplugin instead of cramming everything into my .vimrc file).
I would like to call a function prior to writing wiki files, like so:
autocmd BufWrite *.wiki call CleanMarkdown()
However, vimwiki sets its own BufWrite autocommand, which updates any tables-of-contents in the wiki file. I could clobber this autocommand with my own function that calls both the CleanMarkdown() plus whatever vimwiki is doing today, but that would be brittle in the face of possible future changes in the vimwiki plugin.
Is there a standard way to add to the list of things to do for a BufWrite autocommand?
Multiplicity of autocmds
There can be many :autocmds for any event; the command is cummulative. The corresponding :autocmd! removes certain sets of commands (depending on the arguments given to it).
If you don't specify a [group], the autocmd will be defined in the global space, and there's a high risk of getting this cleared by some :autocmd!. Therefore, it is recommended to specify a [group] (especially in plugins). With this, you avoid that another (mis-behaving) plugin or customization clobbers your autocmd.
Integrating with vimwiki plugin
As the plugin already defines its own filetype, you don't need to duplicate the filetype detection logic, i.e. the *.wiki pattern. Instead, if you put your :autocmd definition in ~/.vim/after/ftplugin/vimwiki.vim, you can use the <buffer> special pattern to make this autocmd apply only to the current (VimWiki) buffer.
augroup MyVimWikiCleanup
autocmd BufWrite <buffer> call CleanMarkdown()
augroup END
Ordering
The :autocmds are executed in the order in which they were defined. By using the after directory, yours will be executed after the plugin's.
The :Gstatus window has specific mappings for that particular buffer. In my case, I would like to change the cc mapping to not only execute :Gcommit but also go into insert mode afterwards.
It seems like the user robodendron figured out how to do this as shown in https://github.com/tpope/vim-fugitive/issues/647, but I'm don't know what he means when he says "changing the order should be enough." Also, I would ask this on the Git issues page, but it seems like the user NicolasWebDev already tried that and no one got back to him.
I can add mappings by creating a after/ftplugin/gitcommit.vim file, but modifying an existing mapping seems to be more difficult since the mapping is defined after the filetype is set.
Also, I could modify the source code mappings, but we all know that's more of a temporary fix.
I am not sure about trying to alter :Gstatus mappings, but you can start insert mode when entering the commit buffer.
Add the following to your vimrc file:
augroup turbo_commit
autocmd!
autocmd BufEnter COMMIT_EDITMSG startinsert
augroup END
For more help see:
:h :autocmd
:h :augroup
:h BufEnter
:h startinsert
I use MacVim and in my .vimrc file I have map ,V :source $MYVIMRC<CR> binding that allows me to apply the newest version of .vimrc in a case it was recently modified.
However I noticed that strange things can happen, relaunch can slow down vim and some plugins can start to conflict after pressing ,V, when everything works fine if I just close and relaunch MacVim from the scratch.
I'd be very thankful if you could give me a hint on the reason of this behavior as I'd like to have a possibility to update .vimrc file that will completely clear internal vim state and grab new configuration file
The only viable way to re-apply your config to a pristine Vim is actually to restart it.
But the most likely cause of slow downs is the overuse/misuse of autocommands.
Autocommands are added without checking for existing ones. One consequence is that they tend to pile-up if you don't manage them properly and every individual autocommand corresponding to a specific event is executed when that event is triggered, leading to dreadful slow downs.
Here are the two ways you are supposed to use autocommands in your vimrc:
Method #1
" anywhere
augroup nameofthegroup
autocmd!
autocmd EventName pattern commandtoexecute
autocmd AnotherEventName anotherpattern anothercommandtoexecute
augroup END
Method #2
" near the top of your vimrc
augroup nameofthegroup
autocmd!
augroup END
" anywhere
autocmd nameofthegroup EventName pattern commandtoexecute
autocmd nameofthegroup AnotherEventName anotherpattern anothercommandtoexecute
The idea is to create a group of autocommands that clears itself whenever it is invoked and thus prevents them from piling-up.
I found this nice plugin for distraction free writing named Goyo, which is really well done.
I setup autocmds to enable Goyo based on the filetype, so if I work on a markdown or textfile Goyo gets initialized automatically. If I leave the buffer or change the filetype then Goyo gets closed. Below is how I implemented the behaviour:
autocmd FileType * :Goyo!
autocmd FileType markdown :Goyo
autocmd FileType text :Goyo
That seems to work fine. The question is, whether or not this is the way to go or if there is a better approach to solve the problem?
That's just fine and how I would implemented it, too. As you only hook into the FileType event, the toggling is only triggered when you :edit a new file, not when you recall an existing buffer with another filetype. You could do that with BufWinEnter, but it may cause too many inadvertent togglings. I guess the plugin comes with a quick toggle mapping to manually do this, anyway.
Alternative
An alternative to the autocmd FileType commands is filetype plugins (i.e. ~/.vim/ftplugin/markdown.vim etc.), which have the benefit of separating things neatly. But as you need a catch-all autocmd to turn off Goyo, and the list of filetypes is small, I would also prefer keeping things together, just like you did.
Improvements
Note that your set of commands would add a duplicate set of autocmds if you re-:source your ~/.vimrc (or whichever script you've put them in). To avoid that, you could wrap them in
augroup AutomaticGoyo
autocmd!
...
augroup END