The famous UNIX vi(1) editor that so many are not able to quit … some of them literally 🙂
You may want to check other articles in the Ghost in the Shell series on the Ghost in the Shell – Global Page where you will find links to all episodes of the series along with table of contents for each episode’s contents.
When I was introduced to vi(1) (or it was vim(1) maybe …) – it really felt strange – like something I have never used before.
I tried to remember what I need to do – and for most of the time I was able to use vi(1) in its really basic usage and this feeling accompanied me till the time I really started using Linux and later FreeBSD as mine main place to live – my desktop/laptop workstation.
One may ask – and I have seen this question multiple times – why learn vi(1) in 2024?
I can answer that in the most annoying way – with another question – why learn anything at all? Because … you really do not have to. Just start watching another show on Netflix or get back to your preferred social media platform and scroll thru the timeline till bored … and the answer I can give You is – its the editor that will be available on any UNIX (or Linux) system today – and if You are interested in learning UNIX systems – then “This is the way!”.
Its like with cursive writing – “Cursive is designed to minimize number of times you need to lift your hand away.” – and its the same with vi(1) editor. One of the nuances of it are that you can use arrow [ Left ] [ Down ] [ Up ] [ Right ] keys or … use the native [ h ] [ j ] [ k ] [ l ] keys – which are closer to your hands as they lay down on the keyboard.
… but I will be brutally honest with You – I never got used to this ‘native’ [ H ] [ J ] [ K ] [ L ] mode and still use keyboard arrows to navigate … but I use many other of its features.
Today I would like to focus on 80/20 rule. I do not plan to show You each possible vi(1) option out there. My goal here is to show you the most frequently used ones and the most useful ones.
The Table of Contents for this article below.
- Modes
- Command Mode
- Copy/Cut/Paste
- Real World Example
- Comment Out Multiple Lines
- Uppercase and Lowercase Fast Switch
- Insert Mode and Editing
- How to Quit
- Search and Replace
- Visual Mode
- Config Files
- Tricks
- IDE Replacement
- Alternatives
- Internals
Modes
First things first – there are TWO modes in which you can achieve different things. Kinda like ‘on any gear’ and ‘neutral’ in a manual transmission car.
There is COMMAND mode in which you move around or do some shit like removing or copy/paste stuff.
There is also INSERT mode in which you just type keys and characters appear on the screen (or in the file).
Command Mode
Lets start with less obvious COMMAND mode. You enter this mode by pressing the [ ESC ] key. I will write all the shortcuts as [ ESC ] + [ $ ] but if you are already in the COMMAND mode then its the same as just typing the [ $ ] key.
Now – here are some useful things you may do while being in the COMMAND mode in the vi(1) editor.
The [ 0 ] will move the cursor the the ‘zero’ position (left) while [ ^ ] will focus on first character AFTER the spaces and tabs in front. So to do this you will type [ ESC ] + [ 0 ] on your keyboard.
The [ $ ] will move to the last character in this line. So to do this you will type [ ESC ] + [ $ ] on your keyboard … and by [ $ ] I mean [ SHIFT ] + [ 4 ] on ANSI layout keyboard – you may have different keyboard layout then ANSI … fortunately the [ Home ] and [ End ] keys also work.
With the [ w ] you will skip forward between words and with [ b ] you will skip backwards between words. So that will be [ ESC ] + [ w ] and [ ESC ] + [ b ] respectively. You can also use ${NUMBER} before [ w ] or [ b ] to skip {NUMBER} of words. For example [ ESC ] + [ 4 ] + [ w ] to skip nest four words.
With {number}G you will be moved to the {number} line – for example [ ESC ] + [ 9 ] + [ G ] (or just [ ESC ] + [ 9 ] + [ G ] if you are already in the COMMAND mode) will move cursor to 9th line of a file. Its uppercase [ G ] so its like [ ESC ] + [ 9 ] + [ SHIFT ] + [ g ] here. Two special cases here are moving to the first line with [ ESC ] + [ 1 ] + [ G ] and [ ESC ] + [ G ] for the end of the file.
Now – lets discuss more moving options. With [ ESC ] + [ H ] and With [ ESC ] + [ M ] and With [ ESC ] + [ L ] you will move to the HIGH position in the window or MEDIUM or LOW respectively. Also can be written as [ ESC ] + [ SHIFT ] + [ h ] and [ ESC ] + [ SHIFT ] + [ m ] and [ ESC ] + [ SHIFT ] + [ l ] shortcuts.
Other option is to ‘move’ contents of a file up with [ ESC ] + [ CTRL ] + [ e ] and down with [ ESC ] + [ CTRL ] + [ y ] keys.
… and also another option to forward a screen use [ ESC ] + [ CTRL ] + [ f ] and backward a screen use [ ESC ] + [ CTRL ] + [ b ] respectively.
Another option for moving in a file is using [ { ] and [ } ] keys – which can also be written as [ ESC ] + [ SHIFT ] + [ [ ] and [ ESC ] + [ SHIFT ] + [ ] ] – they move between next and previous paragraphs.
To delete current line you will use dd command. You can also remove multiple lines with {number}dd command. For example to remove next 10 lines You would use 10dd command. To expand that example – it would be like [ ESC ] + [ 1 ] + [ 0 ] + [ d ] + [ d ] keys pressed.
While dd removes entire line ([ ESC ] + [ d ] + [ d ]) – you may also use d$ command ([ ESC ] + [ d ] + [ $ ]) to remove everything from the cursor position to the end of the line and d^ ([ ESC ] + [ d ] + [ ^ ])to remove everything from cursor position to the beginning of the line.
You can also delete everything from current cursor position to the end of the file with [ ESC ] + [ d ] + [ G ] (or [ ESC ] + [ d ] + [ SHIFT ] + [ g ] if you prefer) and delete everything from current cursor position to beginning of the file with [ ESC ] + [ d ] + [ 1 ] + [ G ] (or [ ESC ] + [ d ] + [ 1 ] + [ SHIFT ] + [ g ] if you prefer).
Copy/Cut/Paste
The cut or copy and paste work a lot different then vi(1) but its usable after getting used to it.
To copy anything we use [ y ] key. To copy entire line it would be [ ESC ] + [ y ] + [ y ] or with {NUMBER} to copy multiple lines – like [ ESC ] + [ 7 ] + [ y ] + [ y ] to copy seven lines. Its generally the same as deleting lines earlier with [ d ] letter … and that serves as the cut operation. With [ ESC ] + [ 7 ] + [ y ] + [ y ] keys you will delete next seven lines and now you can move cursor somewhere else in the file and paste all these 7 lines with [ p ] letter – as [ ESC ] + [ p ] keys. The same paste work for lines copied with [ y ] letter.
You can also copy a word with [ ESC ] + [ w ] + [ y ] … or six words with [ ESC ] + [ 6 ] + [ w ] + [ y ]. Paste is again with p letter.
You can also copy from current position of cursor to beginning of the line with [ ESC ] + [ y ] + [ ^ ] or end of line with [ ESC ] + [ y ] + [ $ ] … and also copy from current cursor position to beginning of the file with [ ESC ] + [ y ] + [ 1 ] + [ G ] (or [ ESC ] + [ y ] + [ 1 ] + [ SHIFT ] + [ g ] alternatively) and copy from current cursor position to end of the file with [ ESC ] + [ y ] + [ G ] (or [ ESC ] + [ y ] + [ SHIFT ] + [ g ] alternatively).
I believe now you start to see the pattern in which way all the commands interact with each other … and do not worry if you do not remember them now – so called muscle memory will come in time.
Also if you type [ p ] multiple times – the buffer will be pasted as many times.
You can also cut a single character with [ x ] key – and then paste it with [ p ]
If you do not have a ‘space’ (would like to just add newline) use [ o ] command – which will add newline below the line with the cursor. There is also [ O ] (or [ SHIFT ] + [ o ] alternatively) which will add newline above the line with cursor.
Real World Example
The vi(1) editor is really liked by sysadmins and not without a reason.
Lets take some real life example – a host ident mismatch in the ~/.ssh/known_hosts file.
You try to login to some host and …
root@blackbox:~ # ssh 10.0.0.99
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:N0+Spy0MaNnkoJHNvtVsls8DyBRYkBqMbszvTMN+/2M.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:8
Host key for 10.0.0.99 has changed and you have requested strict checking.
Host key verification failed.
The solution to that problem in vi(1) editor is just 8GddZZ – yes – only that.
root@blackbox:~ # vi ~/.ssh/known_hosts
… and now You type 8GddZZ – the problematic line is gone – and You did not even needed to hit [ ENTER ] key – file was written and vi(1) editor quit to shell.
Comment Out Multiple Lines
One of the nice – often unknown – features of vi(1) editor is the ‘repeat’ command. Its done by ‘DOT’ key. This [ . ] key. Like the ‘dot’ in ATARI 2600 Adventure game … also explained in the Ready Player One (2018) movie.
One of the real world usage examples of using that in vi(1) is commenting out multiple lines of config/code in a file.
What I did in that short ‘comment out’ session was:
- Navigate to the first position of the line.
- Use [ SHIFT ] + [ r ] keys to enter ‘overwrite’ mode.
- Type # character.
- Hit [ ESC ] key to switch to COMMAND mode.
- When in COMMAND mode – navigate with cursor to place when you want to repeat that action and hit [ . ] (dot) key.You can also do reverse action – uncomment – just use [ SPACE ] character instead of # one.
Uppercase and Lowercase Fast Switch
The vi(1) also comes with fast way to switch between uppercase/lowercase characters – and its done in COMMAND mode with [ ~ ] (tilde) key.
Example usage below.
Insert Mode and Editing
In the INSERT mode you generally input characters. Typically you enter this mode by pressing [ INSERT ] or [ i ] key – to start entering characters in the cursor place or with [ a ] to do that after the cursor.
You may also want to use replace instead – which is enabled with [ R ] (or [ SHIFT ] + [ r ] using other notation).
You can also start from new line below current one with [ o ] or above one with [ SHIFT ] + [ O ] (or [ SHIFT ] + [ o ] way).
While you are typing – and made any mistake – you can use UNDO function with [ ESC ] + [ u ]. If you use vim(1) (or one of its clones nvim(1) fork) you can also use REDO with [ ESC ] + [ CTRL ] + [ r ] shortcut.
You may also insert/add result of a command with r!${COMMAND} syntax. For example – lets assume you want to add current date into your file – place the cursor in which you want to have the date added – then in COMMAND mode type r!date +%Y/%m/%d and hit [ ENTER ] and you have 2024/09/23 added to your file.
There are two more things I would like to share that often help working with vi(1) editor. One is a shortcut to move lower line at the end of the current line – and that can be achieved in COMMAND mode with [ SHIFT ] + [ j ] keys.
shift j
Another one – unfortunately works in vim(1) and not in vi(1) – is ‘cloning’ the upper characters – one by one – into current line. This can be done in INSERT mode with [ CTRL ] + [ y ] keys.
How to Quit
While there are multiple jokes about trying to exit vi(1) makes a great random number generator … or that its a great escape room type of game – there are many ways how to exit it.
Generally – after you made your edits – You just want to write the contents to the file and exit. Its being done in COMMAND mode with
:𝚡 or :wq or ZZ (notice lack of : before ZZ command). Sometimes – when editing files that are read only – but You know what You are doing and still want to overwrite the file (assuming that you have permission to do so) – use :wq! for that or :𝚡.
Not really about exit – but if You just want to write contents to file and continue editing then use :w (or :w to overwrite read only files).
Alternatively – if you made some changes – but want to exit vi(1) without changing the file – use :q! instead.
Search and Replace
Generally search is done with [ / ] key in COMMAND mode – to search for enable switch to COMMAND mode and type /enable and then hit [ ENTER ]. It will take you into first occurrence of enable from the place where you started searching for it. Now – you may skip to next and previous search results with [ n ] and [ N ] (or [ SHIFT ] + [ n ] key) respectively.
You may also do search and replace with :%s/FROM/TO/g syntax. For example to switch every occurrence of YES word into NO word type this in COMMAND mode – :%s/YES/NO/g – and hit [ ENTER ] key.
Additionally in vim(1) you can also highlight a word with [ # ] (or [ SHIFT ] + [ 3 ] using other notation).
Visual Mode
While vi(1) only has COMMAND and INSERT modes – the vim(1) also has VISUAL mode.
It is useful mostly for copying and its used like that – You activate VISUAL mode with [ v ] key while being in COMMAND mode (or [ ESC ] + [ v ] to simplify) – then you can move the cursor and by moving this cursor you also make selection – move to the end of your selection – then hit [ y ] key (yank). Now you have all that selection copied into buffer – and you can paste that as usual – with [ p ] letter.
There is also integration done – that if You select text in vim(1) with mouse – then it will automatically enable VISUAL mode – some people do not like that – but its easy to disable that behavior – so vim(1) will behave like vi(1) here – with set mouse-=a in the ~/.vimrc config file.
Config Files
The config file for vi(1) is ~/.exrc file – and I suggest using these options below as a start.
% cat ~/.exrc
set noautoindent
set number
set ruler
set tabstop=2
set nowrapscan
set wrapmargin=0
set leftright
The vim(1) config file is located at ~/.vimrc place – some startup suggestion below.
% cat ~/.vimrc
set nomodeline
set nocompatible
set backspace=indent,eol,start
set autoindent
set nobackup
set cursorline
set number
set nowrap
set history=64
set ignorecase
set showcmd
set incsearch
set hlsearch
set tabstop=2
set shiftwidth=2
set softtabstop=2
set shiftwidth=2
set expandtab
set ruler
set mouse-=a
let skip_defaults_vim=1
set viminfo=""
syntax on
Tricks
For vim(1) – when using autoindent option – and you want to paste some longer text – it will also be autoidented – to prevent that one can type :set paste in COMMAND mode – and after successful paste – switch back to normal mode with :set nopaste command … which takes some time.
Instead – to achieve the same – you can do that in COMMAND mode:
:r!cat
// paste here everything you needed
^D
Done. The ^D is pressing the [ CTRL ] + [ d ] shortcut.
IDE Replacement
If you want to advance your vim(1) config into IDE like setup – check mine older Perfect Neovim Ansible Setup article – which covers both Neovim and classic vim(1) editors.
Alternatives
Not all people get used to (and like) vi(1) and its successors – and its OK. There are plenty of solutions to choose from.
To start from the most basic ones – there is great simple small editor in the FreeBSD Base System called ee(1) called Easy Editor. It has all its shortcuts described at the top – so You will have some hints how to use it.
If you want something more colored and powerful – then check editors/micro from FreeBSD Ports.
# pkg install -y micro
… and some very quick look at it.
… and while I really like vi(1) world – I also often use Geany editor.
# pkg install -y geany
… and its brief looks below.
Internals
I used multimedia/recordmydesktop to record the xterm(1) window and then used multimedia/ffmpeg to convert recorded movie into GIF file. I also used x11/wmctrl-fork to get X11 window id for multimedia/recordmydesktop argument.
# pkg install -y multimedia/recordmydesktop multimedia/ffmpeg x11/wmctrl-fork % wmctrl -l | grep DRACULA 0x0074001e 2 w520.local xterm | DRACULA % recordmydesktop --fps 30 --no-sound --overwrite --windowid 0x0074001e % ffmpeg -i out.ogv -y -vf 'fps=30,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse' -loop 0 vi.line.up.clone.gif
Hope that helps.
EOF
Pingback: 使用Vi(1)编辑器 - 偏执的码农
It is best not to get hung-up on the hjkl cursors. If you use them for moving around, you’ve misunderstood what it is that makes vi powerful – especially if you’re relying on key repeat by pressing and holding them down. Treat them like any other key combination you learn and add them to your repertoire individually. I regularly use them in combinations like c2l, dvj, d2k and so on but there are also times when I can’t see a simple way to target where I want to move and I’ll just be lazy and press and hold a cursor key. For a new user, there’s far more value in learning things that allow you to move greater distances with one key like like ) } f t , and ;. The cursors still work – they even work with c, d and numbers but once you’ve learnt enough vi to start doing that it’s time to introduce your fingers to h, j, k and l.
LikeLiked by 1 person
Thanks, good insight from You here.
LikeLike
Great article. I used to use vim as my main editor some years ago and I must confess, that – using Devuan/Debian – I now use nano for the most time. But I still use vim from time to time, especially when working on bigger files.
As a fan of minimalist software I’m also interested in other, lightweight vi variants. Of course, there is nvi and nvi2. On Slackware (also many years ago) I used elvis. And recently I discovered neatvi, which is very small but nonetheless can handle UTF-8 and has syntax higlighting (but has no cursor key support, hjkl movement only).
LikeLiked by 1 person
This is a short tutorial I wrote 33 years ago for my non-vi literate friends. In those days I ran it on my PDP-11, YMMV. http://galassi.us/~michael/vi.txt
-michael
LikeLiked by 1 person
Thanks, added to nearest Valuable News episode 🙂
LikeLike
Pingback: Valuable News – 2024/09/30 | 𝚟𝚎𝚛𝚖𝚊𝚍𝚎𝚗