Vim is short for vi improved — translated, an upgraded version of the vi editor. This article covers Vim from the following angles:

  • Installing Vim
  • Basic usage → doing the most basic editing in Vim (surviving inside Vim)
  • Third-party plugins

This article introduces Vim without going into every technical detail, hoping to help you quickly remember a few things, then form muscle memory through repeated practice, and improve your efficiency. This article’s goal is not to research Vim’s technical internals or clever tricks for writing Vimscript.

1. Installing Vim

Installing via a package manager is quick and convenient, but if you want to add certain features, you’ll need to build it from source instead.

1.1 Using a package manager

CentOS/Rocky Linux/Red Hat

sudo dnf install vim

Ubuntu/Debian

sudo apt install vim

1.2 Installing from source

git clone https://github.com/vim/vim.git
cd vim
./configure --with-features=huge --enable-python3interp=yes --prefix=/usr/local --with-python3-config-dir=/usr/lib64/python3.9/config-3.9-x86_64-linux-gnu
make -j8
sudo make install

If you make any changes along the way, clean up the intermediate build results before rebuilding:

make clean distclean
make clean

Once installed, run vim --version

Output of vim --version
vim --version
    VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Nov 28 2022 00:00:00)
    Included patches: 1-963
    Modified by <[email protected]m>
    Compiled by <[email protected]m>
    Huge version without GUI.  Features included (+) or not (-):
    +acl               +file_in_path      +mouse_urxvt       -tag_any_white
    +arabic            +find_in_path      +mouse_xterm       -tcl
    +autocmd           +float             +multi_byte        +termguicolors
    +autochdir         +folding           +multi_lang        +terminal
    -autoservername    -footer            -mzscheme          +terminfo
    -balloon_eval      +fork()            +netbeans_intg     +termresponse
    +balloon_eval_term +gettext           +num64             +textobjects
    -browse            -hangul_input      +packages          +textprop
    ++builtin_terms    +iconv             +path_extra        +timers
    +byte_offset       +insert_expand     +perl/dyn          +title
    +channel           +ipv6              +persistent_undo   -toolbar
    +cindent           +job               +popupwin          +user_commands
    -clientserver      +jumplist          +postscript        +vartabs
    -clipboard         +keymap            +printer           +vertsplit
    +cmdline_compl     +lambda            +profile           +vim9script
    +cmdline_hist      +langmap           -python            +viminfo
    +cmdline_info      +libcall           +python3/dyn       +virtualedit
    +comments          +linebreak         +quickfix          +visual
    +conceal           +lispindent        +reltime           +visualextra
    +cryptv            +listcmds          +rightleft         +vreplace
    +cscope            +localmap          +ruby/dyn          +wildignore
    +cursorbind        +lua/dyn           +scrollbind        +wildmenu
    +cursorshape       +menu              +signs             +windows
    +dialog_con        +mksession         +smartindent       +writebackup
    +diff              +modify_fname      +sodium            -X11
    +digraphs          +mouse             -sound             -xfontset
    -dnd               -mouseshape        +spell             -xim
    -ebcdic            +mouse_dec         +startuptime       -xpm
    +emacs_tags        +mouse_gpm         +statusline        -xsmp
    +eval              -mouse_jsbterm     -sun_workshop      -xterm_clipboard
    +ex_extra          +mouse_netterm     +syntax            -xterm_save
    +extra_search      +mouse_sgr         +tag_binary
    -farsi             -mouse_sysmouse    -tag_old_static
    system vimrc file: "/etc/vimrc"
        user vimrc file: "$HOME/.vimrc"
    2nd user vimrc file: "~/.vim/vimrc"
        user exrc file: "$HOME/.exrc"
        defaults file: "$VIMRUNTIME/defaults.vim"
    fall-back for $VIM: "/usr/share/vim"
    Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -DSYS_VIMRC_FILE=/etc/vimrc -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
    Linking: gcc -Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -specs=/usr/lib/rpm/redhat/redhat-package-notes -L/usr/local/lib -o vim -lm -lselinux -lncurses -lsodium -lacl -lattr -lgpm -Wl,--enable-new-dtags -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -Wl,--build-id=sha1 -fstack-protector-strong -L/usr/local/lib -L/usr/lib64/perl5/CORE -lperl -lpthread -lresolv -ldl -lm -lcrypt -lutil -lc

You can inspect the details of how Vim was compiled.

2. Basic Usage → Surviving in Vim

On a Linux server, you sometimes have no choice but to face a pitch-black command line. With no extra configuration, being able to start using Vim becomes an essential skill.

There’s a well-known joke about Vim: the most-viewed question on Stack Overflow is how to quit Vim.

2.1 Surviving in Vim

Intuitively, the most important functions of an editor are:

  • Opening/closing a file
  • Adding/deleting/modifying characters
  • Saving or discarding changes
vim path

Here, path can be a file or a directory, giving different results:

  • File → Vim’s normal interface
  • Directory → select a file with the up/down arrow keys (++”↑”++ ++”↓”++), confirm which file to edit with ++“Enter”++

Press the ++“i”++ key on the keyboard to enter INSERT mode, at which point Vim behaves like an ordinary editor.

  • Use the up (++”↑”++), down (++”↓”++), left (++”←”++), right (++”→”++) arrow keys, or ++“h”++ ++“k”++ ++“l”++ ++“j”++, to move the cursor
  • Use ++“PageUp”++ and ++“PageDown”++ to move between lines
  • Use ++“BackSpace”++ to delete the content of the previous line

