Table of Content

Exit vim

Lets start with the most searched question about vim, how to close it

Normal ways to close vim

These commands are performed inside of vim

CommandDescription
:qcloses vim, if changes applied, it will ask if you want to save or not
:qacloses all open files by vim for this session
:q!force close vim
`:qa!force close all files opened by vim for this session
:xsave and close
:xasave and close all open files for this vim session
:x!force save and close
:x!force save and close all open files for this vim session
:exitlike :q

Other ways to close vim

Far away from recomended, but we saw that persons doing this for real.

Please never use them, just placed there here to get a little smile on your face ;)

CommandQuotes of user
<C-z>I can not see it any more, so it must be closed
:!pkill -9 vimWe dont care about swap files and who needs :q!
[closing terminal]I hate vim, never get out of it
[waiting for timeout on remote server]When my session is close, vim is closed as well

Generall

vim is the BEST DEITOR of the worl and the universe. Did I triggered you now ;) just kidding, it is a usefull editor. Some others say, they like more nano, emacs, echo/cat/less/more/sed to interact with file, but I think everyone should pic what they are comfortable to use. This will not be a full documentaion about vim, because that just would take way to long and makes harder to find things that are used by us on a regulare base.

Terminology

TermDesctiption
K_SPECIALIs the first byte of a special key code and is always followed by two bytes. The second byte can have any value. ASCII is used for normal termcap entries, 0x80 and higher for special keys, see below. The third byte is guaranteed to be between 0x02 and 0x7f.
KS_ExtraIs used for keys that have no termcap name (not listed in the terminfo database)

Configuration

The configuraiton is done in the ~/.vimrc, ~/.vim/vimrc, /etc/vim and some other places. Inside the vimrc you can define everything what you need, from functions, enabled plugins, to keybindings, to macros and so on.

The option <silent> means that no messages for the key sequence will be shown. <CR> is stands for character return, which you maybe thought already.

Keypress simulation

These keypress simulation of special keys like ^M, ^[ or ^W[a-zA-Z] are created in insertmode by pressing CTRL+v <special button> (<letter button if needed>).

  • CTRL+v Enter for ^M
  • CTRL+v ESC for ^[
  • CTRL+v Delete-Back for ^?
  • CTRL+v Delete-Back for ^[[3~
  • CTRL+v <CTRL>+w H for ^WH

If you want to write macros directly into your vimrc, you will need that quite often.

Using function keys

If you want to reuse the F[1-4] function keys, you have to unset them first, which can be done like this:

set <F1>=^[[11~
set <F2>=^[[12~
set <F3>=^[[13~
set <F4>=^[[14~

After that you can use map to attach a new command/function/.. to it.

map <F2> yyp!!/bin/bash<CR>

Custom Commands

You can also create custom commands, to speed up your working withing vim. These custom commands can also call external binaries with parameters.

command G execute ":Git %"
command! DiffOrig rightbelow vertical new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis

These allow you to write :G instead of :Git to interact with the git extention of vim. The second one, opens a diff view and compares the original file with the buffer you modified by running :DiffOrg.

Open files

To open multible files in one vim session, you have several ways, we now just describe two of them.

In tabs

To open them in tabs, use the parameter -p

$ vim -p <file1> <file2> <file3> <file4> ... <fileN>

You will see then on the top area the tab bar showing the names of the files. With the keybindings gt (next tab) and gT (previouse tab) you can jump between the open tabs.

In buffers

If the tab bar anoys you, you can just open each file in a seperate buffer.

$ vim <file1> <file2> <file3> <file4> ... <fileN>

Now vim will look as always, but with the commands :n (next buffer) and :N (previouse buffer) you can navigate between the buffers.

From stdin

Of course you can just pipe some output directly into vim.

$ ss -tulpena | vim -

After the command finished, vim will open and disaply you the result from stdin. If you want to save this now into a file, use :saveas /path/to/file

Open and execute commands

vim allows you to run commands while you are accessing the file and I dont mean the autocmd now, which can be placed in your .vimrc. I am talking about things like this:

$ vim -c "%s/,/\r/g" -c "sort" -c 'saveas! /tmp/bk_with_linebreaks' ./my_testfile

If you open the file like this, vim will execute the commands in the order you add it as paremter before you see the buffer with the content.

It is also possible, that you do some modifications using vim commands and then save-close the file ;)

$ vim -c "g/^set/d" -c "x" ~/another_file

Keybindings

Text object selection

KeybindingsDescription
awa word, leading/trailing white space included, but not counted
aWk WORD, leading/trailing white space included, but not counted
iwinner word, white space between words is counted
iWinner WORD, white space between words is counted
asa sentence
isinner sentence
apa paragraph, blank lines (only containing white space) is also counted as paragraph boundary
ipinner paragraph, blank lines (only containing white space) is also counted as paragraph boundary
a]/a[a [ ] block, enclosed text is selected, if not in block, performs on next one, including [ and ]
i]/i[innner [ ] block, enclused text is selected, excluding [ and ]
a)/a(/aba ( ) block, enclosed text is selected, if not in block, performs on next one, including ( and )
i)/i(/ibinner ( ) block, enclosed text is selected, if not in block, performs on next one, exluding ( and )
a}/a{/aBa { } block, enclosed text is selected, if not in block, performs on next one, including { and }
i}/i{/iBinner { } block, enclosed text is selected, if not in block, performs on next one, exluding { and }
a>/a<a < > block, enclosed text is selected, including < and >
i>/i<innner < > block, enclused text is selected, excluding < and >
ata tag block, enclosed test in selected tag block (e.g. .. ), including block boundary
itinner tag block, enclosed test in selected tag block (e.g. .. ), excluding block boundary
a"/a'/`a``a quoted string, works only within one line, enclosed text is selected, including the quoats
i"/i'/`i``a quoted string, works only within one line, enclosed text is selected, excluding the quoats
gvrecreates last virutal select
gnforward search with last pattern + starts visual mode
gNbackward search with last pattern + starts visual mode

