VIM
Table of Content
- Exit vim
- Generall
- Configuration
- Open files
- Commands
- Keybindings
- Custom Macros
- Usefull Commands
- What is…
- [.. ^<80>
a
- [.. ^<80>
- [Fun with vim](#fun with vim)
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
Command | Description |
---|---|
:q | closes vim , if changes applied, it will ask if you want to save or not |
:qa | closes all open files by vim for this session |
:q! | force close vim |
`:qa! | force close all files opened by vim for this session |
:x | save and close |
:xa | save 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 |
:exit | like :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 ;)
Command | Quotes of user |
---|---|
<C-z> | I can not see it any more, so it must be closed |
:!pkill -9 vim | We 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
Term | Desctiption |
---|---|
K_SPECIAL | Is 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_Extra | Is 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
Keybindings | Description |
---|---|
aw | a word, leading/trailing white space included, but not counted |
aW | a WORD, leading/trailing white space included, but not counted |
iw | inner word, white space between words is counted |
iW | inner WORD, white space between words is counted |
as | a sentence |
is | inner sentence |
ap | a paragraph, blank lines (only containing white space) is also counted as paragraph boundary |
ip | inner 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( /ab | a ( ) block, enclosed text is selected, if not in block, performs on next one, including ( and ) |
i) /i( /ib | inner ( ) block, enclosed text is selected, if not in block, performs on next one, exluding ( and ) |
a} /a{ /aB | a { } block, enclosed text is selected, if not in block, performs on next one, including { and } |
i} /i{ /iB | inner { } 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 > |
at | a tag block, enclosed test in selected tag block (e.g. <html> .. </html> ), including block boundary |
it | inner 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 |
gv | recreates last virutal select |
gn | forward search with last pattern + starts visual mode |
gN | backward search with last pattern + starts visual mode |
Normal Mode
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 () , {} , [] |
`“ | yank into register <renname> e.g. yank full line to reg x: V"xy / "xyy / "xY or single word `“xyiw |
`“ | 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 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+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 |
=<object-selection> | allows you to perform indentation, e.g. =i{ will align content for inner block |
gg=G | will perform indentation on the full document |
`“=[0-9]+[+-*/][0-9]+p | performs 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
Keybindings | Description |
---|---|
<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
Keybindings | Description |
---|---|
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
Keybindings | Description |
---|---|
<C-i>/<C-a> | starts insertmode before/after selected block |
g<C-a> | creates increment list of numbers |
Visual Line Mode
Keybindings | Description |
---|---|
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 registerh
does not contain any other data.global
: executes theEx
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 theyank
(with appaned) command to the registerh
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 aK_SPECIAL
- the first bite of a special key code (more details at Terminology)<fd>
: This is aKS_EXTR
- placeholder if no termcap name (more details at Terminology)a
: This isKE_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 thisvim +h42
:help holy-grail
:help UserGettingBored
:smile