vi text editor in Linux

  • Post author:
  • Post last modified:August 22, 2023
  • Reading time:17 mins read

vi is a classic text editor that has been available with Unix systems right from the beginning. vi has been a very popular text editor and one can edit files very efficiently using it. In this tutorial, we look at some of the vi commands that make it such a powerful editor.

Since vim (vi-improved) is a superset of vi, and in many cases vi is simply a link to vim, all commands described in this tutorial apply to vim as well.


vi can be started with the command, vi <filename>. For example, if we wish to edit a file, hello.c, we have to open a terminal like gnome-terminal under Linux, and give the command, vi hello.c. Assuming that hello.c did not exist in the current working directory and we wished to create a new file, we see something like this,

"hello.c" [New File]

Figure: vi start screen

The tilde's indicate an empty buffer. Editing is done in a buffer in memory and one can write the contents of the buffer to the underlying file, which is hello.c in this case. The last line, the status line, shows the name of the file being edited.


vi has three modes of operation, which are command, insert and ex modes. The command mode is the default mode of vi. When you give the command, vi <filename>, it starts in the command mode. And, no surprises here, in the command mode you can give commands to the editor. The second mode is the insert mode, in which you can type (insert) text in the file. Actually, you insert text in the buffer, which you can save into the file by giving one of the relevant commands. You can go to the insert mode from the command mode by the giving the insert command, i. Once. in the insert mode, you can keep on typing text, using the necessary keys on the keyboard and correcting typing mistakes using the backspace key. At any time, you can return to the command mode by pressing the Escape key. And the third mode, the ex mode can be entered by pressing the : key. In the ex mode, you can give commands to save a file, read another file in the buffer, execute a shell command, fork a new shell, quit the editor, etc.


As mentioned above, the command mode is the default mode of the editor. In this mode , a user can type in commands to edit the contents of the buffer. The commands are quite short, a few characters long. The commands are silently received and executed by the vi editor; they are not echoed back. The editor starts in the command mode and a user can return to command mode from the other two modes anytime by pressing the Escape key.

A vi command can be optionally preceded by a number indicating the number of times that command should be executed. That is, the command can be entered as,

[count] <command>

Commands are character based and are not to be terminated by ENTER. Let's look at some commands,

Cursor movement

Cursor Movement is an important concept in vi know-how. Cursor Movement is defined as the text that would lie under the cursor as the cursor moves from current position to the new position as a result of a cursor movement command. Some of the cursor movement commands are,

vi – Cursor Movement commands
^F, Page DownScroll forward by one page
^B, Page UpScroll back by one page
^DScroll down by half page
^UScroll up by half page
h, left arrowmove one character position left
j, down arrow, ENTERmove one line down
k, up arrowmove one line up
l, right arrow, spacebarmove one character position right
0Go to the beginning of line
$Go to the end of line
<line number>GGo to <line number>
:<line number>Go to <line number>
GGo to the end of file
%Go to matching [], () or {}
'<bookmark>Go to <bookmark>
wGo to the next word
WGo to the next blank delimited word
bGo to the beginning of word
BGo to the beginning of blank delimited word
/<string>ENTERIf the string occurs in text, go to first occurrence after cursor
/ENTERgo to next occurrence of the last searched string
?<string>ENTERIf the string occurs in text, go to fist occurrence before cursor
?ENTERgo to previous occurrence of the last searched string

When a cursor movement command is given alone, by itself, it results in movement of the cursor from one location to another in vi's buffer. However, some editing commands take cursor movement as an argument. These commands operate on text referenced by the indicated cursor movement. For example, suppose your cursor is on a brace and you give the command d%, where d is the delete command and % means a cursor movement from the brace under the cursor to the matching brace. This means delete text as per cursor movement and would result in deletion of text between the brace under cursor and the matching brace.

The % command is particularly useful in finding matching braces in programs. If you have missed a brace and the compiler is giving a voluminous error listing, the % command can be used to locate the brace without the matching opposite brace.

Having got an idea about navigating in a file, it is time to insert some text in the file.


You can enter the insert mode by typing the command i. Once in the insert mode, you can type text, using backspace key for corrections. When you are done with inserting text, press the Escape key to come out of the insert mode. Inserting a C program in our hello.c file, we have

#include <stdio.h>     
#include <stdlib.h>    

int main (int argc, char **argv)      
    printf ("Hello alpha\n");        
    printf ("Helo beta\n");          
    printf ("Hello gamma\n")         
    printf ("Hello delta\n")         
    printf ("Hello Epsilon\n")       
"hello.c" 11 lines, 224 characters

Figure: After inserting a C program text in the buffer

There are some typing mistakes in the above file, which we will correct during the course of this tutorial. The insert commands are,

vi – text insertion commands
iinsert text at the cursor position
IInsert text at the beginning of line
aappend text after the cursor position
AAppend text at the end of line
oOpen a new line below the cursor for inserting text
OOpen a new line above the cursor for inserting text

