103.8 Basic file editing¶
Weight: 3
Candidates should be able to edit text files using vi. This objective includes vi navigation, vi modes, inserting, editing, deleting, copying and finding text. It also includes awareness of other common editors and setting the default editor.
Objectives
- Navigate a document using vi.
- Understand and use vi modes.
- Insert, edit, delete, copy and find text in vi.
- Awareness of Emacs, nano and vim.
- Configure the standard editor.
Terms
vi, /, ?, h, j, k, l, i, o, a, d, p, y, dd, yy, ZZ, :w!, :q!, EDITOR
Introduction¶
As with any other tool, we have a wide range of choices when it comes to text editors. One of the most common and super powerful choices is the vi editor. It is pre-installed on all major Linux distributions, and knowing it will let you edit your files in all environments, whether a remote server over SSH, a coding environment on your desktop machine, or a CyberDeck machine with a minimal keyboard. Its only drawback might be its slow learning curve, but after a one hour session with it you will manage to find your way in vi.
There is an Improved version of vi which is called VIMproved or vim. Sometimes that is what you will find on your system, and sometimes the vi command is aliased or linked to vim. Let's check this on our system (Ubuntu 22.04):
nagato@funlife:~$ whatis vi
vi (1) - Vi IMproved, a programmer's text editor
nagato@funlife:~$ whereis vi
vi: /usr/bin/vi /usr/share/man/man1/vi.1.gz
nagato@funlife:~$ whatis vim
vim (1) - Vi IMproved, a programmer's text editor
nagato@funlife:~$ whereis vim
vim: /usr/bin/vim /etc/vim /usr/share/vim /usr/share/man/man1/vim.1.gz
nagato@funlife:~$ vi --version
VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Aug 23 2022 20:18:58)
Included patches: 1-242
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org
Huge version without GUI. Features included (+) or not (-):
+acl +file_in_path +mouse_urxvt -tag_any_white
+arabic +find_in_path +mouse_xterm -tcl
+autocmd +float +multi_byte +termguicolors
+autochdir +folding +multi_lang +terminal
-autoservername -footer -mzscheme +terminfo
-balloon_eval +fork() +netbeans_intg +termresponse
+balloon_eval_term +gettext +num64 +textobjects
-browse -hangul_input +packages +textprop
++builtin_terms +iconv +path_extra +timers
+byte_offset +insert_expand -perl +title
+channel +ipv6 +persistent_undo -toolbar
+cindent +job +popupwin +user_commands
-clientserver +jumplist +postscript +vartabs
-clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +vim9script
+cmdline_hist +langmap -python +viminfo
+cmdline_info +libcall +python3 +virtualedit
+comments +linebreak +quickfix +visual
+conceal +lispindent +reltime +visualextra
+cryptv +listcmds +rightleft +vreplace
+cscope +localmap -ruby +wildignore
+cursorbind -lua +scrollbind +wildmenu
+cursorshape +menu +signs +windows
+dialog_con +mksession +smartindent +writebackup
+diff +modify_fname +sodium -X11
+digraphs +mouse -sound -xfontset
-dnd -mouseshape +spell -xim
-ebcdic +mouse_dec +startuptime -xpm
+emacs_tags +mouse_gpm +statusline -xsmp
+eval -mouse_jsbterm -sun_workshop -xterm_clipboard
+ex_extra +mouse_netterm +syntax -xterm_save
+extra_search +mouse_sgr +tag_binary
-farsi -mouse_sysmouse -tag_old_static
system vimrc file: "/etc/vim/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/share/vim"
Note what the first two commands prove. whatis vi returned "Vi IMproved", the description for vim, even though the command typed was vi. On this Ubuntu system, vi is really vim wearing the old name. The bottom of that output is also useful: it lists exactly where vim looks for its config files, /etc/vim/vimrc for the system and $HOME/.vimrc for the user.
To edit a file with vi, just give the file name to it:
You can jump straight to a line when opening:
That opens the file with the cursor already on line 9. A plus sign with no number puts the cursor on the last line.
The screen itself: the whole terminal shows the file, with a footer line giving the cursor position and a tilde ~ marking where the file ends. Those tildes are not part of your file, they are just empty space below it.
vi modes¶
vi works in two modes:
- Command mode is where you go around the file, search, delete text, copy and paste, replace, and give other commands to vi. Some commands start with a
:and some are only a keypress. - Insert mode is where what you type goes into the file at the cursor's position.
To switch to Command mode, press the ESC key. To go back to Insert mode, you can use several commands, but one common one is pressing the i key.
Command mode is also called normal mode, and this is the name you will see in vim's own documentation. The two names mean the same thing.
This one idea is the whole reason vi confuses beginners, so here it is drawn out:
press i, a, o, s, c ...
------------------------->
NORMAL MODE INSERT MODE
(vi starts here) (typing goes
keys are commands <----------------- into the file)
press ESC
In normal mode, pressing "d" does not type a d.
It deletes.
vi starts in normal mode, not insert mode. Typing a sentence straight after opening a file will not add text, it will run a string of commands.
Moving the cursor¶
To move around a text file, use these keys in Command mode:
| key | function |
|---|---|
| h | One character to the left (only current line) |
| j | One line down |
| k | One line up |
| l | One character to the right (only current line) |
| w | Next word on the current line |
| e | Next end of word on the current line |
| b | Previous beginning of the word on the current line |
| Ctrl-f | Scroll forward one page |
| Ctrl-b | Scroll backward one page |
Typing a number before most commands will repeat the command that many times, so 6h will go 6 characters to the left.
The four movement keys sit under your right hand on a QWERTY keyboard, which is why they were chosen:
h j k l
| | | |
| | | +--- right
| | +------ up
| +--------- down
+------------ left
h is on the far left, l is on the far right.
j has a descender, like a downward arrow.
Several more movement keys:
0and$go to the beginning and end of the line1GandGgo to the beginning and end of the document(and)go to the beginning and end of the sentence{and}go to the beginning and end of the paragraphWjumps a word including punctuation, where plainwstops at it
Jumping around¶
| key | function |
|---|---|
| G | With no number, will jump to the end. 10G will jump to line 10 |
| H | 5H will go to the 5th line from the top of the screen |
| L | 3L will move the cursor to the 3rd line from the last line of the screen |
Editing text¶
These commands during command mode will help you enter, edit and replace text:
| key | function |
|---|---|
| i | Enter the insert mode |
| a | Enter the insert mode after the current position of the cursor |
| r | replace only one character |
| o | open a new line below the cursor and go to the insert mode |
| O | open a new line above the cursor and go to the insert mode |
| c | clear to a location and go to the insert mode, then replace up to there and then normal insert (cw will overwrite the current word) |
| d | delete. You can mix with w (dw) to delete a word. Same as cw but dw does not go to the insert mode |
| dd | Delete the current line |
| x | Delete character at the position of the cursor |
| p | Paste the last deleted text after the cursor |
| P | Paste the last deleted text before the cursor |
| xp | swaps the character at the cursor position with the one on its right |
The xp trick shows how vi is meant to be used. x deletes one character and remembers it, p pastes it back after the cursor. Two single letter commands combine into "swap these two letters", which is the fastest way to fix a typo like teh.
The copy commands, which the objective's term list requires:
yandyycopy, called yank, either a selection or the whole linevandVstart a selection, either from the current character or the whole linesandSerase the character or the whole line and enter insert modeuundo,Ctrl-RredoIenter insert mode at the start of the line,Aat the end of the line
How commands combine, which is the real skill:
[count] [command] [movement]
3yy copy this line and the two below it
d5w delete this word and the next four
cw change the current word
dw delete the current word
vey select to the end of the word, then copy it
v3ey select to the end of the third word, then copy it
Two more features worth knowing. Registers let you hold several copied pieces at once. "ly copies into register l, and "lp pastes it back. A register lasts until the session ends.
Marks let you jump between places. Press m then a key to set a mark at the cursor, then ' and the same key to come back to it.
And macros, which record a key sequence for replay. Press q then a register key to start recording, do the actions, then q again to stop. Press @ and the register key to replay it. Macros are lost when the session ends unless you put them in ~/.vimrc.
Searching¶
| key | function |
|---|---|
| / | Search forward (/happiness will find the next happiness) |
| ? | Search backward |
| n | repeat previous search. You can also use / and ? without any parameters |
Search wraps around to the top once the bottom of the file is reached.
The search accepts a regular expression, not just plain text, so everything from 103.7 works here.
Exiting¶
It is always funny when you see someone entering vi and not knowing how to exit. Learn these and prevent the laughter:
| key | function |
|---|---|
| :q! | Quit editing without saving, the escape route after any mistake |
| :w! | Write the file, whether modified or not. Attempts to overwrite existing files, or read-only or other unwritable files |
| :w myfile.txt | Write to a new name |
| ZZ | Exit and save the file if modified |
| :e! | Reload the file from disk |
| :! | Run a shell command |
Entering a colon (:) during command mode will move the cursor to the bottom of the screen and vi will wait for your commands. Press ESC to return to the normal command mode.
The exclamation mark in most commands says "I know what I am doing". It will write to read-only files if you have access, and will exit without asking.
It is possible to combine commands. For example you can combine :w and :q and just say :wq (write and exit).
want to leave without saving -> :q!
want to save and leave -> :wq or ZZ
want to save, stay open -> :w
ZZ is a normal mode command with no colon, while :wq is a colon command. They do the same thing.
A few more colon commands:
:s/REGEX/TEXT/greplaces every match on the current line. It uses the same syntax assed, addresses included, so it ties directly back to 103.7.:xor:exitsaves and exits, but only writes if something actually changed:visualreturns to normal mode:qquits when there are no unsaved changes
Real world use for :!: you are editing a config file and need to check something. Typing :!ls /etc/nginx runs the command, shows the output, and drops you back into the file where you were.
help¶
You can always ask for help with :help or :help subject. This way vi will open a help text which you can search with / just like any other text. Close it with :q.
There is also vimtutor, a separate command on systems using vim. It opens a step by step guide that is itself an editable file, so you practise the commands on the tutorial text as you read it.
Other editors¶
You can also use other editors if you want. One easy to use and common option is nano, and some other choices are micro, emacs (full featured) and neovim (an update to vim).
The objective names two. GNU nano is the simple alternative. The key difference from vi is that nano has no modes: every key you press is inserted into the document, and commands are given by holding Ctrl or Meta, where Meta is usually Alt. Its main keys:
Ctrl-6orMeta-Astart a selectionMeta-6copy the selectionCtrl-KcutCtrl-UpasteMeta-Uundo,Meta-EredoCtrl-\replace textCtrl-Tspell check
Emacs sits between the two. Text is inserted just by typing it, as in nano, but navigation uses keyboard commands, as in vi. It goes well beyond editing, working as a development environment that can compile and run programs, and it can also be set up as a mail, news or RSS client.
Default editor¶
The default editor in bash is set using the EDITOR environment variable. You can change it with:
or by adding the above line to the .bashrc file.
There is a second variable, VISUAL, which bash also checks for the same purpose. Use ~/.bash_profile as the place to make the setting permanent.
This matters because other programs open an editor for you. When you run crontab -e, whichever editor EDITOR names is the one that appears. If it is unset, you usually get vi, which is exactly why knowing how to exit vi is a practical skill and not a joke.
Summary¶
I have a Linux system where vi is always installed, so it is the one editor I can count on being there whether I am on my own machine or on a stranger's server over SSH. On most modern distributions the vi command is really vim, the improved version, and I can confirm that with whatis vi. I open a file with vi file.txt, or jump straight to a line with vi +9 /etc/fstab.
The thing that makes vi feel strange is that it has modes. It opens in normal mode, also called command mode, where every key is a command rather than a character. Pressing i, a, o or s switches me into insert mode where typing actually enters text, and Esc takes me back. Once I accept that, the rest follows: h, j, k and l move left, down, up and right, w, e and b move by word, 0 and $ go to the ends of a line, and G goes to the end of the file or to a numbered line when I put a number in front of it.
Editing is built out of small commands that combine. x deletes a character, dd deletes a line, dw deletes a word, yy copies a line and p pastes what was last deleted or copied. Putting a number in front repeats the command, so 3yy copies three lines and d5w deletes five words. u undoes and Ctrl-R redoes. Searching uses / forward and ? backward, n repeats the search, and the pattern is a regular expression rather than plain text. Beyond that, registers let me hold several clipboard entries at once, marks let me jump between saved positions, and macros replay a whole key sequence.
To leave, I use :q! to abandon everything, :wq or ZZ to save and exit, and :w to save while staying in the file. The exclamation mark means "do it anyway". Colon commands also cover :s/find/replace/g, which uses the same syntax as sed, and :! to run a shell command without leaving the editor. If I want something simpler, nano has no modes at all and shows its shortcuts on screen, while emacs is a much larger tool that happens to include an editor. Which one the system opens for me is decided by the EDITOR variable, or VISUAL, which I set with export EDITOR=nano and make permanent by putting that line in ~/.bashrc or ~/.bash_profile.