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?