vim

vim running in Konsole in KDE on Fedora

Keybindings

Keybindings to move around and edit the buffer in normal mode.

Using the home row1 to navigate the buffer.

  • h: ← left
  • j: ↓ down
  • k: ↑ up
  • l: → right

Editing

  • u: undo
  • C-r: restore

Change paragraphs and words:

  • gwl: reflow/justify current line
  • gwip: reflow current paragraph
  • gwG: reflow from cursor position to end of file
  • gu: lowercase
  • gU: uppercase
  • g~: swap case

Change to normal mode:

  • <esc>: activate normal mode

Jumping around

Moving relative to the visible buffer:

  • H: go to top of the buffer/first visible line
  • L: go to the bottom of the buffer/last visible line
  • M: got to the middle of the (visible) buffer

Moving relative to the file/all lines in the current buffer:

  • gg: go to the first line of the buffer
  • G: go to last line of the buffer

Go to lines:

  • 5gg: go to line 5 (Ng goes to line N)
  • 5G: same as 5gg

Moving through the current line:

  • w: next word

Inserting

Switching from normal mode to insert mode:

  • i: insert at current position
  • a: inert after cursor
  • I: move to start of current line and insert
  • A: move end of current line and insert
  • o: insert on new line below cursor
  • O: insert on new line above cursor
  • ea: insert at end of word

Staying in normal mode:

  • .: repeat last insert

Copy, cut and paste

Copying is called yanking, cutting is called deleting and pasting is called putting.

Selecting

  • v: mark/select text
  • V: mark/select lines

Yanking

  • y: yank/copy current selection
  • y$: yank to end of line
  • yy: yank current line
  • 2yy: yank 2 lines (Nyy yanks N lines).
  • yw: yank the rest of the current word
  • yaw: yank current word and following space
  • yiw: yank current word

Deleting

Same patterns as yanking, but starts with d instead.

  • d: delete/cut current selection
  • d$/D: delete to end of line
  • dd: delete current line
  • 2dd: delete 2 lines (Ndd deletes N lines).
  • dw: delete rest of current word
  • diw: delete current word
  • daw: delete current word and the following space

Pasting

  • p: put/paste after the cursor
  • P: put/paste before the cursor
  • gp: put after cursor and leave cursor after text
  • gP: put before cursor and leave cursor after text

Sorting

  • :sort: sort alphabetically.
  • :sort!: sort descending. Sorts selection in visual mode.
  • :sort u: unique sort.
  • :sort i: ignore case.
  • :sort n: sort on the first number in the line.

Search and replace

  • :%s/<old>/<new>/g: replace <old> with <new> (same as sed)
  • /<pattern>: search for <pattern>
  • ?<pattern>: search backwards for <pattern>
  • n: next match in same direction
  • N: next match in opposite direction
  • ci $DELIMITER: removes the text between the matching $DELIMITER and enters insert mode.
  • :noh: remove highlighting of search matches

Buffers

Open and save files, and move around open buffers in normal mode.

  • :e: edit/open file

Saving and closing

  • :q: quit (errors if there are unsaved edits)
  • :q!: force quit/close
  • :qa: close all buffers
  • :qa!: force close all buffers
  • :w: write/save buffer
  • :wq: save and quit
  • :wqa: save all buffers and quit
  • :wqa!: save all buffers and force quit

Split windows

  • :split/:sp and C-W s: split horizontally
  • :vsplit/:vs and C-W v: split vertically
  • :sun/:sunhide: split to open one window for each open buffer
  • :sun N: same as :sun but to a maximum of N buffers

Move around file tree

  • :Lexplore [$path]: split vertically and list current dir or $path in the split
  • :Lexplore! [$path]: toggle directory listing in split
  • :25Lexplore: split vertically, setting width of split to 25 chars (:${N}Lexplore sets width to $N).
  • :[N]Hexplore [$path]: split horizontally
  • :Explore [$path]/:e $path: Explore current dir or $path in new window

Manage and navigate

  • :ls: show open buffers/files
  • :b 1: switch to buffer 1 (:b N goes to buffer N)
  • :bn: switch to next buffer
  • :bp: switch to previous buffer
  • :b#: switch to most recently used buffer

Other

  • .: repeat last command

.vimrc

Fedora-based systems and Debian based systems have fairly different defaults in /etc/vimrc, and personally I think the Fedora defaults are better.

General vim behaviour

Use vim settings instead of vi defaults. This must be first in your .vimrc.

set nocompatible

Turn off automatic backup files, swap files, terminal bells and don't wrap around the end of the terminal emulator.

set nobackup
set noswapfile
set noerrorbells
set nowrap

Prevent delays when switching to insert mode (this is in /etc/vimrc in Fedora, Amazon Linux and other RH-based distros, but not Debian).

set timeout
set timeoutlen=100

Enable auto indenting by default.

set ai

Default to changing into the dir of the currently open file.

set autochdir

Files and buffers

Remove trailing whitespace from files.

autocmd BufWritePre * :%s/\s\+$//e

Show a few lines around the cursor while moving around the buffer.

set scrolloff=10

Retain history between sessions

Jump to last position when opening a file again.

autocmd BufReadPost *
\ if line("'\"") > 0 && line ("'\"") <= line("$") |
\   exe "normal! g'\"" |
\ endif

By default your history is saved to ~/.viminfo (it's probably not smart to keep this file in source control).

Save undo history between vim sessions

set undofile
set undodir=~/.cache/vim/undo

Will save your undo history in ~/cache/vim/undo.

Searching

Highlight current search matches, also while typing.

set hlsearch
set incsearch

Make search be case-insensitive.

set ignorecase

Syntax highlighting

Enable syntax highlighting.

syntax on

Detect language from filetypes.

filetype on
filetype plugin on

You can also manually setf the filetype based on filenames.

au BufNewFile,BufRead Jenkinsfile setf groovy
au BufNewFile,BufRead *.html.j2 setf html

This will use groovy syntax for Jenkinsfile files, and html syntax for files that match *.html.j2.

netrw

I like using netrw to move around the file tree with :explore. To make it easier to use it's a good idea to remove both the 4-line banner and ./ from the list2.

let g:netrw_banner=0
let g:netrw_list_hide='^\.\=/\=$'

To hide other common and uninteresting-to-vim files in the file tree, you can expand this.

let g:netrw_list_hide= '\~$,\.zip$,\.pyc$,^__pycache__\/$,\.git[a-z]*\/$,\.DS_Store\/$,^\.\=/\=$'

A keybinding to toggle a netrw buffer.

nnoremap <leader>8 :25Lexplore!<cr>

This only binds it while in normal mode, and I personally like using the number keys for toggle-style keybindings.

References

5

md-vim: Markdown plugin for Vim

6

preservim/vim-markdown - GitHub: Syntax highligting, matching rules and mappings for the original Markdown.