Customizing Vim
Settings like indentation and keyword-pairs can vary between different programming languages and file types. You might need to adapt style guides based on client requirements. Or perhaps, you wish to create or override commands to suit your preferences.
This chapter will discuss how you can customize Vim for different purposes. Some of the settings will be specific to GVim.
Documentation links:
- :h usr_05.txt — set your settings
- :h usr_40.txt — make new commands
- :h usr_41.txt — write a Vim script
- :h usr_43.txt — using filetypes
- :h options.txt — reference manual for Options
- :h map.txt — reference manual for Key mapping, abbreviations and user-defined commands
- :h autocmd.txt — reference manual for Automatic commands
Editing vimrc
From :h usr_41.txt and :h vimrc-intro:
The Vim script language is used for the startup vimrc file, syntax files, and many other things.
The vimrc file can contain all the commands that you type after a colon. The simplest ones are for setting options.
This chapter only covers some use cases. You'll see what some of the settings do, how to use mappings, abbreviations and so on. Not much will be discussed about the programming aspects of Vim script. Make sure you have a vimrc file using the following details:
- :e $MYVIMRC if you already have a
vimrcfile, you can use this predefined variable to open it - :h vimrc to find out where the
vimrcfile should be located for your OS - :source $MYVIMRC apply changes from within your current Vim session
To view a sample
vimrcfile, I have one on GitHub. More resources are mentioned in the Further Reading section at the end of this chapter.
defaults.vim
If you haven't created a vimrc file, the defaults.vim file that comes with Vim installation will be used. This file aims to provide saner defaults like enabling syntax highlighting, filetype settings and so on.
- source $VIMRUNTIME/defaults.vim add this to your
vimrcfile if you want to keep these defaults - :h defaults.vim-explained describes the settings provided by
defaults.vim
Alternatively, you can copy only the parts you want to retain from the defaults.vim file to your vimrc file.
General Settings
![]()
setsyntax and guidelines were introduced in the Setting options section.
- set history=200 increase default history from 50 to 200
- as mentioned in the Command-line mode chapter, there are separate history lists for
:commands, search patterns, etc
- as mentioned in the Command-line mode chapter, there are separate history lists for
- set nobackup disable backup files
- set noswapfile disable swap files
- colorscheme murphy a dark theme
- you can use :colorscheme followed by a space and then press Tab or Ctrl+d to get a list of the available color schemes
- set showcmd Command-line area will show partial Normal mode commands and character/line/block-selection for Visual mode
- set wildmode=longest,list,full use
bash-like tab completion- first tab will complete as much as possible
- second tab will provide a list
- third and subsequent tabs will cycle through the completion options
:h 'history' will give you the documentation for the given option (note the use of single quotes).
You can use these settings from the Command-line mode as well, but will be active for the current Vim session only. Settings specified in the
vimrcfile will be loaded automatically at startup. You can also load a different file as thevimrc, which will be discussed in the CLI options chapter.
Further Reading
- stackoverflow: Vim backup files
- stackoverflow: Disabling swap files
- stackoverflow: How to set persistent Undo
Text and Indent Settings
- filetype plugin indent on enables loading of
pluginandindentfiles- these files become active based on the type of the file to influence syntax highlighting, indentation, etc
- :echo $VIMRUNTIME gives your installation directory (
indentandplugindirectories would be present in this path) - see :h vimrc-filetype, :h :filetype-overview and :h filetype.txt for more details
- set autoindent copy indent from the current line when starting a new line
- useful for files not affected by the
indentsetting - see also :h smartindent
- useful for files not affected by the
- set textwidth=80 guideline for Vim to automatically move to a new line with
80characters as the limit- white space is used to break lines, so a line can still be greater than the limit if there's no white space
- default is
0which disables this setting
- set colorcolumn=80 create a highlighted vertical bar at column number
80- use
highlight ColorColumnsetting to customize the color for this vertical bar - see vi.stackexchange: Keeping lines to less than 80 characters for more details
- use
- set shiftwidth=4 number of spaces to use for indentation (default is
8) - set tabstop=4 width for the tab character (default is
8) - set expandtab use spaces for tab expansion
- set cursorline highlight the line containing the cursor
Search Settings
- set hlsearch highlight all matching portions
- using :noh (short for :nohlsearch) will clear the currently highlighted portions
- set incsearch highlights current match as you type the pattern, the screen is updated automatically as needed
- pressing the Enter key would move the cursor to the matched portion
- pressing the Esc key would keep the cursor at the current location
- other matching terms will be highlighted based on the
hlsearchsetting
Custom mapping
Mapping helps you to create new commands or redefine existing ones. You can restrict such mappings for specific modes as well. Only the following settings will be discussed in this chapter:
nnoremapNormal mode non-nested, non-recursive mappingxnoremapVisual mode non-nested, non-recursive mappinginoremapInsert mode non-nested, non-recursive mappinginoreabbrevInsert mode non-nested, non-recursive abbreviation
The following will not be discussed, but you might find it useful to know or explore further:
nmap,xmap,imapandiabbrevallows nested and recursive mappingsnunmap,xunmap,iunmapandiunabbrevunmaps the given command (usually used from Command-line mode to temporarily disable a mapping, will be available again on startup if it was defined invimrc)- use
mapclearinstead ofunmapto clear all the mappings for that particular mode
- use
onoremap(oromap) map a motion or text object to be used with commands likedorycommandhelps you create a Command-line mode command, see :h 40.2 and :h user-commands for details
:nmap, :xmap, :imap and :iab will list all the current mappings for that particular mode. You can provide an argument to display the mapping for that particular command, for example :nmap Y. See :h key-mapping and :h map-overview for reference manuals.
Normal mode
- nnoremap <F2> :w<CR> press F2 function key to save changes
<F2>represents the F2 function key and<CR>represents the Enter key- I chose F2 since it is close to the Esc key (F1 opens help page)
- nnoremap <F3> :wq<CR> press F3 to save changes and quit
- nnoremap <F4> ggdG press F4 to delete everything
- nnoremap <F5> :%y+<CR> press F5 to copy everything to the system clipboard
- nnoremap <left> <nop> do nothing when the ← arrow key is pressed
- likewise, you can map the other arrow keys to do nothing
- nnoremap Y y$ change Y to behave similarly to D and C
- nnoremap / /\v add very magic mode modifier for forward direction search
- nnoremap ? ?\v add very magic mode modifier for backward direction search
- nnoremap <silent> <Space> :noh<CR><Space> press Space key to clear the currently highlighted portions
<silent>modifier executes the command without displaying in the Command-line area- Note that this mapping also retains the default behavior of the Space key
- nnoremap <A-1> 1gt press Alt+1 to switch to the first tab
- I prefer this to make switching tabs consistent with browser and terminal shortcuts
- nnoremap <A-2> 2gt press Alt+2 to switch to the second tab and so on
See :h map-which-keys to know which keys are not already Vim commands, which ones are not commonly used, etc.
See :h key-notation for a list of keys that can be represented using the
<>notation.
Map leader
Normal mode commands are already crowded, so if you are looking to create new commands, using a leader mapping can help you out. You can define a key that'll serve as a prefix for these new set of commands. By default, the backslash key is used as the leader key.
- nnoremap <Leader>f gg=G if
mapleaderhasn't been set, using\fwill auto indent the code for the whole file - let mapleader = ";" change the leader key to
;- nnoremap <Leader>f gg=G this will now require
;fsince the leader key was changed
- nnoremap <Leader>f gg=G this will now require
See learnvimscriptthehardway: Leaders for more examples and details.
Insert mode
- inoremap <F2> <C-o>:w<CR> press F2 to save changes in Insert mode as well
- Ctrl+o is used here to execute a command and return back to Insert mode automatically
- imap <F2> <C-o><F2> can also be used if you've already defined the Normal mode mapping
- inoremap <C-f> <Esc>ea press Ctrl+f to move to the end of the word
- I'd prefer Ctrl+e but that is useful to cancel autocompletion
- inoremap <C-b> <C-Left> press Ctrl+b to move to the beginning of the word
- inoremap <C-a> <End> press Ctrl+a to move to the end of the line
- inoremap <C-s> <Home> press Ctrl+s to move to the start of the line
- inoremap <C-v> <C-o>"+p press Ctrl+v to paste from the clipboard
- If you need Ctrl+v functionality, the Ctrl+q alias can be used to insert characters like Enter key (but this alias may not work in some terminals)
- inoremap <C-l> <C-x><C-l> press Ctrl+l to autocomplete matching lines
- See :h i_CTRL-x and :h ins-completion for all the features offered by Ctrl+x
Use noremap! if you want a mapping to work in both Insert and Command-line modes.
Visual mode
- xnoremap * y/<C-R>"<CR> press * to search the visually selected text in the forward direction
- recall that Ctrl+r helps you insert register contents in Command-line mode
- xnoremap # y?<C-R>"<CR> press # to search the visually selected text in the backward direction
Note that
xnoremapis used here sincevnoremapaffects both Visual and Select modes.
Abbreviations
Abbreviations are usually used to correct typos and insert frequently used text. From :h abbreviations documentation:
An abbreviation is only recognized when you type a non-keyword character. This can also be the
<Esc>that ends insert mode or the<CR>that ends a command. The non-keyword character which ends the abbreviation is inserted after the expanded abbreviation. An exception to this is the character<C-]>, which is used to expand an abbreviation without inserting any extra characters.
inoreabbrev p #!/usr/bin/env perl<CR>use strict;<CR>use warnings;<CR> expand
pto the text as shown in the code snippet below- you can trigger the abbreviation completion using non-keyword characters such as Esc, Space and Enter keys, punctuation characters and so on
- use Ctrl+] to expand the abbreviation without adding anything extra
#!/usr/bin/env perl use strict; use warnings;inoreabbrev py #!/usr/bin/env python3 expand
pyto#!/usr/bin/env python3- this might cause issues if you need
pyliterally (for example,script.py) - you can use something like
[por@pinstead
- this might cause issues if you need
inoreabbrev teh the automatically correct
tehtypo totheinoreabbrev @a always @()<CR>begin<CR>end<Esc>2k$ expand
@ato the text as shown in the code snippet below- this one works best when you type
@afollowed by the Esc key to place the cursor at the end of the first line
always @() begin end- this one works best when you type
:abbreviate or :ab list all abbreviations
See :h 24.7 for more details about using abbreviations.
Matching Pairs
- set matchpairs+=<:> add
<>to the list of pairs matched by the % command in Normal mode
To match keywords like
if-elsepairs with %, you can use thematchit.vimplugin. This supports filetypes such as HTML, Vim, LaTeX, XML, etc. See :h matchit-install for more details.
GUI options
- set guioptions-=m remove menu bar
- set guioptions-=T remove tool bar
See :h guioptions for more details.
Third-party customizations
![]()
See :h 'runtimepath' to know the path within which you can add the plugins and packages discussed in this section.
~/.vimis commonly used on Unix/Linux systems.
Make sure to backup your directory (~/.vim for example) and the vimrc file, so that you can easily apply your customizations on a new machine.
plugin
Some plugins are loaded by default. Some come with Vim installation but you have to explicitly enable them. You can also write your own or add plugins written by others. From :h add-plugin:
Vim's functionality can be extended by adding plugins. A plugin is nothing more than a Vim script file that is loaded automatically when Vim starts.
There are two types of plugins:
global plugin: Used for all kinds of files
filetype plugin: Only used for a specific type of file
If you want to add a global plugin created by you or someone else, place it in the plugin directory. If you don't have that directory yet, you can create it using the below command (assuming Unix/Linux):
$ mkdir -p ~/.vim/plugin
$ cp plugin_file.vim ~/.vim/plugin/
If you have multiple related plugin files, you can put them under a subdirectory:
$ mkdir -p ~/.vim/plugin/python
$ cp file_1.vim file_2.vim ~/.vim/plugin/python/
If you want to add plugins that should work based on a specific filetype, add them to the ftplugin directory:
$ mkdir -p ~/.vim/ftplugin
$ cp ftplugin_file.vim ~/.vim/ftplugin/
package
Packages make it easy to manage projects that require multiple plugins, use a version controlled repository directly and so on. See :h packages for more details. From :h add-package:
A package is a set of files that you can add to Vim. There are two kinds of packages: optional and automatically loaded on startup.
The Vim distribution comes with a few packages that you can optionally use. For example, the matchit plugin.
- packadd! matchit enable
matchitpackage- this plugin comes with Vim, see :h matchit for further details
!is used to prevent loading this plugin when Vim is started with the--nopluginCLI option
vim-surround is used here as an example for a third-party package. Installation instructions (provided in this repository) are shown below, assuming you want to enable this package at startup:
# 'pack' is the directory for packages
# 'tpope' subdirectory is useful to group all packages by this author
# 'start' means this package will be loaded at startup
$ mkdir -p ~/.vim/pack/tpope/start
# go to the directory and clone the git repository
# you can then update the repository when new changes are needed
$ cd ~/.vim/pack/tpope/start
$ git clone https://github.com/tpope/vim-surround.git
When you start Vim after the above steps, vim-surround will be automatically active. Couple of examples are shown below, see the repository linked above for more details.
- ysiw] will surround a word with
[], for examplehelloto[hello] - cs"' will change text surrounded by double quotes to single quotes, for example
"hi bye"to'hi bye'
If you want to enable this package optionally, put it under opt directory instead of start.
# 'opt' makes it optional
$ mkdir -p ~/.vim/pack/tpope/opt
$ cd ~/.vim/pack/tpope/opt
$ git clone https://github.com/tpope/vim-surround.git
- :packadd vim-surround enable this package from Command-line mode
- packadd! vim-surround enable this package in
vimrc(usually under some condition)
color scheme
There are different ways to add a new color scheme. The simplest is to copy the theme.vim file to the ~/.vim/colors directory. Or, follow the installation steps provided by the theme creators. Here are couple of solarized themes you can check out:
After installation, you can use the :colorscheme command to set the new theme. If the theme offers multiple variations, you might need additional settings like set background=dark or set background=light. See the installation instructions provided in the above repositories for more details.
See Where to put what section under :h packages for more details about installation directories.
See also this collection of awesome color schemes for Vim.
autocmd
From :h 40.3:
An autocommand is a command that is executed automatically in response to some event, such as a file being read or written or a buffer change.
Autocommands are very powerful. Use them with care and they will help you avoid typing many commands. Use them carelessly and they will cause a lot of trouble.
Syntax from the reference manual is shown below:
:au[tocmd] [group] {event} {aupat} [++once] [++nested] {cmd}
Here's an example for Python files:
augroup pyg
autocmd!
" add Python shebang for a new buffer with .py extension
" py abbreviation was discussed earlier in this chapter
autocmd BufNewFile *.py normal ipy
" Black command is provided by a Python code formatter plugin
autocmd BufWritePre *.py Black
augroup END
autocmd BufNewFile *.py normal ipyBufNewFileevent that triggers on editing a file that doesn't already exist*.pyfilenames ending with.py(similar to shell wildcards)normal ipycommand to be executed (normalis needed here since by default commands are treated as Command-line mode)
autocmd BufWritePre *.py BlackBufWritePreevent that triggers on writing a fileBlackcommand to be executed (see black vim plugin documentation for more details)
augrouphelps you to group related autocommands- autocmd! removes all autocommands within a group (
pygin the above example)- useful to avoid autocommands getting defined again when you source the
vimrcfile
- useful to avoid autocommands getting defined again when you source the
- :autocmd list all autocommands, you can provide arguments to narrow down this listing
![]()
Note that in earlier versions of Vim, double quotes is used for comments as shown in the above snippet. You'll need to use the
#character instead forvim9script. See vim9-conversion-aid for upgrading old scripts.
See also:
- :h 40.3 for user manual, :h :autocmd and :h autocmd-groups for reference manuals
- :h autocmd-events for a list of events
- learnvimscriptthehardway: autocmd tutorial
- learnvimscriptthehardway: augroup tutorial
Further Reading
- Learn Vimscript the Hard Way — book on Vimscript and customizing Vim (written for
version 7.3) - Vimscript cheatsheet
- Vim Awesome — a directory of Vim plugins
vimrcreference, tips and generation- vi.stackexchange: Open filename under cursor in a new tab (or split)
- stackoverflow: Open filename under cursor based on current filetype
- stackoverflow: Information regarding Vim history
- stackoverflow: Indenting all the files in a folder