Vim

repo: mhinz/vim-galore
category: Editors related: Neovim · Emacs · Sublime Text


Intro

Basics

Usage

Tips

Commands

Debugging

Miscellaneous

Common problems

Technical quirks

Terminology

List of colorschemes

List of plugins

<br>

Intro

What is Vim?

Vim is a text editor with a long line of ancestors that goes back to qed. Bram Moolenaar released it in 1991.

The project is hosted online at vim.org.

Getting Vim: Use your favourite package manager or visit the download page from vim.org.

Discussions and user questions are best done on the vim_use mailing list or using IRC (Freenode) in the #vim channel.

Development happens on GitHub, discussions on the vim_dev mailing list.

Read Why, oh WHY, do those #?@! nutheads use vi? to see common misconceptions about Vim explained.

The Vim Philosophy

Vim adheres to the modal editing philosophy. This means that it provides multiple modes and the meaning of keys changes according to the mode. You navigate files in normal mode, you insert text in insert mode, you select lines in visual mode, you access commands in command-line mode and so on. This might sound complicated at first, but has a huge advantage: you don't have to break your fingers by holding several keys at once, most of the time you simply press them one after the other. The more common the task, the fewer keys are needed.

A related concept that works well with modal editing are operators and motions. Operators start a certain action, e.g. changing, removing, or selecting text. Afterwards you specify the region of text you want to act on using a motion. To change everything between parentheses, use ci( (read change inner parentheses). To remove an entire paragraph of text, use dap (read delete around paragraph).

If you see advanced Vim users working, you'll notice that they speak the language of Vim as well as pianists handle their instruments. Complex operations are done using only a few key presses. They don't even think about it anymore as muscle memory took over already. This reduces cognitive load and helps to focus on the actual task.

First steps

Vim comes bundled with an interactive tutorial that teaches the most basic things you need to know about. You can start it from the shell:

$ vimtutor

Don't be put off by how boring it looks like and work through the exercises. The editors or IDEs you used before were most probably all non-modal, so working by switching modes will seem awkward at first, but the more you use Vim, the more it becomes muscle memory.

Vim was bolted on Stevie, a vi clone, and supports two operating modes: "compatible" and "nocompatible". Using Vim in compatible mode means using vi defaults for all options, opposed to Vim defaults. As long as you didn't create a user vimrc yet or started Vim with vim -N, compatible mode is assumed! Don't use Vim in compatible mode. Just don't.

Next steps:

  1. Create your own vimrc.
  2. Have some cheatsheets ready for the first weeks.
  3. Read through the basics section to learn what is even possible.
  4. Learn on demand! You never finish learning Vim. If you encounter any problems, just look for it on the internet. Your problem was solved already. Vim comes with great documentation and knowing how to navigate it is a must: Getting help offline.
  5. Have a look at the additional resources.

One last advice: Please learn how to use Vim properly before starting to add all kinds of hyped plugins that only implement features that Vim already supports natively.

Minimal vimrc

The user vimrc can be put into ~/.vimrc or for the sake of better separation into ~/.vim/vimrc. The latter makes it easy to put the entire configuration under version control and upload it to, let's say GitHub.

You find many "minimal vimrcs" all over the net, and maybe my version isn't as minimal as it should be, but it provides a good set of sane settings that I deem to be useful for starting out.

Eventually you have to read up on all the mentioned settings anyway and decide for yourself. :-)

So here it is: minimal-vimrc

In case you're interested, here's my vimrc.

TIP: Most plugin authors maintain several plugins and also publish their vimrc on GitHub (often in a repository called "vim-config" or "dotfiles"), so whenever you find a plugin you like, look up its maintainer's GitHub page and look through the repositories.

What kind of Vim am I running?

Looking at :version will give you all the information you need to know about how the currently running Vim binary was compiled.

The first line tells you when the binary was compiled and the version, e.g. 7.4. One of the next lines states Included patches: 1-1051, which is the patch level. Thus, your exact Vim version is 7.4.1051.

