why-vi.rocks/index.md

311 lines
4.7 KiB
Markdown
Raw Normal View History

<p class="f7">
<a href="/suggest.html">suggestion box</a> &ndash;
<a href="https://git.high5.nl/why-vi.rocks/log/">latest additions</a> &ndash;
<a href="/also.html">see also</a> &ndash;
<a href="/colophon.html">colophon</a>
</p>
2019-04-06 16:45:57 +02:00
2019-04-20 08:17:02 +02:00
<img class="mt4" src="vi-sw.png">
2019-04-07 09:49:48 +02:00
_[vi](https://en.wikipedia.org/wiki/Vi) is the **de facto** standard
text editor in any Unix-like operating system._
2019-04-06 16:45:57 +02:00
Here is a collection of [vi(1)](https://man.openbsd.org/vi.1)/[ex(1)](https://man.openbsd.org/ex.1) commands and command sequences.<br>
Tested with [nvi](https://en.wikipedia.org/wiki/Nvi) 1.79 and 2.1.3 (unicode).
[Bill Joy's greatest gift to man - the vi editor](https://www.theregister.co.uk/2003/09/11/bill_joys_greatest_gift/)
2019-04-06 23:50:55 +02:00
## Yank/delete lines
2019-04-06 16:45:57 +02:00
(1) mark the first line: `mk`<br>
(2) move to last line<br>
(3a) yank: `y'k`<br>
(3b) delete: `d'k`<br>
(4) move to destination line<br>
(5) put with `P` or `p`<br>
2019-04-06 16:45:57 +02:00
## Apply regex to lines
2019-04-06 16:45:57 +02:00
(1) mark the first line: `mk`<br>
(2) mark the last line: `ml`<br>
2019-04-06 23:00:29 +02:00
<pre>
:'k,'ls/<em>regex</em>/<em>power</em>/g
</pre>
2019-04-06 23:00:29 +02:00
## Increment / Decrement number in command mode
(1) move cursor to number<br>
(2a) increment by one: #+<br>
(2b) increment by N (5): 5#+<br>
(3a) decrement by one: #-<br>
(3b) decrement by N (9): 9#-
## Add &#35; to a block
<pre>
:'k,'ls/^/#/
</pre>
## Remove trailing whitespace from every line
2020-07-19 09:02:38 +02:00
<pre>
:%s/ *$//
</pre>
## Remove trailing whitespace from a block
2019-04-06 23:00:29 +02:00
2020-07-19 09:02:38 +02:00
<pre>
:'k,'ls/\ *$//
</pre>
2019-04-06 23:00:29 +02:00
## Remove the first N-characters from every line
N = 5
<pre>
:%s/^.\{0,<em>5</em>\}//
</pre>
## Delete all lines N-character long
N = 10
<pre>
:g/^.\{<em>10</em>\}$/d
</pre>
## Delete all lines _except_ N-character long
N = 10
<pre>
:g!/^.\{<em>10</em>\}$/d
</pre>
## Search/replace paths using &#35; as delimiter
<pre>
:%s#<em>/usr/local/log</em>#<em>/var/log</em>#g
</pre>
## Write the file as root
2019-04-06 16:45:57 +02:00
:w !doas tee %
## Diff the file on disk with the buffer
2019-04-06 16:45:57 +02:00
:w !diff -u % -
## Make a backup of the file on disk
2019-04-06 16:45:57 +02:00
2019-04-06 18:21:54 +02:00
:!cp % %.bak
2019-04-06 16:45:57 +02:00
## Sort all lines
2019-04-06 16:45:57 +02:00
:%!sort
2019-04-06 18:21:54 +02:00
## Sort a block
`}` won't be shown
2019-04-06 18:21:54 +02:00
<pre>
2019-04-20 08:38:21 +02:00
!<u>}</u>sort
</pre>
2019-04-07 12:57:19 +02:00
## Sort from the current line to EOF
`G` won't be shown
<pre>
!<u>G</u>sort
</pre>
## Delete duplicated lines in the file
2019-04-06 16:45:57 +02:00
:%!uniq
## Delete duplicated lines in the block
`}` won't be shown
<pre>
!<u>}</u>uniq
</pre>
2019-04-06 18:21:54 +02:00
## Delete duplicated lines till EOF
2019-04-06 18:21:54 +02:00
`G` won't be shown
2019-04-07 12:57:19 +02:00
<pre>
!<u>G</u>uniq
</pre>
## Underline all lines starting with `pattern`
<pre>
:g/^<em>pattern</em> /t.|s/./=/g
</pre>
## Search for `pattern`, print the containing function (start with `def`) and line number
<pre>
:g/<em>pattern</em>/?^ *<em>def</em> ?#
</pre>
## Add &#35; to paragraph containing `pattern`
<pre>
:g/<em>pattern</em>/?^$?+,//-s/^/#
</pre>
## Sort content of a multiline CSS block
:g/{$/+,/^}/-!sort
## Sort content of a multiline CSS block (media queries)
:g/^[^@].*{$/+,/}/-!sort
## Format content of `<p>` tag to fixed width
width = 40
<pre>
:g/&lt;p&gt;/+,/&lt;\/p&gt;/-!fmt -<em>40</em>
</pre>
## Format whole document
:%!fmt -s
In your .nexrc
<pre>
map gF :%!fmt -s<u>&lt;CTRL-V&gt;&lt;ENTER&gt;</u>
</pre>
## Reverse all lines, move `m` all lines to 0
:g/1*/m0
## Swap `Lastname, Firstname` to `Firstname, Lastname`
2019-04-08 19:54:24 +02:00
:%s/\(.*\), \(.*\)/\2 \1/
## Convert to lowercase
2019-04-20 08:46:47 +02:00
:%s/.*/\L&/
## Join all lines
2019-04-06 18:21:54 +02:00
:%j
## Copy `t` or move `m` lines containing `pattern`
<pre>
:g/<em>pattern</em>/t$
:g/<em>pattern</em>/m$
</pre>
## Select a column of a table
Select 3rd column separated by colon (`:`)
<pre>
:%!awk -F'<em>:</em>' '{print $<em>3</em>}'
</pre>
## Insert the sum of a list of numbers after an arbitrary number of lines
2019-04-06 18:21:54 +02:00
2019-04-20 08:46:47 +02:00
(1) mark the first line: `mk`
(2) mark the last line: `ml`
2019-04-06 18:21:54 +02:00
<pre>
:'k,'l!awk 'END{print "<em>total:</em>", i}{i+=$1; print}'
</pre>
or
<pre>
:'k,'l!awk 'END{print "<em>total:</em>", i} ++i || 1'
</pre>
## Email the block
2019-04-06 16:45:57 +02:00
<pre>
:?^$?+,//-w !mail -s "<em>subject</em>" <em>email@example.com</em>
</pre>
## Enable and use `ex` history
(1) Set `ESC` key to enable history or add to `~/.nexrc`:
2019-04-20 08:48:09 +02:00
<pre>
2019-04-20 08:48:09 +02:00
:set cedit=<u>&lt;CTRL-V&gt;&lt;ESC&gt;</u>
</pre>
2019-04-20 08:48:09 +02:00
(2) Use it with:
<pre>
:<u>&lt;ESC&gt;</u>
</pre>
## Integrate with tmux buffer
(1) cut text from current position to mark 'm' into tmux buffer. Hit undo to put text back into vi buffer.
<pre>
!'mtmux load-buffer -
</pre>
(2) paste text from tmux buffer into vi buffer.
<pre>
:r!tmux show-buffer
</pre>
2019-06-05 11:10:31 +02:00
(3) Map in ~/.nexrc (command mode)
<pre>
map gx !'mtmux load-buffer -<u>&lt;CTRL-V&gt;&lt;ENTER&gt;</u>
map gy !'mtmux load-buffer -<u>&lt;CTRL-V&gt;&lt;ENTER&gt;</u>u
map gp :r!tmux show-buffer<u>&lt;CTRL-V&gt;&lt;ENTER&gt;</u>
</pre>
2019-04-27 10:29:52 +02:00
2019-06-05 11:10:31 +02:00
## Remap ESC to ALT-i in ~/.nexrc (insert mode)
2019-04-27 10:29:52 +02:00
<pre>
map! <u>&lt;CTRL-V&gt;&lt;ALT-i&gt;</u> <u>&lt;CTRL-V&gt;&lt;ESC&gt;</u>
</pre>