Normal Mode

<<<<<<< Updated upstream Keybindings | Description –––––––––– | ———– <C-r> | redo commands (undo your undone changes) q[a-z] | starts macro recording and maps to [a-z] q[A-Z] | appends commands to macro [A-Z] (uppercase to append) q | stops macro recording @[a-z] | execute macro [a-z] [1-n]@[a-z] | executes macro [a-z] for n times (default 1) @@ | executes last macro again [1-n]@@ | executes last macro for n times (default 1) "+p | inserts clipboard content <C-^> | jumps between last opend two files in argument list zo | open fold zO | open all folds beneigth the cursor zc | close fold zC | close all folds beneigth the cursor za | toggles folds zA | toggles folds and child folds zM | closes all folds zR | openes all folds zF | create folded text in visual mode zE | eliminate all folds in the current file zd | delets fold where cursor is on zD | deletes folds recursively at the cursor gt | go to next tab gT | go to previous tab <C-w>+T | move the current split window into tabs, to open a additional file in split use :vsp /path/.xxx {i}gt | go to tab in position {i} <C-w> K | Change two vertically split to horizonally split <C-w> H | Change two horizonally split to vertitally split <C-w> < | Resizes current split to the left with one line <C-w> > | Resizes current split to the right with one line <C-w> + | Extend height of current split with one line <C-w> - | Lower height of current split with one line <C-w> _ | Max the height of current split <C-w> | | Max the width of current split <C-w> = | Normalize all split sizes <C-w> J | moves splited window at the bottom <C-w> K | moves splited window at the top <C-w> R | Swap top/bottom or left/right split <C-w> N | changes terminal mode to normal mode (use vim keybindings to navigate and so on) <C-w> i/a | changes terminal back to insert mode <Leader> | by default \ which can be changed with mapleader % | move to matching character like (), {}, [] "<regname>yy | yank into register <renname> e.g. yank full line to reg x: V"xy "<REGNAME>yy | appends yank into register <renname> e.g. yank full line to reg x: V"Xy "<regname>p | past contens of reg <regname> e.g. past from reg x: "xp m<markname> | set current position for mark <markname> e.g. set position on mark a: ma <markname> | jup to position of mark <markname> e.g. jup to mark a: `a y`<markname> | yank text of position of mark <markname> e.g. yank from mark a: y`a ctrl+o | opens previous opened files z= | opens suggestions from spellchecker zg | adds word to own spell list ]s | move the cursor to the next misspelled word [s | move the cursor back through the buffer to previous misspelled words q: | opens last commands view q:<tab> | inside of last commands you will get a list of all executeables to run g; | jump back to the position of previos (older) change g, | jump back to the position of next (newer) change gj | If you have multiline enabled in vim, you can use gj to navigate in such lines one down gk | Same as above, but naviges in multiline one up dgn | Delets the next search pattern matching last search

