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
vimrc
file, you can use this predefined variable to open it - :h vimrc to find out where the
vimrc
file should be located for your OS - :source $MYVIMRC apply changes from within your current Vim session
To view a sample
vimrc
file, 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
vimrc
file 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
set
syntax 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
vimrc
file 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
plugin
andindent
files- these files become active based on the type of the file to influence syntax highlighting, indentation, etc
- :echo $VIMRUNTIME gives your installation directory (
indent
andplugin
directories 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
indent
setting - 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
80
characters 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
0
which disables this setting
- set colorcolumn=80 create a highlighted vertical bar at column number
80
- use
highlight ColorColumn
setting 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
hlsearch
setting
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:
nnoremap
Normal mode non-nested, non-recursive mappingxnoremap
Visual mode non-nested, non-recursive mappinginoremap
Insert mode non-nested, non-recursive mappinginoreabbrev
Insert 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
,imap
andiabbrev
allows nested and recursive mappingsnunmap
,xunmap
,iunmap
andiunabbrev
unmaps 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
mapclear
instead ofunmap
to clear all the mappings for that particular mode
- use
onoremap
(oromap
) map a motion or text object to be used with commands liked
ory
command
helps 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
mapleader
hasn't been set, using\f
will auto indent the code for the whole file - let mapleader = ";" change the leader key to
;
- nnoremap <Leader>f gg=G this will now require
;f
since 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
xnoremap
is used here sincevnoremap
affects 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
p
to 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
py
to#!/usr/bin/env python3
- this might cause issues if you need
py
literally (for example,script.py
) - you can use something like
[p
or@p
instead
- this might cause issues if you need
inoreabbrev teh the automatically correct
teh
typo tothe
inoreabbrev @a always @()<CR>begin<CR>end<Esc>2k$ expand
@a
to the text as shown in the code snippet below- this one works best when you type
@a
followed 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
-else
pairs with %, you can use thematchit.vim
plugin. 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.
~/.vim
is 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
matchit
package- this plugin comes with Vim, see :h matchit for further details
!
is used to prevent loading this plugin when Vim is started with the--noplugin
CLI 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 examplehello
to[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 ipy
BufNewFile
event that triggers on editing a file that doesn't already exist*.py
filenames ending with.py
(similar to shell wildcards)normal ipy
command to be executed (normal
is needed here since by default commands are treated as Command-line mode)
autocmd BufWritePre *.py Black
BufWritePre
event that triggers on writing a fileBlack
command to be executed (see black vim plugin documentation for more details)
augroup
helps you to group related autocommands- autocmd! removes all autocommands within a group (
pyg
in the above example)- useful to avoid autocommands getting defined again when you source the
vimrc
file
- 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
vimrc
reference, 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