VIM

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

Commands

Normal Mode

Execute command on all open bufferes

To execute something (command,macro,keybinding) on all open buffers, you can use the command :argdo.

VIM will execute what ever you have defined in a serial way (like you would do it manually)

Lets assume, we want to rearange some content. We have 10 files, each file contain the output of seferal md5sum commands. What we want is, to have the md5-sums at the end of the line and the file path at the beginning. For this, we register a macro, which performs this for us:

0/ \/.^MD0I ^[P0@q

If you are not familiar with the macro and with the special character please have a look at Macro sample

Now as we have the macro in place, lets quickly undo all done changes in the file, that we are back to the original data.

If your VIM saves the cursor position for each file, keep in mind that you have to ensaure that you are, for the above mentioned macro, at the first line of the file

The setup is ready and we can start use now the following command:

:argdo :normal @<register>

Of course, replace <register> with the register you have used to record the macro into.

What will happen next is, that VIM executes the macro in the current buffer, if it is finished, it will jump to the next buffer and continues like this.

Keybindings

Text object selection

KeybindingsDescription
awa word, leading/trailing white space included, but not counted
aWa 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. <html> .. </html>), including block boundary
itinner tag block, enclosed test in selected tag block (e.g. <html> .. </html>), 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

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 (), {}, []
`“y{motion}yank into register <renname> e.g. yank full line to reg x: V"xy/ "xyy / "xY or single word `“xyiw
`“y{motion}appends 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 line position of mark <markname> e.g. jup to mark a: 'a
`<markname>jup to line and character 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 perform indentation, e.g. =i{ will align content for inner block
gg=Gwill perform indentation on the full document
`“=[0-9]+[+-*/][0-9]+pperforms calculation and pasts it, calculation itself is stored in register =

If you want to use the result afterwards again of the calculation using the register = you can not simply run "=p as this will already initialize a new content for the register =.

To get the content again printend, use :put = instead.

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