If you use a graphical user interface such as the GNOME desktop, you can paste text from the clipboard. For this, first, use a cursor movement command to get to the desired position in the buffer. Then, get into the insert mode using the i command. Using mouse, paste the text from the clipboard. Finally, press Escape to complete the operation.


In an earlier section, we looked at some of the cursor movement commands for navigating in the buffer. Now we look at some more commands that will help us in editing text in the vi's buffer.

vi – editing commands
xdelete character under the cursor
DDelete text from the cursor to the end of line
dddelete the entire line
d<cursor movement>delete from cursor to location indicated by the <cursor movement>
c<cursor movement>change from cursor to location indicated by the <cursor movement>
rreplace one character
RReplace text on current line from cursor till Escape is pressed
m<bookmark>Place a bookmark on the current line.
<bookmark> is a single alphabetic character
.repeat the last command
~toggle case of character under cursor
JJoin current line with the next line
uUndo the last command
^Gdisplay the current line number and file status

With these commands, we can correct the errors in our hello.c file. The first error is a missing l (el) in the line printf ("Helo beta\n"); . We use the cursor movement commands to reach the l (el) in Helo, press i to get into the insert mode type the character l (el) and then press Escape to come out of the insert mode. The next three lines have missing semicolons. We go down one line, press A for append at the end of line, type a semicolon and press Escape. For putting a semicolon on next two lines, the last command is to be repeated. So we come down a line and press .. And we repeat it one more time to put a semicolon on the last line before the brace.

The syntax errors have got removed, but it will be good if alpha, beta, gamma and delta start with an uppercase character. This is easily done using the tilde command. Place the cursor on a in alpha and press ~ for the tilde command. This toggles the case. The same is repeated for the next three lines. The resulting hello.c file looks like this,

#include <stdio.h>     
#include <stdlib.h>    

int main (int argc, char **argv)      
    printf ("Hello Alpha\n");        
    printf ("Hello Beta\n");          
    printf ("Hello Gamma\n");         
    printf ("Hello Delta\n");         
    printf ("Hello Epsilon\n");       
"hello.c" 11 lines, 228 characters


The power of vi becomes evident in commands for copy and paste. vi provides you with 26 registers named a through z for this purpose. So you can copy blocks of text in some of these registers and paste the text at desired locations in the file. While 26 registers are a bit too many, it is quite common to use three or four registers to copy that many blocks of text for pasting at different locations in a file.

Text is copied in a register using the yank command. The command is


where, <register-name> is any one of the characters a – z. The command places the entire text as referenced by the <cursor-movement> in the relevant register. Also,


puts the current line into the <register-name>. Preceding this with a count places that may lines in the relevant register. For example, the command,


places the next 5 lines, into the register a.

The yanked text can be pasted by using the Put command, p. The command is,


For example if you had yanked text in the register a, you can use cursor movement to get to location where you wish to paste the contents of a and give the command,


to paste the contents of the register below the current cursor position.

Apart from the 26 named registers mentioned above, there is a default unnamed register. In all the above mentioned commands, you can skip the <register-name> and use the default register. For example,


copies the current line into the default register and the command,


pastes the line from the default register below the current cursor position. While using the default register, there can not be a delete operation between yank and put. Whenever you delete text, vi puts the deleted text in the default register. So if there is a delete between yank and put using the default register, the deleted text would overwrite the contents of the default register.

vi ex MODE

ex mode commands start with a colon (:) and are echoed on the last line of the terminal window. Some of the commands are,

vi – ex mode commands
:wwrite buffer contents to the file
:w <filename>write buffer contents to <filename>
:w! <filename>force write buffer contents to <filename>
:qquit vi
:q!Force quit, without saving the modified buffer contents
:e <filename>load contents of <filename> into vi's buffer
:vi <filename>load contents of <filename> into vi's buffer
:e #load the previous file
:vi #load the previous file
:e!reload the current file (discarding modifications)
:vi!reload the current file (discarding modifications)
:nGo to next file (if vi has been started with multiple file names)
:m,ns/string1/string2/For lines in the range m-n substitute first occurrence of string1 with string2
:m,ns/string1/string2/gFor lines in the range m-n substitute all occurrences of string1 with string2
:m,ns/string1/string2/gcFor lines in the range m-n substitute all occurrences of string1 with string2 with confirmation
:r <filename>read <filename> below the current cursor position
:!<shell-command>execute the <shell-command>
:shfork a new shell

The substitute command works for the line number range m through n. Special line numbers are . for the current line and $ for the last line.


1. William Joy and Mark Horton,
An Introduction to Display Editing with Vi

See also


Karunesh Johri

Software developer, working with C and Linux.
0 0 votes
Article Rating
Notify of
Inline Feedbacks
View all comments