My Vim Config

There are a huge amount of options in Vim. It enables us to customize our own Vim as our wishes. Here's my config.

TL;DR

If you don't want to see the full configuration process and just want to use my configuration:

Firstly, install vim-plug:

1
2
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

Then, edit ~/.vimrc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
" Basic options based on https://missing.csail.mit.edu/2020/editors/
nmap Q <Nop> " 'Q' in normal mode enters Ex mode. You almost never want this.
set backspace=indent,eol,start
set hidden
set ignorecase
set incsearch
set laststatus=2
set mouse+=a
set nocompatible
set noerrorbells visualbell t_vb=
set number
set relativenumber
set shortmess+=I
set smartcase
syntax on

" Plugin options
filetype plugin on
" vim-plug
call plug#begin()
Plug 'bkad/CamelCaseMotion'
Plug 'ctrlpvim/ctrlp.vim'
Plug 'dense-analysis/ale'
Plug 'dracula/vim', { 'as': 'dracula' }
Plug 'easymotion/vim-easymotion'
Plug 'itchyny/lightline.vim'
Plug 'jiangmiao/auto-pairs'
Plug 'mileszs/ack.vim'
Plug 'nelstrom/vim-visual-star-search'
Plug 'preservim/nerdtree'
Plug 'preservim/vim-indent-guides'
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-sensible'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-unimpaired'
Plug 'ycm-core/YouCompleteMe', { 'do': './install.py --clangd-completer' }
call plug#end()

" lightline.vim
set noshowmode
if !has('gui_running')
set t_Co=256
endif
let g:lightline = { 'colorscheme': 'wombat' }

" nerdtree
nnoremap <C-S-E> :NERDTree<CR>
" Start NERDTree when Vim is started without file arguments.
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists('s:std_in') | NERDTree | endif
" Exit Vim if NERDTree is the only window remaining in the only tab.
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif

" vim-indent-guides
set ts=2 sw=2 et
let g:indent_guides_start_level=2
let g:indent_guides_enable_on_vim_startup = 1

" ycm
" Let clangd fully control code completion
let g:ycm_clangd_uses_ycmd_caching = 0
" Use installed clangd, not YCM-bundled clangd which doesn't get updates
let g:ycm_clangd_binary_path = exepath("clangd")

" Set color scheme.
colorscheme dracula

" Let vim automatically infer indents based on context
set smartindent

" Mapping configurations
let mapleader = " " " leader is space
" Map jk to <ESC>
imap jk <ESC>
" Move vertically by visual line
nmap j gj
nmap k gk
vmap j gj
vmap k gk
" Handle windows quicker
nnoremap <leader>\| :vsp<CR>
nnoremap <leader>- :sp<CR>
map <C-h> <C-w>h
map <C-j> <C-w>j
map <C-k> <C-w>k
map <C-l> <C-w>l

Finally, start vim and run :PlugInstall to install all the plugins using vim-plug. See the basic usage of these plugins here.

Brief

To see the complete option list, run:

1
:help option-list

To change an option only for this time, run:

1
:set <option>

Add an ! at the tail to reverse the option:

1
:set <option>!

To see the current status of an option, add a ?:

1
:set <option>?

If you want to save your options, edit ~/.vimrc.

Getting Started

