111

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?

8 Answers 8

109

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.

It's not my vimrc!

Hurray! Go and ask your question. Be sure to mention that you tried starting Vim without a vimrc file!

So it's my vimrc, now what?

If you haven't already, you probably want to save a backup copy of your vimrc file first.

Check the plugins

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:

  1. Comment out (or remove) about half your vimrc file.
  2. Restart Vim, or open a new Vim (reloading the vimrc is not good enough, as settings aren't unset).
  3. Is the problem now gone? Put back the part you removed out (keeping Vim open and using undo is useful here) and repeat step 1 on the part you added back.
  4. Does the problem still occur? Go to step 1.

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 ;-)

Debugging a single plugin

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.

  1. 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
    
  2. 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
    
  3. 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.

12
  • 11
    This technique is called Binary Search Fault Localization.
    – tommcdo
    Feb 19, 2015 at 23:53
  • 2
    After you figure out your bug, this would be a great time to start keeping your .vimrc under version control :) It's almost always going to be one of the last changes you made to it that made stuff behave strangely.
    – escrafford
    Jun 17, 2015 at 21:02
  • 1
    You don't need -U NONE if you have -u NONE.
    – Antony
    Jul 4, 2016 at 7:59
  • 5
    I've come to prefer 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.
    – B Layer
    Jul 8, 2019 at 11:39
  • 1
    Yeah sure @BLayer; I won't have time in the coming days to do a proper write-up anyway (not that it's that much work, but I like to test out these sort of things to make sure I get all details correct, and also need to look at the details for neovim). I'll accept it and it'll be on top, and this answer is still useful for people with older Vims. Jun 17, 2021 at 4:00
41

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:

2
  • 1
    This was most helpful in finding a simple mistake in .vimrc file that was causing an error message. Worth trying this first as it's quick to do.
    – RichVel
    Jul 21, 2016 at 17:09
  • 1
    @kenorb this command is freaking awesome, save me from going to another editor. Nov 22, 2016 at 14:23
22

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.

14

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.

3
  • 6
    And if you use 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.
    – statox
    Mar 4, 2016 at 8:43
  • This is almost what I needed, I want to see what the value of cpoptions is at a point in my vimrc, how do I echo the output of ":set cpoptions?" ? Jun 15, 2018 at 14:26
  • @MikeLippert you can use echom &cpoptions. Interactively, :verbose set cpoptions? is a bit nicer
    – D. Ben Knoble
    Oct 17, 2020 at 16:19
12

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
6

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.

Overview

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.

Issues 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.

"I feel like a Vim noob!"

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.

"When you say 'NONE' don't you really mean 'SOME'?"

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. ;)

Enter 8.0.0716 and 8.0.1554

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.)

defaults.vim and 'DEFAULTS'

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 '--clean' Flag

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:

  • initializations from files and environment variables is skipped
  • 'runtimepath' and 'packpath' are set to exclude home directory entries (does not happen with -u DEFAULTS).
  • the defaults.vim script is loaded, which implies 'nocompatible': use Vim defaults
  • no gvimrc script is loaded
  • no viminfo file is read or written

Note the second item which solves the problem of loading "after" files and the like.

Neovim

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:

  • Skips initializations from files and environment variables.
  • No 'shada' file is read or written.
  • Excludes user directories from 'runtimepath'

And as with Vim, when you use --clean you won't have to worry about "after" files (third bullet).

4
  • 1
    Is -Nu NONE any better? I use that more often than -u NONE, though I do really like clean.
    – D. Ben Knoble
    Jun 18, 2021 at 10:53
  • 1
    @D.BenKnoble Ah, he does mention -N already. Perfect. But my next edit I'll do so, too, because I noticed a good place to note it.
    – B Layer
    Jun 18, 2021 at 12:26
  • 1
    The other downside to -u NONE is that while it ignores almost all configuration it doesn’t ignore everything. This isn’t just academic! I originally wrote that question after a testing mishap when a plug-in got picked up that I was specifically trying to ignore.
    – Rich
    Jun 19, 2021 at 6:06
  • @Rich Great info which I'll link/integrate soon. Thanks.
    – B Layer
    Jun 19, 2021 at 20:16
1

Here is a vey simple procedure to get you started.

  1. comment out contents of your entire .vimrc file
  2. reload your .vimrc by running :source % or :so $MYVIMRC
  3. uncomment a discreet part of the file (generally starting from the top)
  4. Repeat steps 2 and 3 until you find the error.
  5. fix the error.
2
  • 1
    This answer could be a lot better if you properly capitalised and punctuated it.
    – user579
    Sep 12, 2018 at 6:31
  • Highly recommend doing this with a binary search.
    – D. Ben Knoble
    Feb 27, 2019 at 18:03
1

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.

1
  • 1
    Welcome to the site! This is a useful tidbit, but it's quite a bit more specific than the very general question asked. It might be better added as an answer to e.g. this question, or, if you're just looking to share knowledge, you could perhaps ask-and-answer your own question?
    – Rich
    Oct 3, 2018 at 10:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.