Once you’ve finished editing, press ++“ESC”++ to exit insert mode, then press ++”:”++ ++“w”++ ++“q”++ to save and close the file (++“w”++ for write and ++“q”++ for quit).

At this point, you’ve already learned Vim — go ahead and use it to boost your productivity.

3. Using Vim Better

Surviving is obviously not the final goal, since some functions taken for granted in other editors haven’t been covered yet. And Vim certainly doesn’t lack these functions:

  • Selecting
  • Copying
  • Pasting
  • Replacing
  • Selecting multiple objects

If you only use Vim’s basic functions, it’s like operating the keyboard with only one hand. To use Vim better, you need to dig a bit deeper into:

  • Basic operation syntax
  • Vim’s three modes
  • Cursor movement
  • Visual mode

3.1 Basic syntax

Vim has several modes, such as:

  • Normal mode
  • Insert mode
  • Visual mode
  • Command-line mode

Why does an editor need so many modes? All in service of better editing.

Normal mode

Normal mode treats Vim as a read-only viewer, used for browsing the whole file. Opening a file with Vim starts in this mode by default. This mode doesn’t involve modifying content, so it has more shortcut keys available.

Insert mode

Insert mode is where actual editing of the file happens. From normal mode, holding ++“i”++ switches to insert mode. From there, pressing keys just modifies the file being edited.

Visual mode

Visual mode is for selecting a block of text to operate on, entered by pressing ++“v”++ (or ++“V”++ for line-wise, or Ctrl-V for block-wise) from normal mode.

Command-line mode

Command-line mode is for typing commands in Vim to carry out related functions. When Vim is in normal mode, typing ++”:”++ enters command-line mode, used for command-related operations, as well as running shell commands from within Vim.

3.2 Cursor movement

Moving the Vim cursor via keyboard keys (rather than moving the mouse) is one reason Vim is efficient.

Single-character movement

The up (++”↑”++), down (++”↓”++), left (++”←”++), right (++”→”++) arrow keys, or ++“h”++ ++“k”++ ++“l”++ ++“j”++, move the cursor character by character.

What’s with ++“h”++ ++“k”++ ++“l”++ ++“j”++? They’re simply the keys the right hand rests on most naturally on the keyboard — not every keyboard has explicit arrow keys, and using arrow keys might require holding down an extra key, like ++“shift”++. So the most comfortable right-hand keys, ++“h”++ ++“k”++ ++“l”++ ++“j”++, were chosen instead.

Word movement

  • ++“w”++ moves right by one word (word)
  • ++“b”++ moves left by one word (back)

Paging

  • ++“PageUp”++ → page up
  • ++ctrl++ + ++“f”++ → page forward
  • ++“PageDown”++ → page down
  • ++ctrl++ + ++“b”++ → page back

Line scrolling

  • ++ctrl++ + ++“e”++ → scroll the whole view up by one line
  • ++ctrl++ + ++“y”++ → scroll the whole view down by one line

Adjusting line position

  • ++“z”++ ++“t”++ places the cursor’s line at the top — t for top
  • ++“z”++ ++“z”++ places the cursor’s line in the middle — z is probably just convenient
  • ++“z”++ ++“b”++ places the cursor’s line at the bottom — b for bottom

3.3 Deleting lines

  • ++“d”++ ++“d”++: cuts the current line
  • ++“p”++: pastes below the cursor

4. Configuring Vim

The main goal here is to improve your proficiency. Like most tools, Vim supports two ways to configure it:

  • Using configuration commands
  • Using a configuration file

Running vim --version shows you where the configuration file lives — for example, the output shows ~/.vimrc has the highest priority among config files. Naturally, its priority is still lower than a configuration command. This also matches typical usage habits: use a command for a temporary tweak, and use the config file for a permanent change. My ~/.vimrc looks like this:

set encoding=utf-8
set number # turn off via: set nonumber
syntax on
set autoindent
set tabstop=4
set expandtab
set wrap
set linebreak
set showmatch
set ruler
set background=dark
colorscheme iceberg
set list
set listchars=tab:>-

Every line above can also be run with ++”:”++ + the command — for example, : set number turns on line numbers, and : set nonumber turns them off.

5. Third-Party Vim Plugins

5.1 The native package manager

Vim’s strength lies in its rich plugin ecosystem. Before Vim 8, there was no official, formal implementation for third-party Vim plugins. Starting with Vim 8, Vim ships with its own built-in package manager. See here for more information.

The native package-management approach is to place an entire package’s folder into one of these fixed directories:

  • ~/.vim/pack/xxx/start/yyy
  • ~/.vim/pack/xxx/opt/yyy

Packages placed in the start folder are loaded automatically, while packages placed in opt need to be loaded with packadd yyy. Also, packages placed in start cannot be unloaded.

5.2 Commonly used plugins

YouCompleteMe

This is an autocompletion plugin.

mkdir -p ~/.vim/pack/plugins/start
cd ~/.vim/pack/plugins/start
git clone https://github.com/ycm-core/YouCompleteMe.git
cd YouCompleteMe
git submodule update --recursive --init
python3 ./install.py --all --verbose

nerdtree

This is used for file management within Vim.

6. Summary

This article covered how to use Vim, including installing Vim, the most basic usage of Vim, and ways to memorize some commonly used shortcut keys.