Here is an example .vimrc provided by MIT:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
" Comments in Vimscript start with a `"`.

" If you open this file in Vim, it'll be syntax highlighted for you.

" Vim is based on Vi. Setting `nocompatible` switches from the default
" Vi-compatibility mode and enables useful Vim functionality. This
" configuration option turns out not to be necessary for the file named
" '~/.vimrc', because Vim automatically enters nocompatible mode if that file
" is present. But we're including it here just in case this config file is
" loaded some other way (e.g. saved as `foo`, and then Vim started with
" `vim -u foo`).
set nocompatible

" Turn on syntax highlighting.
syntax on

" Disable the default Vim startup message.
set shortmess+=I

" Show line numbers.
set number

" This enables relative line numbering mode. With both number and
" relativenumber enabled, the current line shows the true line number, while
" all other lines (above and below) are numbered relative to the current line.
" This is useful because you can tell, at a glance, what count is needed to
" jump up or down to a particular line, by {count}k to go up or {count}j to go
" down.
set relativenumber

" Always show the status line at the bottom, even if you only have one window open.
set laststatus=2

" The backspace key has slightly unintuitive behavior by default. For example,
" by default, you can't backspace before the insertion point set with 'i'.
" This configuration makes backspace behave more reasonably, in that you can
" backspace over anything.
set backspace=indent,eol,start

" By default, Vim doesn't let you hide a buffer (i.e. have a buffer that isn't
" shown in any window) that has unsaved changes. This is to prevent you from "
" forgetting about unsaved changes and then quitting e.g. via `:qa!`. We find
" hidden buffers helpful enough to disable this protection. See `:help hidden`
" for more information on this.
set hidden

" This setting makes search case-insensitive when all characters in the string
" being searched are lowercase. However, the search becomes case-sensitive if
" it contains any capital letters. This makes searching more convenient.
set ignorecase
set smartcase

" Enable searching as you type, rather than waiting till you press enter.
set incsearch

" Unbind some useless/annoying default key bindings.
nmap Q <Nop> " 'Q' in normal mode enters Ex mode. You almost never want this.

" Disable audible bell because it's annoying.
set noerrorbells visualbell t_vb=

" Enable mouse support. You should avoid relying on this too much, but it can
" sometimes be convenient.
set mouse+=a

" Try to prevent bad habits like using the arrow keys for movement. This is
" not the only possible bad habit. For example, holding down the h/j/k/l keys
" for movement, rather than using more efficient movement commands, is also a
" bad habit. The former is enforceable through a .vimrc, while we don't know
" how to prevent the latter.
" Do this in normal mode...
nnoremap <Left> :echoe "Use h"<CR>
nnoremap <Right> :echoe "Use l"<CR>
nnoremap <Up> :echoe "Use k"<CR>
nnoremap <Down> :echoe "Use j"<CR>
" ...and in insert mode
inoremap <Left> <ESC>:echoe "Use h"<CR>
inoremap <Right> <ESC>:echoe "Use l"<CR>
inoremap <Up> <ESC>:echoe "Use k"<CR>
inoremap <Down> <ESC>:echoe "Use j"<CR>

Learn more on Editors (Vim) · Missing Semester (mit.edu).

My Options

I use vim-plug as my vim plugin manager. If you also want to use it, run:

1
2
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

Learn more on junegunn/vim-plug: Minimalist Vim Plugin Manager.

Then you can use my .vimrc. Attention that it is based on the MIT basic version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
" Plugin options
filetype plugin on
" vim-plug
call plug#begin()
Plug 'bkad/CamelCaseMotion'
Plug 'ctrlpvim/ctrlp.vim'
Plug 'dense-analysis/ale'
Plug 'dracula/vim', { 'as': 'dracula' }
Plug 'easymotion/vim-easymotion'
Plug 'itchyny/lightline.vim'
Plug 'jiangmiao/auto-pairs'
Plug 'mileszs/ack.vim'
Plug 'nelstrom/vim-visual-star-search'
Plug 'preservim/nerdtree'
Plug 'preservim/vim-indent-guides'
Plug 'tpope/vim-commentary'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-sensible'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-unimpaired'
Plug 'ycm-core/YouCompleteMe', { 'do': './install.py --clangd-completer' }
call plug#end()

" lightline.vim
set noshowmode
if !has('gui_running')
set t_Co=256
endif
let g:lightline = { 'colorscheme': 'wombat' }

" nerdtree
nnoremap <C-S-E> :NERDTree<CR>
" Start NERDTree when Vim is started without file arguments.
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists('s:std_in') | NERDTree | endif
" Exit Vim if NERDTree is the only window remaining in the only tab.
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif

" vim-indent-guides
set ts=2 sw=2 et
let g:indent_guides_start_level=2
let g:indent_guides_enable_on_vim_startup = 1

" ycm
" Let clangd fully control code completion
let g:ycm_clangd_uses_ycmd_caching = 0
" Use installed clangd, not YCM-bundled clangd which doesn't get updates
let g:ycm_clangd_binary_path = exepath("clangd")

" Set color scheme.
colorscheme dracula

" Let vim automatically infer indents based on context
set smartindent

" Mapping configurations
" leader is space
let mapleader = " "

" Insert mode, no recursively
" Map jk to <ESC>.
inoremap jk <ESC>

" Normal mode, no recursively
" Move vertically by visual line.
nnoremap j gj
nnoremap k gk

" Handle windows quicker
nnoremap <leader>\| :vsp<CR> " don't forget the escape character
nnoremap <leader>- :sp<CR>
map <C-h> <C-w>h
map <C-j> <C-w>j
map <C-k> <C-w>k
map <C-l> <C-w>l

To use vim-plug to install the plugins, run:

1
:PlugInstall

Note that I install YouCompleteMe with clangd support (Learn more here). I met an issue here. See Q&A.

Basic Usage of Plugins

Plugin Basic Usage Link
ack.vim Search text in the project using :Ack command GitHub
ale Perform syntax checks while editing code with configured tools GitHub
auto-pairs Automatically insert closing brackets for opening brackets GitHub
CamelCaseMotion Press <leader> followed by a motion command to move to the next/previous CamelCase word GitHub
ctrlp.vim Open CtrlP window with :CtrlP or <C-p>, then search and open files GitHub
lightline.vim Customize appearance and content of the statusline GitHub
nerdtree Open NERDTree window with :NERDTree, navigate with hjkl keys GitHub
vim-commentary Comment/uncomment lines with gc or gC commands GitHub
vim-dracula Switch to Dracula theme with :colorscheme dracula GitHub
vim-easymotion Trigger EasyMotion with <Leader> <Leader> and enter characters to jump GitHub
vim-fugitive View file status with :G status, commit changes with :G commit and so forth GitHub
vim-indent-guides Visually display indent levels in Vim GitHub
vim-sensible Configure Vim with sensible defaults for a pleasant editing experience GitHub
vim-surround Change surrounding characters with cst, delete surroundings with dst, and more GitHub
vim-unimpaired Provides various useful mappings for manipulating vertical whitespace and more GitHub
vim-visual-star-search Search for the visually selected text with * and # commands GitHub
YouCompleteMe A code-completion engine for Vim GitHub

Vim Mode in Other Editors

Vim in Code

In VS Code, I use vscodevim and configure it in settings.json like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"vim.camelCaseMotion.enable": true,
"vim.easymotion": true,
"vim.history": 200,
"vim.hlsearch": true,
"vim.incsearch": true,
"vim.insertModeKeyBindings": [{ "after": ["<esc>"], "before": ["j", "k"] }],
"vim.ignorecase": true,
"vim.smartcase": true,
"vim.leader": " ",
"vim.normalModeKeyBindings": [
{ "after": ["g", "j"], "before": ["j"] },
{ "after": ["g", "k"], "before": ["k"] },
{ "before": ["<leader>", "-"], "commands": [":sp"] },
{ "before": ["<leader>", "|"], "commands": [":vsp"] }
],
"vim.useCtrlKeys": true,
"vim.useSystemClipboard": true,
"vim.visualstar": true,
"vim.visualModeKeyBindings": [
{ "after": ["g", "j"], "before": ["j"] },
{ "after": ["g", "k"], "before": ["k"] }
]
}

If you want to auto switch input method, the configuration should be:

1
2
3
4
"vim.autoSwitchInputMethod.enable": true,
"vim.autoSwitchInputMethod.defaultIM": "com.apple.keylayout.US",
"vim.autoSwitchInputMethod.obtainIMCmd": "/usr/local/bin/im-select",
"vim.autoSwitchInputMethod.switchIMCmd": "/usr/local/bin/im-select {im}"

Learn more here.

And in keybindings.json like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[
{
"key": "ctrl+h",
"command": "workbench.action.navigateLeft"
},
{
"key": "ctrl+j",
"command": "workbench.action.navigateDown"
},
{
"key": "ctrl+k",
"command": "workbench.action.navigateUp"
},
{
"key": "ctrl+l",
"command": "workbench.action.navigateRight"
}
]

Vim in JetBrains IDEs

In JetBrains IDEs, I use IdeaVim and configure it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
" .ideavimrc
"" Source your .vimrc
source ~/.vimrc

"" -- Map IDE actions to IdeaVim -- https://jb.gg/abva4t
"" Map \r to the start run
map \r <Action>(Run)

"" Map \d to start debug
map \d <Action>(Debug)

"" Map \b to toggle the breakpoint on the current line
map \b <Action>(ToggleLineBreakpoint)

The default file tree hotkey is Alt + 1. I add Ctrl + Shift + E.

Q&A

ImportError when I try to install ycm

1
The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). Unexpected error while loading the YCM core library. Type ':YcmToggleLogs <...>.log' to check the logs.

Log:

1
ImportError: /home/<...>/miniconda3/lib/libstdc++.so.6: version `GLIBCXX_3.4.30` not found (required by /home/<...>/.vim/plugged/YouCompleteMe/third_party/ycmd/ycm_core.cpython-311-x86_64-linux-gnu.so)

This is an issue caused by conda. You should run install.py using the system python, not the conda one. Learn more here.

Reference