I have a problem in Vim, and I think it may be in my vimrc
file (or have been told it could be my vimrc
file).
How do I verify this? If it is my vimrc
file, how do I know where exactly the problem lies?
The first thing you want to do is to start Vim with the default settings:
vim -u NONE -U NONE -N
The -u NONE
prevents Vim from loading your vimrc, -U NONE
prevents Vim from
loading your gvimrc, and -N
tells Vim to use no-compatible mode (this isn't
required, but most Vim users are not used to "compatible" mode).
Note that the NONE
is required to be in all-caps.
In Windows you can add these flags by creating a new shortcut1.
If the problem stays, then you know it's not something in your vimrc.
If the problem disappears, you now it's caused by something in your vimrc file.
Hurray! Go and ask your question. Be sure to mention that you tried starting Vim without a vimrc file!
If you haven't already, you probably want to save a backup copy of your vimrc file first.
The next thing you probably want to do is disable all plugins first; plugins can
alter quite a bit in Vim. If this fixes the problem, then try to find out
which plugin by re-enabling them one-by-one. After you've found out which
plugin exactly causes the problem, you can try & fix it by reading this plugin's
documentation, and/or by asking a question tagged with plugin-<name>
.
If it's not a plugin, and you don't have any idea what's causing your problem, then it's a trial-and-error procedure. Comment out one or more lines in your vimrc, start Vim, check if the problem occurs, and repeat this procedure until the problem stops occurring. The fastest way of doing this is:
In the end you should have a single option or a combination of a few options that causes your problem. You can find out more about any option in Vim by using:
:help 'option_name'
The quotes are important here, it usually works without them, but sometimes you end up on the wrong page if you omit them.
If you're still confused after reading the help page, you know where to ask a question ;-)
If you want to isolate a single plugin, perhaps to ask a question about it, you want to load as little as possible but still load the plugin; you can easily do this with Vim's packages feature. This requires Vim 8 or a reasonably recent version of Neovim.
Create a new empty directory; we'll use the ~/plugin
path in this example.
Now put the plugin in the regular pack/plugins/start/$name
directory. For
example:
git clone https://github.com/fatih/vim-go.git ~/plugin/pack/plugins/start/vim-go
Create a test-vimrc
file with the following contents; this will ensure that
Vim will load plugins from the ~/plugin
directory and not the ~/.vim
directory:
set nocompatible
set packpath=~/plugin,/usr/share/vim/vimfiles,/usr/share/vim/vim80,/usr/share/vim/vimfiles/after,~/plugin/after
packloadall!
syntax on
filetype plugin indent on
Start Vim with:
vim -U NONE -u ~/test-vimrc
You now have a minimal vimrc with just this single plugin.
Footnotes
1 For example: on 64 bit Windows, the shortcut would look something like this: "C:\Program Files (x86)\Vim\vim74\vim.exe" -u NONE -U NONE -N
. To create it, right click in File Explorer where you want the shortcut, then select New -> Shortcut and paste the shortcut text. You may need to change the Vim path if your Vim is installed in another location.
vim --clean
for many situtations. Besides being easier to type, it's equivalent to -u DEFAULTS -U NONE -i NONE
plus a few more bits like excluding $HOME from $RUNTIMEPATH. -u DEFAULTS
uses defaults.vim
as vimrc...which means Vim is actually usable while you debug.
There is -D
Vim parameter specially for debugging which will go to debugging mode after executing the first command from a script.
E.g. to run Vim in debug mode without any plugins, run as:
vim --noplugin -D
Type n
/next
to parse the next line and keep pressing Enter.
And cont
or q
to go back to vim
interface.
If you're using a GUI version, put a gui
command in your vimrc to start the debugging right after that command.
Press Ctrl+d for list of available commands
Read more:
:help debug-scripts
As already mentioned, first try vim -u NONE -U NONE -N
to make sure your vanilla vim is working fine.
Then start vim normally and check
:messages
from inside vim after the problem, which will show all warnings and errors.
Finally start vim with the following command
vim -V9logfile.log
which will create a logfile called logfile.log
, -V9
is the logging level and try to reproduce your problem.
One more tip: as caveman as it may seem, I do like adding :echom "message" to my .vimrc to see whats being executed and what is not.
For example
if executable('ag')
:echom "AG FOUND"
...
endif
This helps me quickly see if the if block is being executed, etc. The message will be printed on the console next time you start vim.
echom
another interesting command is :messages
to get the full log of the messages echoed. It can sometimes be useful to look at them after the startup.
echom &cpoptions
. Interactively, :verbose set cpoptions?
is a bit nicer
One thing that I've found helps is keeping a collection of variables that toggle parts of your .vimrc
so you can disable or enable portions of it without having to comment stuff out. It also has the pleasant side effect of forcing you to think about the organization of your .vimrc
.
" feature toggles in vimrc
let g:vimrc_feat_pathogen = 1
let g:vimrc_feat_core_minimal = 1
let g:vimrc_feat_matchit = 1
let g:vimrc_feat_options = 1
let g:vimrc_feat_colors_and_highlight = 1
let g:vimrc_feat_key_rebinding_arpeggio = 1
let g:vimrc_feat_key_rebinding = 1
let g:vimrc_feat_autocommand_group = 1
let g:vimrc_feat_custom_definitions = 1
let g:vimrc_feat_load_opam = 1
Here's an example of a section guarded by an if
:
if g:vimrc_feat_core_minimal
set nocompatible
filetype plugin indent on
syntax on
endif
If you are using a version of Vim prior to 8.0.0716 or Neovim build #9907 skip this and jump to the answer posted by @MartinTournoij which describes the Vim flags available to you for setting up clean configurations.
This answer describes the command-line flag --clean
, introduced in Vim 8, as a recommended alternative to -u NONE
and related flags.
If you're not familiar with said flags or vimrc debugging in general you may want to start with a read of the answer linked above then return here to get up to speed on more recent developments.
Either way, here is a summary of the flags in question:
-u NONE
: Skip all initializations from files and environment variables.-U NONE
: Don't load any "gvimrc" (GUI initialization) files. Redundant when -u NONE
is present.-i NONE
: Don't read/write the "viminfo" file.-N
: Equivalent to :set nocompatible
. In other words, don't enable emulation of legacy editor 'vi'. Usually used with -u NONE
.-u NONE
is fairly well known and widely used to help debug issues with Vim that are thought to be caused by user/local configuration. It has some pitfalls, though.
With -u NONE
enabled you may find Vim annoying if not difficult to use. For example, command-line history and command and filename completion are gone which means having to type everything manually. File type detection is disabled so you won't have syntax highlighting to make things more legible. And surely worst of all, 'compatible'
will be enabled which makes Vim behave in ways alien to many modern Vimmers.
The 'compatible'
part can be solved by using -N
with -u NONE
but everything else is off/default and you still have the potential issue described in the next section.
There are additional local customizations one can apply besides those found in your personal vimrc file. For an example here's an excerpt from a question @Rick pointed out to me where he asked about disabling such settings:
the runtimepath option still contains ~/.vim and, notably, ~/.vim/after, (so e.g. if I subsequently turn on file type detection and change filetype, code in ~/.vim/after/syntax/the_relevant_filetype.vim will be executed).
Source: How can I get Vim to ignore all user configuration, as if it were freshly installed?
-u NONE
is of no help here. (The top answer there is, spoiler alert, --clean
. ;)
Vim patch 8.0.0716 gives us solutions to the issues detailed in the "noob" section, above, and patch 8.0.1554 covers the issue described in the section following it. (These patches were merged into Neovim but they are necessarily scaled down quite a bit. See below.)
First up is the introduction of DEFAULTS
as an argument to -u
, e.g. vim -u DEFAULTS myfile
. Instead of loading no vimrc file like -u NONE
this will load $VIMRUNTIME/defaults.vim
. This file contains a sane, stable configuration that makes Vim far more usable while being unlikely to impede your debugging efforts. That configuration includes all of those things I mentioned as missing in the "noob" section above. (If some included configuration does impact your debugging take a look in the file because it contains instructions on how to reset individual settings as well how to revert a number of the commands it runs.)
Side note: I actually load defaults.vim as one of the first steps in all of my vimrc files. Even if you override/revert a setting or two it'll likely reduce the size of your vimrc.
The next thing we get from the patch, and the reason we're all here, is the flag --clean
. It has an effect similar to using these flags: -u DEFAULTS
, -U NONE
and -i NONE
but with an added punch. I'll turn to :h --clean
for the details:
'runtimepath'
and 'packpath'
are set to exclude home directory entries (does not happen with -u DEFAULTS
).defaults.vim
script is loaded, which implies 'nocompatible'
: use Vim defaultsgvimrc
script is loadedNote the second item which solves the problem of loading "after" files and the like.
There is no defaults.vim file included with Neovim because it's default settings are considered sane and are familiar to modern users. Most signficantly there's no 'compatible'
setting; no vi compatibility, period, in Neovim. So --clean
is more limited though still may be useful. It is equivalent to -u NONE
and -i NONE
and, again, quoting the the documentation:
'shada'
file is read or written.'runtimepath'
And as with Vim, when you use --clean
you won't have to worry about "after" files (third bullet).
-N
already. Perfect. But my next edit I'll do so, too, because I noticed a good place to note it.
Here is a vey simple procedure to get you started.
:source %
or :so $MYVIMRC
My vimrc loading time was very slow, around 400ms, and i reduced it to 20ms only by removing this line:
silent !mkdir ~/.config/nvim/backups > /dev/null 2>&1
Make sure you don't have calls to external commands like that.