Another line states something like Tiny version without GUI or Huge version with GUI. The obvious information from that is whether your Vim includes GUI support, e.g. for starting gvim from the shell or running :gui from Vim within a terminal emulator. The other important information is the Tiny and Huge. Vim distinguishes between feature sets called tiny, small, normal, big, and huge, all enabling different subsets of features.

The majority of :version output is consumed by the feature list itself. +clipboard means the clipboard feature was compiled in, -clipboard means it wasn't compiled in.

A few Vim features need to be compiled in for them to work. E.g. for :prof to work, you need a Vim with a huge feature set, because that set enables the +profile feature.

If that's not the case and you installed Vim from a package manager, make sure to install a package called vim-x, vim-x11, vim-gtk, vim-gnome or similar, since these packages usually come with the huge feature set.

You can also test for the version or features programmatically:

" Do something if running at least Vim 7.4.42 with +profile enabled.
if (v:version > 704 || v:version == 704 && has('patch42')) && has('profile')
  " do stuff
endif

Help:

:h :version
:h feature-list
:h +feature-list
:h has-patch

Cheatsheets

  • http://people.csail.mit.edu/vgod/vim/vim-cheat-sheet-en.png
  • https://cdn.shopify.com/s/files/1/0165/4168/files/preview.png
  • http://michael.peopleofhonoronly.com/vim/vim_cheat_sheet_for_programmers_screen.png
  • http://www.rosipov.com/images/posts/vim-movement-commands-cheatsheet.png

Or quickly open a cheatsheet from within Vim: vim-cheat40.

Basics

Buffers, windows, tabs

Vim is a text editor. Every time text is shown, the text is part of a buffer. Each file will be opened in its own buffer. Plugins show stuff in their own buffers etc.

Buffers have many attributes, e.g. whether the text it contains is modifiable, or whether it is associated with a file and thus needs to be synchronized to disk on saving.

Windows are viewports onto buffers. If you want to view several files at the same time or even different locations of the same file, you use windows.

And please, please don't call them splits. You can split a window in two, but that doesn't make them splits.

Windows can be split vertically or horizontally and the heights and widths of existing windows can be altered, too. Therefore, you can use whatever window layout you prefer.

A tab page (or just tab) is a collection of windows. Thus, if you want to use multiple window layouts, use tabs.

Putting it in a nutshell, if you start Vim without arguments, you'll have one tab page that holds one window that shows one buffer.

By the way, the buffer list is global and you can access any buffer from any tab.

Active, loaded, listed, named buffers

Run Vim like this vim file1. The file's content will be loaded into a buffer. You have a loaded buffer now. The content of the buffer is only synchronized to disk (written back to the file) if you save it within Vim.

Since the buffer is also shown in a window, it's also an active buffer. Now if you load another file via :e file2, file1 will become a hidden buffer and file2 the active one.

Both buffers are also listed, thus they will get listed in the output of :ls. Plugin buffers or help buffers are often marked as unlisted, since they're not regular files you usually edit with a text editor. Listed and unlisted buffers can be shown via :ls!.

Unnamed buffers, also often used by plugins, are buffers that don't have an associated filename. E.g. :enew will create an unnamed scratch buffer. Add some text and write it to disk via :w /tmp/foo, and it will become a named buffer.

Argument list

The global buffer list is a Vim thing. Before that, in vi, there only used to be the argument list, which is also available in Vim.

Every filename given to Vim on the shell command-line, is remembered in the argument list. There can be multiple argument lists: by default all arguments are put into the global argument list, but you can use :arglocal to create a new argument list that is local to the window.

List the current arguments with :args. Switch between files from the argument list with :next, :previous, :first, :last and friends. Alter it with :argadd, :argdelete or :args with a list of files.

If you should prefer using the buffer or argument list for working with files is a matter of taste. My impression is that most people use the buffer list exclusively.

Nevertheless, there is one huge use case for the argument list: batch processing via :argdo! A simple refactoring example:

:args **/*.[ch]
:argdo %s/foo/bar/ge | update

This replaces all occurrences of "foo" by "bar" in all C source and header files from the current directory and below.

Help: :h argument-list

Mappings

You can define your own mappings with the :map family of commands. Each command of that family defines a mapping for a certain set of modes. Technically Vim comes with a whopping 12 modes, 6 of them can be mapped. Additionally, some commands act on multiple modes at once.

Recursive Non-recursive Unmap Modes
:map :noremap :unmap normal, visual, operator-pending
:nmap :nnoremap :nunmap normal
:xmap :xnoremap :xunmap visual
:cmap :cnoremap :cunmap command-line
:omap :onoremap :ounmap operator-pending
:imap :inoremap :iunmap insert

E.g. this defines the mapping for normal mode only:

:nmap <space> :echo "foo"<cr>

Unmap it again by using :nunmap <space>.

For a few more but rather uncommon modes (or combinations of them), see :h map-modes.

So far, so good. There's only one problem that can be pretty confusing to beginners: :nmap is recursive! That is, the right-hand side takes other mappings into account.

So you defined a mapping that simply echoes "Foo":

:nmap b :echo "Foo"<cr>

But what if you want to map the default behavior of b (going one word back) to another key?

:nmap a b

If you hit <kbd>a</kbd>, we expect the cursor to go back a word, but instead "Foo" is printed in the command-line! Because the right-hand side, b, was mapped to another action already, namely :echo "Foo"<cr>.

The proper way to resolve this problem is to use a non-recursive mapping instead:

:nnoremap a b

Rule of thumb: Always use non-recursive mappings unless recursing is actually desired.

Look up your mappings by not giving a right-hand side. E.g. :nmap shows all normal mappings and :nmap <leader> shows all normal mappings that start with the mapleader.

If you want to disable a standard mapping, map them to the special <nop> character, e.g. :noremap <left> <nop>.

Help:

:h key-notation
:h mapping
:h 05.3

Mapleader

The mapleader is simply a placeholder than can be used with custom mappings and is set to \ by default.

nnoremap <leader>h :helpgrep<space>

This mapping is triggered by \h. If you want to use <space>h instead:

let mapleader = ' '
nnoremap <leader>h :helpgrep<space>

Moreover, there is <localleader> that is the local counterpart to <leader> and is supposed to be used for mappings that are local to the buffer, eg. filetype-specific plugins. It also defaults to \.

Note: Set the mapleaders before mappings! All leader mappings that are in effect already, won't change just because the mapleader was changed. :nmap <leader> will show all normal mode leader mappings with the mapleader resolved already, so use it to double-check your mappings.

See :h mapleader and :h maplocalleader for more.

Registers

Registers are slots that save text. Copying text into a register is called yanking and extracting text from a register is called pasting.

Vim provides the following registers:

Type Character Filled by? Readonly? Contains text from?
Unnamed " vim [ ] Last yank or deletion. (d, c, s, x, y)
Numbered 0 to 9 vim [ ] Register 0: Last yank. Register 1: Last deletion. Register 2: Second last deletion. And so on. Think of registers 1-9 as a read-only queue with 9 elements.
Small delete - vim [ ] Last deletion that was less than one line.
Named a to z, A to Z user [ ] If you yank to register a, you replace its text. If you yank to register A, you append to the text in register a.
Read-only :, ., % vim [x] :: Last command, .: Last inserted text, %: Current filename.
Alternate buffer # vim [ ] Most of the time the previously visited buffer of the current window. See :h alternate-file
Expression = user [ ] Evaluation of the VimL expression that was yanked. E.g. do this in insert mode: <c-r>=5+5<cr> and "10" will be inserted in the buffer.
Selection +, * vim [ ] * and + are the clipboard registers.
Drop ~ vim [x] From last drag'n'drop.
Black hole _ vim [ ] If you don't want any other registers implicitly affected. E.g. "_dd deletes the current line without affecting registers ", 1, +, *.
Last search pattern / vim [ ] Last pattern used with /, ?, :global, etc.

Each register that is not readonly can be set by the user:

:let @/ = 'register'

Afterwards <kbd>n</kbd> would jump to the next occurrence of "register".

There are numerous exceptions when registers get implicitly filled, so be sure to read :h registers.

Yank with y and paste with p/P, but mind that Vim distinguishes between


truncated — full list on GitHub

[[curator]]
I'm the Curator. I can help you navigate, organize, and curate this wiki. What would you like to do?