A Gentle Introduction To vi
Chapter 12
A classic tale involves someone inquiring about directions to Carnegie Hall in New York City:
Visitor: Excuse me, how can I reach Carnegie Hall?
Passerby: Practice, practice, practice!
Much like mastering a musical instrument, learning the Linux command line isn't a skill acquired quickly. It demands years of dedicated practice. In this chapter, we'll delve into vi (pronounced “vee eye”), a fundamental program in the Unix tradition. vi is infamous for its complex user interface, but observing an expert at the keyboard is akin to witnessing an artistic performance. We won't achieve mastery in this chapter, but by the end, we'll at least know how to play a basic tune like “chopsticks” in vi.
Why We Should Learn vi
viIn this era of user-friendly graphical editors and accessible text-based options like nano, what's the value in learning vi? Here are three compelling reasons:
viis consistently available, making it a lifesaver in scenarios where graphical interfaces aren't accessible, like on remote servers or local systems facing configuration issues. Whilenanogains popularity, it isn't universally present. The POSIX standard mandatesvi's existence for Unix system compatibility.viis nimble and swift. It's often quicker to launchvifor tasks than navigating menus to find and load a larger graphical text editor. Moreover,viprioritizes typing speed, allowing proficient users to seamlessly edit without lifting their fingers from the keyboard.There's a certain reputation in the Linux and Unix community associated with vi proficiency. Embracing
vican help avoid the perception of being inexperienced or reliant solely on simpler editors.
A Little Background
The initial iteration of vi was crafted in 1976 by Bill Joy, a University of California at Berkeley student who later co-founded Sun Microsystems. vi's name stems from "visual" since it was designed for editing on video terminals featuring a movable cursor. Before visual editors, line editors worked on one line of text at a time. They required specifying changes by directing the editor to a specific line and detailing the alteration, like adding or deleting text. Visual editing became feasible with the introduction of video terminals, departing from printer-based terminals like teletypes. vi actually integrates a robust line editor named ex, allowing us to employ line editing commands within vi.
Most Linux distributions don't include the original vi; instead, they incorporate an enhanced alternative known as vim (short for "vi improved"), developed by Bram Moolenaar. vim represents a significant advancement over traditional Unix vi and is typically linked (or aliased) to the name vi on Linux systems. Throughout our discussions, we'll operate under the assumption that the vi program refers to vim.
Starting And Stopping vi
viTo start vi, we simply enter the following:
[me@linuxmachine ~]$ viAnd a screen like this should appear:
Similar to our earlier experience with nano, the initial step to grasp is how to exit. Exiting involves entering the following command (keep in mind that the colon character is integral to the command):
Once the command is executed, the shell prompt should reappear. If vi persists and won't exit, typically due to unsaved changes in a file, we can emphasize our intent to exit by appending an exclamation point to the command:
Compatibility Mode
In the provided example startup screen (from Ubuntu 8.04), we notice the statement "Running in Vi compatible mode." This indicates that vim operates in a mode closer to vi's standard behavior rather than its enhanced vim behavior. For the purposes of this chapter, we aim to use vim with its enhanced capabilities.
To achieve this, you have several options:
Try executing vim instead of
vi.If successful, consider adding an
alias vi='vim'to your.bashrcfile.Alternatively, apply this command to include a line in your vim configuration file:
Various Linux distributions package vim differently. Some default installations include a minimal vim version with limited features. During the subsequent exercises, you might encounter missing features. In such cases, install the complete version of vim to ensure access to all functionalities.
Editing Modes
Let's initiate vi once more, but this time, we'll provide it with the name of a non-existent file. This is the method to generate a new file using vi:
If all goes well, we should get a screen like this:
The tilde characters at the start (~) signal that the line is devoid of any text, confirming that our file is currently empty. Refrain from entering any text at this point!
The second crucial aspect to understand about vi (following the exit process) is its modal nature. Upon startup, vi opens in command mode. In this mode, nearly every keystroke represents a command. If we were to start typing immediately, vi would interpret it as commands, potentially leading to chaos and a disorganized file.
Entering Insert Mode
To include text in our file, we need to switch to insert mode. This requires pressing the i key. Following this action, if vim operates in its standard enhanced mode (this won't display in vi compatible mode), you should observe the following at the bottom of the screen:
Now we can enter some text. Try this:
To exit insert mode and return to command mode, press the Esc key.
Saving Our Work
To preserve the recent modification made to our file, we need to input an ex command while in command mode. This can be accomplished effortlessly by pressing the : key. Following this action, a colon character should surface at the bottom of the screen:
To write our modified file, we follow the colon with a w then Enter:
The file will be saved onto the hard drive, and a confirmation message should appear at the bottom of the screen, resembling this:
Tip
When you explore the vim documentation, you'll observe that, somewhat confusingly, what's termed command mode elsewhere is referred to as normal mode in vim, while ex commands are labeled as command mode. Stay cautious of this distinction.
Moving The Cursor Around
While in command mode, vi offers a large number of movement commands, some of which it shares with less. Here is a subset:
l or Right Arrow
Right one character.
h or Left Arrow
Left one character.
j or Down Arrow
Down one line.
k or Up Arrow
Up one line.
0 (zero)
To the beginning of the current line.
^
To the first non-whitespace character on the current line.
$
To the end of the current line.
w
To the beginning of the next word or punctuation character.
W
To the beginning of the next word, ignoring punctuation characters.
b
To the beginning of the previous word or punctuation character.
B
To the beginning of the previous word, ignoring punctuation characters.
Ctrl-f or Page Down
Down one page.
Ctrl-b or Page Up
Up one page.
numberG
To line number. For example, 1G moves to the first line of the file.
G
To the last line of the file.
The choice of h, j, k, and l keys for cursor movement in vi stems from the era when not all video terminals included arrow keys. Skilled typists could maneuver the cursor using standard keyboard keys without needing to lift their fingers from the keyboard.
In vi, numerous commands can be initiated with a preceding number, similar to the G command mentioned earlier. This numeric prefix allows us to specify the frequency of executing a command. For instance, inputting 5j instructs vi to move the cursor down five lines.
Basic Editing
The core of editing involves fundamental actions like inserting, deleting, and relocating text through cutting and pasting. vi, in its distinctive manner, accommodates all of these operations. Additionally, vi offers a form of limited undo functionality. While in command mode, pressing the u key prompts vi to undo the most recent change made, proving useful as we experiment with basic editing commands.
Appending Text
vi provides multiple methods to enter insert mode. We've already utilized the i command to insert text.
Let's go back to our foo.txt file for a moment:
Suppose we intend to include text at the conclusion of a sentence. In such a scenario, the i command won't suffice as we can't position the cursor beyond the line's end. vi offers an append command, sensibly labeled as a. By maneuvering the cursor to the line's end and inputting a, vi moves the cursor past the line's end, transitioning into insert mode. This action permits us to append additional text:
Remember to press the Esc key to exit insert mode.
Given that appending text to the end of a line is a common action, vi provides a shortcut to swiftly navigate to the line's end for appending: the A command. Let's experiment with it by adding more lines to our file.
To initiate, let's reposition the cursor to the line's start using the 0 (zero) command.
Then, input A to seamlessly append the subsequent lines of text:
Again, press the Esc key to exit insert mode.
The A command proves more practical as it relocates the cursor to the line's end before activating insert mode.
Opening A Line
There's an alternative method to insert text by "opening" a line. This action introduces a blank line between two existing lines while simultaneously entering insert mode. This process has two variations:
o
The line below the current line.
O
The line above the current line.
We can demonstrate this as follows: place the cursor on “Line 3” then press the o key.
Below the third line, a new line was created, and we entered insert mode. To exit insert mode, use the Esc key. Then, press the u key to undo our recent change.
Now, utilize the O key to open a line above the current cursor position:
Exit insert mode by pressing the Esc key and undo our change by pressing u.
Deleting Text
As anticipated, vi presents several methods to delete text, each involving one of two keystrokes. Initially, the x key deletes a character at the cursor's position. Preceding x with a number specifies the quantity of characters to be deleted.
On the other hand, the d key serves a more versatile purpose. Similar to x, it can be preceded by a number, specifying the deletion's repetition. Moreover, d is always accompanied by a movement command, determining the deletion's scope. Here are a few examples:
x
The current character.
3x
The current character and the next two characters.
dd
The current line.
5dd
The current line and the next four lines.
dW
From the current cursor position to the beginning of the next word.
d$
From the current cursor location to the end of the current line.
d0
From the current cursor location to the beginning of the line.
d^
From the current cursor location to the first non-whitespace character in the line.
dG
From the current line to the end of the file.
d20G
From the current line to the twentieth line of the file.
Position the cursor on the word “It” within the first line of our text. Continuously press the x key until the remaining part of the sentence is deleted. Then, repeatedly press the u key until the deletion is undone.
Let's attempt the deletion once more, this time employing the d command. Once again, relocate the cursor to the word “It” and press dW to delete the word:
Press d$ to delete from the cursor position to the end of the line:
Press dG to delete from the current line to the end of the file:
Press u three times to undo the deletion.
Cutting, Copying, And Pasting Text
The d command not only erases text but also functions as a "cut" operation. Whenever we execute the d command, the deletion is stored in a paste buffer (think of it like a clipboard) that can be retrieved later. To paste the buffer's contents after the cursor, use the p command or use the P command to paste before the cursor.
Similar to d for cutting text, the y command functions as a "yank" or copy operation. Here are a few examples illustrating the combination of the y command with various movement commands:
yy
The current line.
5yy
The current line and the next four lines.
yW
From the current cursor position to the beginning of the next word.
y$
From the current cursor location to the end of the current line.
y0
From the current cursor location to the beginning of the line.
y^
From the current cursor location to the first non-whitespace character in the line.
yG
From the current line to the end of the file.
y20G
From the current line to the twentieth line of the file.
Let's experiment with copying and pasting. Position the cursor on the first line of the text and input yy to copy the current line. Afterward, move the cursor to the last line (using G) and enter p to paste the line below the current line:
Similar to the previous action, applying the u command will revert our modification. While the cursor remains on the last line of the file, input P to paste the text above the current line:
Experiment with various y commands from the table provided earlier to familiarize yourself with their functionalities alongside the behavior of both the p and P commands. Once finished, restore the file to its initial state.
Joining Lines
vi maintains a strict concept of what constitutes a line. Typically, moving the cursor to the line's end and deleting the end-of-line character to merge it with the subsequent line isn't allowed. vi offers a distinct command, J (distinct from j, used for cursor movement), specifically for joining lines.
When the cursor is positioned on line 3 and the J command is executed, here's the outcome:
Search-And-Replace
In vi, the cursor can navigate based on search queries, whether within a single line or across an entire file. Additionally, vi facilitates text replacements, allowing users to opt for confirmation or make replacements directly.
Searching Within A Line
The f command within vi locates a specified character within a line and shifts the cursor to its next occurrence. For instance, entering fa would move the cursor to the subsequent appearance of the character “a” within the present line. To reiterate a character search within a line, simply type a semicolon.
Searching The Entire File
To navigate the cursor to the subsequent appearance of a word or phrase, vi utilizes the / command, which operates similarly to what we previously learned in the less program. Initiating the / command prompts a / to display at the screen's bottom. Subsequently, input the desired word or phrase to search for, followed by pressing Enter. The cursor will relocate to the next instance containing the search string. To repeat the search, use the n command with the previous search string. Here's an illustration:
Position the cursor on the first line of the file. Enter:
Then press Enter. The cursor will shift to line 2. Following this, input n, and the cursor will proceed to line 3. Executing the n command repetitively will move the cursor down the file until all matches are exhausted. While our search patterns have been limited to words and phrases, vi enables the utilization of regular expressions—a robust means of expressing intricate text patterns. Detailed coverage of regular expressions will be presented in a subsequent chapter.
vi employs an ex command to execute search-and-replace operations, referred to as "substitution" within vi, across a designated range of lines or the entire file. To replace all instances of the word “Line” with “line” throughout the entire file, execute the following command:
Let's dissect this command into its individual components to understand the function of each part:
:
The colon character starts an ex command.
%
Defines the line range for the operation. % serves as a shortcut indicating from the initial line to the final line. Alternatively, the range could have been designated as 1,5 (considering our file comprises five lines), or 1,$, signifying "from line 1 to the file's last line." If the line range is omitted, the operation is executed solely on the current line.
s
Specifies the operation. In this case, substitution (search-and- replace).
/Line/line/
The search pattern and the replacement text.
g
This "global" attribute signifies that the search-and-replace action is executed on every occurrence of the search string within a line. If omitted, solely the first instance of the search string on each line is substituted.
After executing our search-and-replace command our file looks like this:
Another approach involves specifying a substitution command with user confirmation, accomplished by appending a “c” to the end of the command. For instance:
Executing this command reverts our file to its previous state. Yet, before each substitution, vi pauses and prompts us to confirm the replacement with the following message:
Each character enclosed in the parentheses represents a potential choice, outlined as follows:
y
Perform the substitution.
n
Skip this instance of the pattern.
a
Perform the substitution on this and all subsequent instances of the pattern.
q or Esc
Quit substituting.
l
Perform this substitution and then quit. Short for “last.”
Ctrl-e, Ctrl-y
Scroll down and scroll up, respectively. Useful for viewing the context of the proposed substitution.
If you type y, the substitution will be performed, n will cause vi to skip this instance and move on to the next one.
Editing Multiple Files
Editing multiple files concurrently can be quite handy. There might be a need to modify several files or to transfer content from one file to another. vi allows us to open multiple files for editing by specifying them in the command line:
Let's exit the ongoing vi session by typing :wq to save the changes made. Then, we'll create a new file for experimentation in our home directory. We can generate this file by capturing output from the ls command:
Now, let's utilize vi to edit both our existing file and the newly created one:
Upon starting vi, the first file will appear on the screen:
Switching Between Files
To transition from one file to the next in vi, use the following ex command:
To revert to the preceding file, utilize:
However, vi maintains a rule that prevents file switching if the current file holds unsaved changes. To override this and switch files while abandoning modifications, append an exclamation point (!) to the command.
Beyond the switching technique described earlier, vim (and certain vi versions) offer additional ex commands facilitating easier management of multiple files. To view the list of files being edited, utilize the :buffers command. This displays a file list at the bottom of the display:
To transition to another buffer (file), input :buffer followed by the respective buffer number for the desired file. For instance, switching from buffer 1, which contains foo.txt, to buffer 2 containing ls-output.txt can be done by typing:
Subsequently, the screen will display the content of the second file.
Opening Additional Files For Editing
We can also include additional files in our ongoing editing session. Using the ex command :e (abbreviated for “edit”) followed by a filename, we can open another file alongside the current one. Let's conclude our current editing session and return to the command line.
Initiate vi again with just one file:
To incorporate the second file, input:
The content of the second file should now display on the screen. To confirm, the first file remains accessible, as we can ascertain by:
Note
Files loaded via the :e command cannot be switched using either the :n or :N command. To switch between these files, utilize the :buffer command followed by the respective buffer number.
Copying Content From One File Into Another
Frequently, when editing multiple files, there's a need to transfer a segment of one file into another that's under editing. This task is conveniently accomplished using the standard yank and paste commands we've previously used. Allow me to demonstrate. Initially, with our two files open, let's navigate to buffer 1 (foo.txt) by entering:
This command will present us with the following:
Next, move the cursor to the first line, and type yy to yank (copy) the line.
Switch to the second buffer by entering:
The screen will now contain some file listings like this (only a portion is shown here):
Move the cursor to the first line and paste the line we copied from the preceding file by typing the p command:
Inserting An Entire File Into Another
We can also include an entire file into the one we are currently editing. To witness this in action, let's conclude our vi session and initiate a new one, this time with just a single file:
We will see our file listing again:
Move the cursor to the third line, then enter the following ex command:
The :r command (abbreviated for “read”) inserts the designated file before the cursor's position. Our screen's current display should resemble this:
Saving Our Work
Similar to other functionalities in vi, there exist multiple methods to save our edited files. We've previously covered the ex command :w, yet there are additional options that might prove beneficial.
In command mode, entering ZZ will save the current file and exit vi. Similarly, the ex command :wq combines the actions of :w and :q, thereby both saving the file and exiting.
Moreover, the :w command permits the specification of an optional filename, serving akin to a “Save As...” function. For instance, if we're editing foo.txt and wish to preserve an alternate version as foo1.txt, the following command would be used:
Summary
These fundamental skills allow us to execute the majority of text editing tasks necessary for maintaining a standard Linux system. Developing proficiency in using vim regularly will yield long-term benefits. Given the extensive integration of vi-style editors within Unix culture, we'll encounter numerous other programs influenced by its design. For instance, less serves as a prime example of this influence.
Last updated