KeybindingsDescription
<C-r>redo commands (undo your undone changes)
q[a-z]starts macro recording and maps to [a-z]
q[A-Z]appends commands to macro [A-Z] (uppercase to append)
qstops macro recording
@[a-z]execute macro [a-z]
[1-n]@[a-z]executes macro [a-z] for n times (default 1)
@@executes last macro again
[1-n]@@executes last macro for n times (default 1)
"+pinserts clipboard content
<C-^>jumps between last opend two files in argument list
zoopen fold
zOopen all folds beneigth the cursor
zcclose fold
zCclose all folds beneigth the cursor
zatoggles folds
zAtoggles folds and child folds
zMcloses all folds
zRopenes all folds
zFcreate folded text in visual mode
zEeliminate all folds in the current file
zddelets fold where cursor is on
zDdeletes folds recursively at the cursor
gtgo to next tab
gTgo to previous tab
<C-w>+Tmove the current split window into tabs, to open a additional file in split use :vsp /path/.xxx
{i}gtgo to tab in position {i}
<C-w> KChange two vertically split to horizonally split
<C-w> HChange two horizonally split to vertitally split
<C-w> <Resizes current split to the left with one line
<C-w> >Resizes current split to the right with one line
<C-w> +Extend height of current split with one line
<C-w> -Lower height of current split with one line
<C-w> _Max the height of current split
<C-w> |Max the width of current split
<C-w> =Normalize all split sizes
<C-w> Jmoves splited window at the bottom
<C-w> Kmoves splited window at the top
<C-w> RSwap top/bottom or left/right split
<C-w> Nchanges terminal mode to normal mode (use vim keybindings to navigate and so on)
<C-w> i/achanges terminal back to insert mode
<Leader>by default \ which can be changed with mapleader
%move to matching character like (), {}, []
"<regname>yyank into register <renname> e.g. yank full line to reg x: V"xy
"<REGNAME>yappends yank into register <renname> e.g. yank full line to reg x: V"Xy
"<regname>ppast contens of reg <regname> e.g. past from reg x: "xp
m<markname>set current position for mark <markname> e.g. set position on mark a: ma
<markname>jup to position of mark <markname> e.g. jup to mark a: `a
y`<markname>yank text of position of mark <markname> e.g. yank from mark a: y`a
ctrl+oopens previous opened files
z=opens suggestions from spellchecker
zgadds word to own spell list
]smove the cursor to the next misspelled word
[smove the cursor back through the buffer to previous misspelled words
q:opens last commands view
q:<tab>inside of last commands you will get a list of all executeables to run
g;jump back to the position of previos (older) change
g,jump back to the position of next (newer) change
gjIf you have multiline enabled in vim, you can use gj to navigate in such lines one down
gkSame as above, but naviges in multiline one up
dgnDelets the next search pattern matching last search
=<object-selection>Allows you to perofrm indentation, e.g. =i{ will align content for inner block

Stashed changes

Insert Mode

KeybindingsDescription
<C-y>copies live above symbol by symbol
<C-r>[0-9a-z]will past the content of the register [0-9a-z]
<C-h>deletes backwards
<C-w>deletes backwards word
<C-n>opens auto-complete dialog

Visual Mode General

KeybindingsDescription
g <C-g>counts bytes/words/lines in visual selected area
<C-g>swiches between visual/select mode
:<command>works kind of close to normal mode
[a-z]most keybdinings for modifing the content work as before

Visual Block Mode

KeybindingsDescription
<C-i>/<C-a>starts insertmode before/after selected block
g<C-a>creates increment list of numbers

Visual Line Mode

KeybindingsDescription
g <C-g>counts lines of visual area

Custom Macros

You can add macros in the your vimrc config or where ever you have placed your configuration.

They are easy to add, with a simple structe:

let @<macro_keyboard_key>='<vim_commands>'

If you need special characters, have a look at the topic Keypress simulation there you will get some insites to this.

Macro sample

This will replace traiding whitespaces in your open buffer if you press @+m in vim

let @w=':%s/[[:blank:]]*$//g^M'

And as you can see there, we have ^M used for simulating an Enter key ;)

If you want to copy/paste it via OS clipboard you could write it like this:

let @w=":@s/[[:blank:]]*$//g\<CR>"

As if you paste virtual key press simulation into another vim session, it happens that it does interpret each character as text, so the virtual key press gets lost.

Usefull Commands

Search and append line to register

Assuming you want to have all your header lines which are starting with # in your .md file copied to the register h you could use the following command:

:let @h=''
:gloabl/^##* /yank H

So what is it doing:

  • let @h='': frist we want to ensure that our register h does not contain any other data.
  • global: executes the Ex command globaly
  • /^##* : searches with regex ^##* meaning all lines starting with at least one # followed by a space are getting used
  • /yank H: performs on each found line the yank (with appaned) command to the register h

What is…

^[<80>a

Sometimes you will see in your macros the sequence ^[<80><fd>a and ask your self what this is. The escape sequence ^[ is something what you maybe konw already and if not, have a look here: Keypress simulation But what is the rest?

Lets go through that quickly.

  • <80>: This is a K_SPECIAL - the first bite of a special key code (more details at Terminology)
  • <fd>: This is a KS_EXTR - placeholder if no termcap name (more details at Terminology)
  • a: This is KE_NOP - don’t do anything

The full sequence is a <Nop>, like “no operation”. Vim will not blamle about it and process it as a valid command, but actually it does nothing.

So, why do we see this now in our macros/registers.

The reason why Vim will insert a <Nop> right after an <Esc> while recording a macro is that <Esc> is typically a key that starts a special sequence (special keys such as <Up>, <Down>, <F1>, etc. all produce sequences that start with <Esc>), so if you were to press a sequence of keys that produced a valid escape sequence, right after pressing <Esc>, then when replaying that sequence, Vim would recognize that key, instead of <Esc> and the other characters that were actually recorded.

Fun with vim

It is getting less that applications have easter eggs, vim has still some ;) hope you will enjoy them and bring a litle :smile to your face

  • :help!
  • :Ni!
  • :help 42 or start vim like this vim +h42
  • :help holy-grail
  • :help UserGettingBored
  • :smile