2019-04-06 23:02:07 +02:00
|
|
|
# Why vi Rocks
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-07 09:49:48 +02:00
|
|
|
**[vi](https://en.wikipedia.org/wiki/Vi)** is the _de facto_ standard
|
|
|
|
Unix editor, you find it in every *NIX derived OS.
|
|
|
|
|
|
|
|
Here you will find a collection of commands, command sequences in
|
|
|
|
[vi(1)](https://man.openbsd.org/vi.1)/[ex(1)](https://man.openbsd.org/ex.1)
|
|
|
|
or with 3rd party unitilities which make
|
2019-04-10 16:10:01 +02:00
|
|
|
**[vi](https://en.wikipedia.org/wiki/Vi)** rock \m/. These all work
|
2019-04-07 09:49:48 +02:00
|
|
|
with at least [nvi](https://en.wikipedia.org/wiki/Nvi) 1.79 and
|
|
|
|
2.1.3 (unicode).
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-15 09:28:18 +02:00
|
|
|
We are always looking for [suggestions](/suggest.html) that go beyond the basics.
|
|
|
|
|
2019-04-10 20:55:18 +02:00
|
|
|
Helpful documents:
|
|
|
|
|
2019-04-06 23:43:20 +02:00
|
|
|
- [Roman Zolotarev: Edit text with vi(1)](https://rgz.ee/vi.html)<br />
|
2019-04-08 21:31:06 +02:00
|
|
|
- [Hugo Daniel: vi is not vim](https://hugodaniel.pt/posts/vi-is-not-vim/)<br />
|
2019-04-10 20:55:18 +02:00
|
|
|
- [Jeff W: vi help](http://www.jeffw.com/vi/vi_help.txt) / [Maarten Litmaath: vi reference](http://www.ungerhu.com/jxh/vi.html)<br />
|
|
|
|
- [alphanrrrd: extremely concise cheatsheet](http://www.alphanrrrd.org/vi.html) / [ViEmu: Graphical vi cheatsheet](http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html)<br />
|
|
|
|
- [The vi archive and FAQ (mirror)](http://git.larryhynes.net/vi/)
|
2019-04-06 23:50:55 +02:00
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Yank / delete an arbitrary number of lines
|
2019-04-06 16:45:57 +02:00
|
|
|
|
|
|
|
1) mark the first line: mk
|
|
|
|
2) move to last line
|
|
|
|
3a) yank: y'k
|
|
|
|
3b) delete: d'k
|
2019-04-07 09:49:48 +02:00
|
|
|
4) move to destination line
|
|
|
|
5) put with P or p
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Apply regex to an arbitrary number of lines
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
1) mark the first line: mk
|
|
|
|
2) mark the last line: ml
|
|
|
|
:'k,'ls/regex/power/g
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-06 23:00:29 +02:00
|
|
|
#### Add # to block of text
|
|
|
|
|
2019-04-08 19:31:16 +02:00
|
|
|
:'k,'ls/^/#/
|
2019-04-06 23:00:29 +02:00
|
|
|
|
|
|
|
#### Remove trailing whitespace of block of text
|
|
|
|
|
|
|
|
:'k,'ls/\ *$//
|
|
|
|
|
2019-04-15 08:44:30 +02:00
|
|
|
#### Remove the first N (5) characters from every line
|
|
|
|
|
|
|
|
:%s/^.\{0,5\}//
|
|
|
|
|
2019-04-08 19:33:45 +02:00
|
|
|
#### Search and replace PATHs, using different delimiter
|
|
|
|
|
|
|
|
:%s#/usr/local/log#/var/log#g
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Write file as root
|
2019-04-06 16:45:57 +02:00
|
|
|
|
|
|
|
:w !doas tee %
|
|
|
|
|
2019-04-06 21:51:17 +02:00
|
|
|
#### Diff the file on disk with the file in the buffer
|
2019-04-06 16:45:57 +02:00
|
|
|
|
|
|
|
:w !diff -u % -
|
|
|
|
|
|
|
|
#### Make a backup of the file on disk
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
:!cp % %.bak
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Sort all lines
|
2019-04-06 16:45:57 +02:00
|
|
|
|
|
|
|
:%!sort
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Sort paragraph
|
|
|
|
|
|
|
|
!}sort
|
|
|
|
|
2019-04-07 12:57:19 +02:00
|
|
|
<sub><sup>} won't be shown in the command.</sup></sub>
|
|
|
|
|
2019-04-07 12:45:27 +02:00
|
|
|
#### Sort from current line to EOF
|
|
|
|
|
|
|
|
!Gsort
|
|
|
|
|
|
|
|
<sub><sup>G won't be shown in the command.</sup></sub>
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Uniq all lines
|
2019-04-06 16:45:57 +02:00
|
|
|
|
|
|
|
:%!uniq
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Uniq paragraph
|
|
|
|
|
|
|
|
!}uniq
|
|
|
|
|
2019-04-07 12:57:19 +02:00
|
|
|
<sub><sup>} won't be shown in the command.</sup></sub>
|
|
|
|
|
2019-04-07 12:45:27 +02:00
|
|
|
#### Uniq from current line to EOF
|
|
|
|
|
|
|
|
!Guniq
|
|
|
|
|
|
|
|
<sub><sup>G won't be shown in the command.</sup></sub>
|
|
|
|
|
2019-04-08 11:00:53 +02:00
|
|
|
#### Underline all lines starting with CHAPTER
|
|
|
|
|
|
|
|
:g/^CHAPTER /t.|s/./=/g
|
|
|
|
|
|
|
|
#### Search for "pattern", print the containing function (start with def) and line number
|
|
|
|
|
|
|
|
:g/pattern/?^ *def ?#
|
|
|
|
|
|
|
|
#### Add # to paragraph containing "pattern"
|
|
|
|
|
|
|
|
:g/pattern/?^$?+,//-s/^/#
|
|
|
|
|
|
|
|
#### Sort content of multiline CSS blocks
|
|
|
|
|
|
|
|
:g/{$/+,/^}/-!sort
|
|
|
|
|
|
|
|
#### Sort content of multiline CSS blocks (media queries)
|
|
|
|
|
|
|
|
:g/^[^@].*{$/+,/}/-!sort
|
|
|
|
|
|
|
|
#### Reformat HTML paragraphs to a fixed width (40)
|
|
|
|
|
|
|
|
:g/<p>/+,/<\/p>/-!fmt -40
|
|
|
|
|
|
|
|
#### Swap "Lastname, Firstname" to "Firstname, Lastname"
|
|
|
|
|
2019-04-08 19:54:24 +02:00
|
|
|
:%s/\(.*\), \(.*\)/\2 \1/
|
2019-04-08 11:00:53 +02:00
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Join all lines
|
|
|
|
|
|
|
|
:%j
|
|
|
|
|
2019-04-08 11:00:53 +02:00
|
|
|
#### Copy (t) or move (m) lines containing "pattern"
|
|
|
|
|
|
|
|
:g/pattern/t$
|
|
|
|
:g/pattern/m$
|
|
|
|
|
2019-04-06 18:21:54 +02:00
|
|
|
#### Select a column (3rd) from formated text seperated by ':'
|
|
|
|
|
|
|
|
:%!awk -F':' '{print $3}'
|
|
|
|
|
2019-04-08 11:00:53 +02:00
|
|
|
#### Insert the sum of a list of numbers after an arbitrary number of lines
|
|
|
|
|
|
|
|
1) mark the first line: mk
|
|
|
|
2) mark the last line: ml
|
|
|
|
:'k,'l!awk 'END{print "Total:", i}{i+=$1; print}'
|
|
|
|
|
|
|
|
More compact version:
|
|
|
|
:'k,'l!awk 'END{print "Total:", i} ++i || 1'
|
|
|
|
|
|
|
|
#### Email the current paragraph
|
2019-04-06 16:45:57 +02:00
|
|
|
|
2019-04-08 11:00:53 +02:00
|
|
|
:?^$?+,//-w !mail -s "<subject>" email@example.com
|
2019-04-10 10:25:06 +02:00
|
|
|
|
|
|
|
#### Enable and use ex history
|
|
|
|
|
|
|
|
1) Set ESC key to enable history, or add to .exrc:
|
|
|
|
:set cedit=<CTRL-V><ESC>
|
|
|
|
|
|
|
|
2) Use it with:
|
|
|
|
:<ESC>
|