Learning the vi editor/Print version
From Wikibooks, the open-content textbooks collection
[edit] Learning the vi editor
This book aims to teach you how to use the vi editor, common to many Unix and Unix-like operating systems. ~ ~ ~ ~ ~ "Learning_the_vi_editor" [New file].
The above text is a little example of how the vi editor's screen looks.
[edit] Other sources of information:
- http://www.texteditors.org
- http://thomer.com/vi/vi.html
- An introduction to the vi editor
- Functions of VI editor
- vi Editor Basics
[edit] Getting acquainted
[edit] Introduction
[edit] Overview
vi is a powerful editor that is ubiquitous amongst Unix and Unix-like operating systems, but is available on many other operating systems, even on MS-DOS, Windows and the Macintosh. If not the original vi, there is usually at least a good clone available that runs on your system. Even if you use another editor you must have a passing knowledge of vi as an administrator. Sometimes vi is the only editor available when your computer crashes leaving a minimal system for you to repair.
vi, pronounced like 'vee eye', was originally written by Bill Joy for BSD Unix in Berkeley in 1976 and became quickly part of many vendor-specific versions of the (at that time) original AT&T Unix. It was later directly added to AT&T's System V Unix, too. Bill Joy later went on to co-found Sun Microsystems, and became the company's Chief Scientist at that time. vi stands for visual and was an enormous improvement of the classic Unix editor called ed. ed is a line-editor. If you are still familiar with MS-DOS, then you may know the MS-DOS edlin editor. ed is similar, although more powerful than edlin, which doesn't mean much.
vi also has a line-mode, called ex. In fact, one can argue that the program is indeed two editors in one, one editor called vi, another called ex. It is possible to switch between line and visual mode during editing. It is also possible to choose the mode during startup. However, pure usage of ex is rare. The visual mode is the prevailing mode.
Although vi stands for visual, classic vi is mainly operated via the character keys, and not via the mouse or the cursor keys. Once you are used to this, it becomes extremely convenient, because there is less movement of the hands to the cursor keys or mouse involved.
vi also served as a kind of incubator for Unix's terminal control capabilities. Because of vi's need to control the terminal and the many different types of terminals at that time, the termcap (terminal-capabilities) database was introduced (later replaced with the more flexible terminfo database). vi's internal high-level screen control library was later separated, and became curses - the Unix standard library for CRT screen handling.
[edit] Conventions
- <c>
- A single character, such as 'a' or '1'.
- <ESC>, <Ctrl-[>
- Indicates that the Escape (Esc) key on your keyboard should be pressed, which is identical to Control and '['.
- <CR>
- Indicates that the Return (Enter) key should be pressed.
- <TAB>
- Indicates that the Tabulator key should be pressed
- <Ctrl-x>, <C-x>
- Indicates that the Control key and the 'x' key should be pressed simultaneously. 'x' can be almost any other key on your keyboard.
- <Shift-x>, <S-x>, <X>
- Indicates that the Shift key and the 'x' key should be pressed simultaneously
- <Meta-x>, <M-x>
- Indicates that the Meta or Alt key and the 'x' key should be pressed simultaneously.
- :quit, :q
- An Ex command. started with <:>, followed by the command and ends with <CR>. For many Ex commands there is a long form (:quit) and a short form (:q).
- :set nocompatible
- represents a setting.
- strlen ()
- represents a function.
- /pattern/, ?pattern?
- A Search pattern. Search pattern in vi are regular expressions.
- :ranges/search/replace/options, :global /pattern/ delete
- A Search pattern combined with an Ex command.
All commands in vi are case sensitive.
unix-command(section)
- Sometimes references to Unix commands are used in this book. On first occurrence such a name of a command is written in the typical Unix style. This style consists of the command's name followed by the section of the manual pages in which the command description can be found, in brackets. E.g. sed(1) refers to Unix's sed command which is usually documented in section 1 of the Unix manual pages (sed is the Unix stream editor; a tool for manipulating text without user interaction).
[edit] Getting vi if you don't have it already
If you're running a Unix system, or a Unix-like system (for simplicity from now on we will refer to both as a "Unix system"), such as a BSD or Linux distribution, or even Mac OS X, you're sure to have vi or one of its variants on your system.
If you're running Windows, you can get a version of vi called "vim" or "elvis". If you're on an older Mac OS (pre-OS X) system, you can get MacVim Classic here.
[edit] Noted vi variants
As mentioned, vi has a number of variants. They have been created because vi was only available on rather expensive Unix operating systems. Although vi itself, as well as nvi was created in Berkeley for the free BSD Unix variant, usage of BSD Unix required an original AT&T Unix license (this has later changed, see below). Original vi, for example, used code from AT&T's ed(1) editor.
Over time, BSD replaced many of the original AT&T code up to the point where today there is no such code anymore in BSD, and an original Unix license is no longer needed. As part of the effort to replace all AT&T code in BSD, Keith Bostic undertook the work to create a clone of vi that was free of AT&T code, called nvi. nvi then became BSD's standard vi instead of the original vi. Another vi clone is Elvis, which was written by Steve Kirkendal.
Over time, nvi was enhanced – for example, supporting multiple windows – but originally it was not supposed to be an enhancement, 'just' a pure clone.
BSD's original vi (with the ed code inside) lives on as the vi which is distributed with System V Unix, because AT&T decided a long time ago to take it from BSD and add it to the official Unix. Of course AT&T didn't have a problem with an AT&T Unix license, so they probably never replaced the ed code inside the original vi.
Yet, some find nvi still to be too minimal, and so vim was born. vim (vi-improved), is another effort to extend vi's capabilities. Unlike nvi, vim goes even further to extend vi's capabilities. However some find that vim is often too much. vim comes in two variants, a text-only version, and a GUI version, the latter is called gvim.
Other vi clones are the already mentioned elvis and stevie. These clones were born in the CP/M and home computer area to bring the editor to these platforms, too. Of course, they were later ported to MS-DOS and Windows. These days, however, vim seems to be the prevailing vi-clone on free/open platforms and proprietary platforms as well.
You should choose the version you feel most comfortable with – if you have an editor you feel displeased with, it will affect your productivity.
[edit] Getting around vi
[edit] Starting the editor
If you are running a Unix system, you can start up vi by typing
vi<CR>
at the command line. If you are running X, with a desktop like GNOME, KDE, CDE/Motif or OpenLook you may have a launcher button handy to start the editor - if you have such a setup, you can just click the icon.
If you are running Windows or DOS with elvis, you can start up the Windows editor by double-clicking "winelvis.exe", or in DOS, you can start the editor by typing in "elvis" at the command line.
You will be greeted with a screen similar to:
~ ~ ~ ~ ~ ~ "No File"
[edit] Quitting the editor
To quit for now, press the Escape key (the editor should beep), then enter the three characters :q! and press Return:
<ESC>:q!<CR>
Just before you type the final <CR> the screen will look similar to
~ ~ ~ ~ ~ ~ :q!
:q! is the short form of :quit! which quits the editor.
You should be dropped back to your operating system (or, rather, the shell from where you started).
There are other ways to quit, e.g. pressing <Z><Z> (<Shift-z><Shift-z>) will save any unsaved work and quit the editor. Typing :wq will always save, even if there are no unsaved changes, and then quit the editor. :x will write if there are no unsaved changes, and it will quit. :wq and :x requires that you had previously provided a file name, so it will not work for the above simple example. Typing :q will quit if there have been no changes made; if changes have been made, vi will print a warning similar to "No write since last change".
[edit] Don't worry
Many first time vi users stop at this point, and never touch vi again. If you tried to enter some text after you started, you will most likely have been greeted with a series of beeps and rather erratic behavior. Don't worry. This is perfectly normal for vi, and the editor is not broken. You will soon see why this is normal vi behaviour.
[edit] Continue
Now that you know how to start the editor and quit it, let's move on to getting things done in vi: see Learning the vi editor/Basic tasks
[edit] Basic tasks
Now that we know how to invoke the editor and quit it, we can get acquainted with how to use the editor.
Alternatively, you can use the ViM tutor which comes with many modern vim distributions. It contains, essentially the same information as the text below. You can invoke the tutor by entering vimtutor at your shell.
[edit] Vi is a modal editor
The vi editor can do two things:
- accept a command, such as deleting a line
- accept text, written by you
In the vi editor, each of these tasks is achieved by putting the editor into a particular mode of operation (normally just called a mode). When you wish to give vi a command, you enter command mode, and when you want to enter text, you enter insert mode. We'll cover how to do this below.
It is important to set the correct mode before you begin writing, but this is simple to do. When you first start vi, it is automatically in command mode.
[edit] Entering text
Entering text is the most basic task an editor can do! From command mode (in which the editor starts), press i to enter insert mode, and you can begin typing. You can use the backspace key to correct mistakes you make. If you make a mistake after a few sentences, leave these errors for now, we will look at correcting them later. To leave insert mode once you're done typing, and return to command mode, press the Escape key on your keyboard (or type Control-[).
[edit] Exercise
Let's have an exercise:
- Start the editor.
- Enter insert mode.
- Type some text
- Return to command mode.
- Quit the editor.
[edit] Solution
- We can start the editor as in the previous section.
- Since the editor starts in command mode, we must press the <i> key before we can start typing.
- You can make some text up yourself!
- Press the <Escape> key.
- If you want to quit the editor, you need to be in command mode. Since pressing Escape puts you in command mode, you can just use the method in the previous section to exit: type :q!
[edit] Command mode
Command mode allows you to perform many useful tasks within vi.
[edit] Moving around
Say you have been writing for some time, and have forgotten something. Pressing <Backspace>, erasing previous work is not the best solution! We would like to move around the document freely, moving the cursor.
We can move around in the editor by first entering command mode, and then using the <h>, <j>, <k>, and <l> keys.
- Note
- your arrow keys may be set up to work, and you can use them if you like, but for proficiency and for advanced work later, you should learn to use the letter keys.
- The <h> key, in command mode, moves the cursor one character left.
- The <j> key, in command mode, moves the cursor one character down.
- The <k> key, in command mode, moves the cursor one character up.
- The <l> key, in command mode, moves the cursor one character right.
If you have trouble remembering this, keep in mind that <h> is leftmost, the letter <j>goes down below the line, the letter <k>pokes up above the line, and the <l> key is rightmost. (J also resembles an arrow pointing downward, if you squint a bit.)
After you have moved the cursor using those keys, you can enter insert mode again by pressing <i>. When you do this, you insert text at the cursor, inserting text between the character to the left of the cursor and the current position of the cursor. Let's practice this in an exercise.
[edit] Exercise
You can repeat this exercise with your own sentences. Make sure you are proficient doing this before you continue.
- Start the editor.
- Enter the text: "The quick fox jumps over the dog"
- Insert the word "brown" between "quick" and "fox".
- Insert the word "lazy" between "the" and "dog".
- Quit the editor.
[edit] Solution
- Use the method in the previous section.
- Press <i>, then enter The quick fox jumps over the dog normally.
- Press <Escape>, then press <h> until the cursor is at the letter "f" of "fox". Press <i>, and then type "brown ".
- Press <Escape>, then press <l> until the cursor is at the letter "d". Press <i>, and then type "lazy ".
- Press <Escape> again, then type :quit!.
[edit] More on movement
Using h, j, k, and l is ok, but vi understands more than rows and columns. These are some commands that move by text objects:
- w moves forward to the beginning of the next word.
- b moves backwards to the beginning of the previous word.
- ( and ) move by sentences, either backward or forward.
- { and } move by paragraphs.
[edit] Deleting things
If you have made a mistake after a few lines, for instance, pressing Backspace until you have erased the mistake and starting again isn't always the best solution. We need a method of deleting mistakes that happen in the normal course of editing.
vi allows you several methods of deleting text, based on how much you want to remove. Now that you are familiar with moving around, once you've moved the cursor to where your error is:
- the x key deletes one character
- pressing dw deletes one word.
- pressing dd deletes one line
[edit] Exercise
From now on, we will omit the steps for you to start and quit the editor - you should be already familiar with those.
- Enter the following text: Sad I been here, I wouldnt ever ever leave.
- Change the word "Sad" to "Had".
- Add an apostrophe after "wouldn".
- Delete the extra "ever".
- Delete the line.
[edit] Solution
- Type the text normally. (You should already be familiar with entering insert mode and leaving it.)
- Enter command mode, use h to move to the start of the line, and then press x to delete the "S". Press i to enter insert mode, insert the "H", then leave insert mode by pressing Escape.
- Now position the cursor on the t, and press i to enter insert mode, type the " ' ". Leave insert mode by pressing escape.
- Position the cursor over the first "e" in the word "ever" (choose whichever one you like). Type dw to delete the word.
- Type dd to remove the entire line.
[edit] Making your work easier
Currently, you should by now know the rudiments of using vi. However, to really make vi work for you, it may be helpful to know the following to make your work easier for you.
[edit] More on commands
Say you are editing a document, and you wish to delete ten lines - as of now, the only way to do this is to enter dd ten times. Or if you want to delete seven characters exactly - you would have to enter x seven times. There must be a better way!
[edit] Repetition
Fortunately, vi lets you augment most of the commands in case you want to repeat that command a certain number of times. This is done by typing in the number of times you want that command repeated, followed by the command.
So, if you want to delete ten lines, you would type 10dd. Or if you want to delete seven characters, you would type 7x.
You can also repeat the last action done by typing . (this is a single period keystroke), the single-repeat operation over the location you want to repeat the previous operation.
So if you wanted to repeat the deletion of ten lines as in the previous example, you could repeatedly press . to perform this operation over and over again.
[edit] Exercise
1. Type the sentence Good morning Doctor, how are you today?. Delete "Good morning".
2. Now using the single-repeat operation, delete "how are".
[edit] Motion
vi allows you greater flexibility over motion as well. There are a few commands to allow you to quickly jump around your document, such as :
- 0 moves to the immediate beginning of the line
- $ moves to the immediate end of the line
- ^ moves to the first non-whitespace character of the line
^ acts in the following way, if the line was
hello how are you
and your cursor is on the u, if you would enter ^, the cursor would be upon the h.
Furthermore, the / command allows you to jump directly to some pattern in the file. For example, if you're looking for the next occurrence of the word "pomegranate" in your text, if you hit /, then type in pomegranate (you need not enter insert mode) and hit enter, the cursor will jump to the next occurrence of the word, if it exists. If you want to search backwards, you would perform the same procedure, but use the ? command. To repeat either search, enter //, ??, or alternatively, type / or ? and hit Enter.
[edit] Commands and motion
We know now that vi lets you enter a number to specify how many times to do something. Consider this example now: you want to delete everything after a certain point on a line - you could enter dw for each word from the cursor position to the end of the line, or hold down x, but these are cumbersome examples. vi thankfully lets you do something much faster.
With certain commands, vi allows you to specify a position, using the methods in the previous sections. The position is specified after the command. For example, to delete up to the end of the line, you would enter d$.
Other examples:
- d/; will delete until the next semicolon (This is helpful in languages like C and perl that use semicolons to finish statements).
- d2} to delete the next two paragraphs.
- d4b to delete the previous four words (alternatively, you could enter 4b4dw).
[edit] Advanced tasks
[edit] Copying and Pasting
Copying and pasting tasks are done with three keys, <y> (for "yank"), <d> (for "delete"), and <p> (for "paste"). In general, you type <y> or <d> to tell vi that you're at the position where you want to start yanking or deleting some text. Then you need to tell vi where to stop, using cursor movement or other commands.
You can also simply use key <v> to enter a visual mode. Then you can highlight text by moving cursor keys. And finally press <y> to copy text to clipboard. And <p> for paste.
[edit] A Word
To delete a single word, move your cursor to the first letter, then type <d><w>. To yank a single word, move your cursor to the first letter, then type <y><w>.
[edit] Other Methods
Move to the character past the last letter and type <d> <b>.
To delete a word like "can't", which has an apostrophe, move to the first character and type <d><W>. Note the capital W. This tells vi to go all the way to the first whitespace character after the word.
Likewise, try dB.
[edit] A Line
To delete a single line, type <d><d>.
[edit] Other Amounts
One of the great things about vi is that it lets you select a bunch of text without having to move your hand to your mouse.
Type <m><a>. This will mark the current position that your cursor is at as mark a. You can go back to this position anytime you want from now on by typing <`><a>. (`a means "move to the character that has been marked as a")
Now move to some other position. Type <d><`><a>. This will delete everything from the current position to the position you marked as a.
Note that you can use nearly any key in place of the <a> used in this example. For instance, you might use <m><t> to mark the top of a section, or <m><b> to mark the bottom. These mnemonics are strictly in the user's head - vi doesn't care that t means top or b means bottom. Vi will remember all unique bookmarks, allowing the user to easily and quickly jump between them. Some users find using <m><m> to be a convenient temporary bookmark, because it can be typed so quickly.
[edit] To the end or beginning of a line
<d><$> or <d><^>
[edit] To the end or beginning of the file
<d><G> or <d><1><G>
[edit] To the next occurrence of a pattern
<d>/myPattern
This is particularly useful when editing HTML files with d/<
[edit] Adjusting the Screen
vi, as a visual screen-oriented editor has a number of useful commands to redraw or adjust the screen in case you find yourself somewhere where you don't want to be.
If you run in a Unix shell, it is possible that some background process writes to the same terminal. This will disturb vi's screen layout. In order to force vi to redraw the complete screen, press <Ctrl-L> or <Ctrl-R>. Both commands do the same.
If you want to adjust what is currently displayed, then the <z> command is rather useful. It's a kind of Swiss army knife, and has a rather complex syntax:
[/pattern/][m]z[n](<CR>|.|-)
([ ... ] denotes optional items, (...|...) denotes alternatives)
Before we explain the syntax in detail, here are some common applications of the command:
Scroll the screen so the current line becomes the middle line of the screen. The cursor remains on that line:
<z><.>
Scroll the screen so the current line becomes the top line on the screen:
<z><CR>
Scroll the screen, so the current line becomes the bottom line of the screen
<z><->
If a /pattern/ or a number m is given the cursor is moved further after the adjustment. /pattern/ indicates to move the cursor to the first match of that pattern. m indicates to move the cursor to the mth line on the screen. So, for example,
/while/z<CR>
would first scroll the screen so the current line becomes the top line on the screen, and then move the cursor to the first 'while' in the text from that position on.
The number n is a rather obscure parameter. If provided, it tells vi to behave as if the screen is just n lines high. The result is that only n number of lines are adjusted, and the rest of the screen is either ignored or cleared, presumably useful on slow terminals to avoid redrawing the screen unneccessarily.
[edit] Details
This section describes some of the details of the vi program itself (such as command line features), and other advanced vi features for aspiring vi power users.
[edit] Command line invocation
Different vi clones of course have different ways of starting the program (invocation). Usually, however, command-line versions of vi share a common basic set of command line options. These following command line options and flags are typically available. In addition, vi can be started under different names. Depending on the name used to start vi, it may either behave slightly differently or load a different vi clone.
The common command line options and flags are
- -
or
- -s
- Suppress. All interactive user feedback is suppressed (not written to the terminal). This allows to pipe editing commands through the editor, and use it as a kind of stream editor. There are probably better streaming editor tools on Unix, like sed(1), awk(1), or Perl(n).
- Note, "-" is a common Unix notation to indicate standard input. It has been chosen as an alternative to -s by the vi authors to provide a familiar look when piping commands. It does not realy mean 'read from standard input' since vi does that anyhow.
- -C
- Encryption. vi prompts the user for a key (a kind of password), and uses this key to encrypt its files before writing. It also uses this key to decrypt any file opened with vi. This feature is not supported by many clones, and the encryption algorithm is a very weak one (it is based on a 256-element one-rotor algorithm). The algorithm is easy to crack. It is compatible with the Unix crypt(1) command. See also -x.
- -l
- (lower-case letter L) Change some default settings so they are more useful for editing LISP source code.
- -L
- (upper case letter L) Lists all files which have been saved during a crash. See -r, too.
- -r filename
- Recover the file filename after a crash. Use -L to get a list of files which can be recovered.
- -R
- Readonly. Files can only be viewed, not written.
- -S
- Tags are not sorted. When a tag file is used, this flag tells vi that the tag file is not sorted, therefore vi will use a slower algorithm to look up tags. See -t, too.
- -t tag
- Edit (open) that file which contains the given tag. This of course requires that a tag file (called tags) is available.
- -v
- Start in visual mode. Only useful if the editor is started under the name ex and not vi.
- -V
- Verbose. Commands read via standard input are echoed to standard error. This is useful for debugging when the editor is used as a streaming editor.
- -wnumber
- Window size. Set the editor's number of lines to number. vi behaves as if the terminal has only number number of lines. This was used in the old days to speed up things when connecting via a slow terminal or modem line.
- -x
- Encryption. Similar to -C. The difference is that vi tries to guess if a file that is opened needs decryption or not. -C on the other hand always runs the decryption when a file is opened.
- +command
or
- -c command
- Execute the command command before allowing the user to enter own commands. The most common usage is to use this to position the editor at some specific line in a file. E.g.
vi +10 list.txt
- will open the file list.txt and position the cursor at line 10. Another common usage is to specify a pattern:
vi +/END script.awk
- This will open the file script.awk and position the cursor at the first occurance of the pattern 'END'.
As already mentioned, vi can be started using different names (all may not be available depending on the particular clone):
- vi
- The usual way to start vi.
- view
- vi starts in read-only mode.
- vedit
- A few settings are changed to better suit beginners: magic is cleared, showmode and novice are set, and report is set to 1.
- ex -v
- Same as just typing vi
[edit] Commands: Objects & Operators
[edit] General
Until now, this tutorial has just talked about commands, and that commands can be used in conjunction with things like word counts. E.g. d2w has been explained as the operator delete applied to two words. Note the 2w part. You have learned that this part specifies to which text the operator should apply. And indeed, the 2w part specifies to which objects of the text (words, lines, characters etc.) the operator is supposed to be applied. And you have seen that the same object specifiers can be used with all types of operators - as long as the combination makes sense.
vi commands in fact follow a general schema. Commands are made up from operators and objects:
[[count] operator] [[number] object]
This means the operator should be executed count times on number of objects. Almost all parts are optional. Also, some operators don't take objects at all. This operator/operation syntax is vi's heart. It is why people either love or hate vi. People love it, because it is such a simple schema. Once one knows the few operators (not more than ten), and a few of the objects one can be very productive in vi. People who hate vi simply can't get this schema, and the fact that there is a difference between command and insert mode, into their heads.
[edit] Objects
We told you that things like the w command moves one word. We actually cheated a little bit when telling you this. There is no such thing as a w command. w is an object specification, not a command. The object specification was given without an explicit operator like d. In such a case vi uses the implicit default operator. And that operator is move.
Whenever you use an object specification without an operator, the operator move will be used. Therefore, object specifiers degrade to move commands. The following is a list and summary of all object specifier. Logically, you can use them in conjunction with operators, or to move around if used stand-alone. You have seen a few of them already:
[edit] Paragraph, Section, Sentence Objects
- }
- Everything until next paragraph end.
- {
- Everything until previous paragraph end.
- ]]
- [Everything until next section end.]
- [[
- [Everything until previous section end.]
- )
- Everything until next sentence end.
- (
- Everything until previous sentence end.
[edit] Line Objects
- [number]G
- Everything until line number. If number is omitted, last (not first) line in file. The first line can be addressed as 1G instead.
- [number]H
- number of lines after the first line currently on screen. If number is not given, the first line on the screen.
- [number]L
- number of lines before the last line currently on screen. If number is not given, the last line on the screen.
- M
- The middle line of the screen.
- j
- One line down from current line.
- k
- One line up from current line.
- _
- (underscore) The current line as a whole.
[edit] Positions within Lines
- 0
- (Digit 0). Backward to first column of line. Same as 1| (not 0|).
- ^
- Backward to first non-whitespace character.
- $
- Forward to end of line.
- [number]|
- Column number of the current line. If number is not given, column 1 is used.
- tchar
- Before the next appearance of character char on the current line.
- Tchar
- Backwards after the next appearance of character char on the current line.
- fchar
- Next appearance of character char on the current line.
- Fchar
- Previous appearance of character char on the current line.
- ;
- Repetition of the last t, T, f, or F command.
- ,
- Repetition of the last t, T, f, or F command, but in opposite direction.
- +
or
- <CR>
- To the first non-whitespace character on the next line.
- -
- To first non-whitespace character on the previous line.
[edit] Word Objects
- w
- Forward to next begin of a word.
- e
- Forward to next end of a word.
- b
- Backwards to next begin of a word.
[edit] Character Object
- h
or
- <BS>
- Left character.
- l
or
- <SPACE>
- (lower-case letter L or space) Right character.
[edit] Pattern Matching Objects
- /pattern/
- Forward to the beginning of the first match of pattern pattern.
- ?pattern?
- Backwards to the beginning of the first match of pattern pattern.
- <n>
- Repeat the last / or ?.
- <N>
- Repeat the last / or ? in opposite direction.
- <%>
- To next matching (, {, or [.
[edit] Operators
The previously listed objects can be used as arguments to operators. If no operator is given, the default move operator is used. The number of operators in vi is surprisingly small - ten in total. Here is a list of the operators:
needs better descriptions, a few of them are separately described later in this module
[edit] Operators taking Objects
- c
- change - change the addressed objects. In fact, the text is replaced by what is typed in.
- d
- delete - delete the addressed objects. The deleted text is placed in the undo buffer.
- y
- yank - copy the text of the addressed objects into the buffer.
- <
- shift left - object arguments can only be objects which address lines Indenting and Shifting.
- >
- shift right - object arguments can only be objects which address lines Indenting and Shifting.
- !
- bang filter-through - filter lines through an external program. Objects can only be objects addressing lines Filtering (stub).
[edit] Operators not taking Objects
r, s,
- x
- Delete character. Use the d operator for deleting other objects than characters.
- ~
- Flip case of character at cursor position. An uppercase letter becomes its lowercase equivalent, and a lowercase letter becomes its uppercase equivalent.
[edit] Special Operator Forms
There are two special forms when typing an operator:
- Typing the character in upper-case, instead of lower-case. E.g. Y instead of y , and
- doubling the character. E.g. yy instead of y.
[edit] 'Strange' lines on the screen
vi was written at a time when terminal or modem connections were slow. Therefor, vi used several optimisation techniques to limit the need for redrawing the whole screen. In such cases, vi used to display lines beginning with a special marker. Modern vi's seldom have the need for such performance optimizations any more, but they still have the habit to display such lines.
There are two special markers used:
~line
A leading '~' indicates that the line is past the end of the file (non-existant). This can be observed, for example, when vi is started on a new or empty file.
@line
The line is only on the screen, not in the file. This happens for deleted lines. If wrap is enabled (the default), this also happens for lines that are too long to show on the screen all at once.
[edit] Indenting and shifting
vi supports auto-indentation of text lines and also provides command for manual indentation. This is usefull when editing program source code. It is a common convention in many programming languages to use indentation to increase readability of the source code.
[edit] Options
The option shiftwidth (sw) determines how much space is used for indentation. E.g.
<ESC>:set shiftwidth=4<CR>
or
<ESC>:set sw=4<CR>
tells vi to use four spaces for indentation.
The option [no]autoindent (ai) tells vi to use auto identation or not. Auto indentation is turned on by
<ESC>:set autoindent<CR>
or
<ESC>:set ai<CR>
And it is turned off by
<ESC>:set noautoindent<CR>
or
<ESC>:set noai<CR>
[edit] Command Mode
Shifting lines is done with the < and > commands. < moves the text one shiftwidthto the left (outdenting), while > moves the text one shiftwidth to the right (indenting). The number of lines which can be affected are specified in vi's typical way. However, only objects which identify lines, and not objects which identify words or individual characters can be used.
E.g.
>G
moves all lines from the current line until the end of the file to the right.
Or
<}
moves all lines from the current line until the end of the paragraph to the left. Of course, the shift commands can be used in conjunction with %, which indicates the next opening bracket. E.g. to shift the lines encompassing the current cursor position up to the first line with a matching (, {, or [ to the left one would type:
<%
Like with all commands it is also possible to specify a line count:
- [number]<<
or
- <[number]<
- Moves number of lines, starting at the current line, one shiftwidth to the left (outdenting). If number is not given, 1 is assumed - this leads to the shifting of the current line to the left.
- [number]>>
or
- >[number]>
- Moves number of lines, starting at the current line, one shiftwidth to the right (indenting). If number is not given, 1 is assumed - this leads to the shifting of the current line to the right.
The < and > commands can also be used with a marker. In this case, the reference to the marker is placed between the two characters of the command:
- <'m<
- Shifts the lines from the marker m up and including the current line to the left.
- >'m>
- Shifts the lines from the marker m up and including the current line to the right.
[edit] Insert Mode
- ^t
- Moves shiftwidth to the right. Note, it is a common mistake to use the <TAB> key instead of ^t. <TAB> inserts a Ctrl-I character and moves to the next multiple of tabstop, and not to shiftwidth. So <TAB> only works if tabstop and shiftwidth are set to the same value.
- Since it is not a good idea to set tabstop to anything else than 8, <TAB> can only be used instead of ^t for indenting when shiftwidth is also set to 8.
- ^d
- In autoindent mode, backtabs one shiftwidth. E.g. if autoindent is on, and one wants to enter the follwing text:
if(true) {
printf("done"); // start sw indent
return;
} // bracket moved back to the left
- one would type
if(true) {<CR>
^tprintf("done"); // start sw indent<CR>
return;<CR>
^d} // bracket moved back to the left<CR>
There are some special variants of ^d, too:
- ^^d
- (the letter ^ followed by Ctrl-D). When this is typed first on a new line, all autoindent is killed (the insertion point is moved to the beginning of the line). Autoindent is then continued on the next line.
- E.g. to enter the following text when using autoindenting
an indented paragraph
another line in the indented paragraph
.F roff formating commands have to start at column one with a '.'
more text in the indented paragraph
one would type
^tan indented paragraph<CR> another line in the indented paragraph<CR> ^^d.F roff formating commands have to start at column one with a '.'<CR> more text in the indented paragraph<CR>
- 0^d
- (the digit 0 followed by Ctrl-D). Kills all autoindent (moves cursor to the beginning of the line), and leaves autoindent off, until text is once manually indented (using ^t).
- E.g. to enter the following text when using autoindenting
INTEGER FUNCTION FAC(N)
FAC = 1
DO 100 I = 2, N
FAC = I * FAC
C
C PROVIDE LABEL TO END LOOP
C A HINT FOR THOSE GRASSHOPPERS: THIS IS FORTRAN CODE :-)
C
100 CONTINUE
RETURN
END
- one would type
<ESC>:set sw=5<CR> o^tINTEGER FUNCTION FAC(N)<CR> FAC = 1<CR> DO 100 I = 2, N<CR> ^tFAC = I * FAC<CR> 0^dC<CR> C PROVIDE LABEL TO END LOOP<CR> C A HINT FOR THOSE GRASSHOPPERS: THIS IS FORTRAN CODE :-)<CR> C<CR> 100 CONTINUE<CR> ^tRETURN<CR> END<CR>
[edit] Modelines
Modelines are a fancy but dangerous vi feature. Therefore, they are usually turned off by default in every self-respecting vi version and may have only partial support or no support at all. Some clones intentionally only support selected commands in modelines to avoid the security problems.
Modelines are lines in text files which are specially interpreted by vi when such a text file is opened. When the modeline (ml) (in some version of vi also called modelines) option is turned on (e.g. in the users .exrc file), vi scans the first and last five lines of each opened file for text of the form
unrelated text vi:command: more unrelated text
or
unrelated text ex:command: more unrelated text
Each command from such lines is taken and executed as it would have been typed by the user. Any text in front of the modeline-marker (vi: or ex:) or behind the closing : is ignored for the modeline interpretation. This can be used to place modelines in comments if they are used in some programming source code.
Here is an example Java source code file. It contains a modeline on the second and third line, in a Java comment:
/* * vi:set sw=4 ai: * vi:set showmatch: */
package gnu.freesoftware; public class Interpreter { public Interpreter() ... ...
When modelines are turned on, and this file is opened, shiftwidth (sw) is set to 4, autoindent (ai) is turned on, and the showmatch (sm) option is turned on, too. There is no particular reason why two set commands on two modelines are used other than to demonstrate that all modeline commands found in the first and last five lines are executed, and not just the first.
Modelines can be used to play some practical jokes. E.g., a file with the modeline
vi:q!:
immediately closes the editor and makes it impossible to edit the file as long as modelines are turned on.
Modelines get outright dangerous if they mess with system files. E.g., if the super user (administrator) of a Unix system has modelines turned on, and is tricked into opening a file with the following modeline, the important Unix password file is overwritten with the contents of the opened file:
vi:2,$w! /etc/passwd: root:A shiny new root password:0:0:System Administrator:/:/bin/sh anotheruser:Another shiny new password:1:0:Just another user:/home/anotheruser:/bin/sh
Therefore modelines should only be turned on in a controlled environment. This is sad, since in principle it is a nice idea that files are able to provide the editor with a configuration best suited to edit that file.
There are some other problems with modelines. Classic vi versions always set a file's status to modified if they find a modeline, even if no editing in the file has taken place. This forces the user to leave the editor with :q! instead of just :q. If instead ZZ is used to leave, the file is written. This causes tools like make to think the file has changed if it in fact hasn't.
[edit] .exrc Configuration File
This module is a stub. You can help Wikibooks by fixing it. For a start:
.exrc files are files containing vi (and ex) configuration data. The format of the data in such a file is that of ex commands, without the leading ':' (column). Typically, .exrc files are used to load some default mappings (map and map! ex commands) or define particular defaults. E.g. the following .exrc file would set autoindent and the shiftwidth when vi is started:
set ai set sw=4
Normally, a .exrc file is placed in the user's home directory. Since the file name starts with a '.', the file is hidden under Unix-like operating systems. It is possible to place .exrc files in other directories, too. Vi can read the .exrc file in the current directory from which it is started. However, this feature is considered a security risk and turned off by default. It is considerd a risk, because similar jokes can be played with .exrc files as with what has been described for modelines. The .exrc file in a user's home directory is considered save, because on a correctly configured Unix system only the particular user should have write access to it.
There are three important things which should be observed when working with a classic vi and .exrc files:
- .exrc files must not contain empty lines. Classic vi chokes on these lines with all kinds of cryptic error messages.
- There is no official way to place a comment in .exrc files. However, since the beginning of time the following hack is used and is known to work: A line which starts with a " (quotation character) is ignored by vi.
- Classic vi is very picky about map and map! commands. Definitions which by all means should work can trigger strange error messages. This is due to classic vi's limited parser and interpreter for such definitions. Spliting a map or map1 command in several smaller ones can sometimes help.
Many clones have relaxed these rules by allowing empty lines in an .exrc file, and by officially specifying the " as the comment character. Also, good clones should have no problem with map or map! specifications.
" " This is a comment in an .exrc file " A .exrc file must not contain empty lines, so " comment lines need to be used to separate entries " set sm set sw=8 " set wm=8 " " map 'g' to go to begin of file map g 1G " rcs check-out (/co) and check-in (/ci) map /co :w! %.co.bak^M:!co -l %^M:e! map /ci :w^M:!ci -u %^M:e!^M " " Abbreviations ab Lx Linux
[edit] Tags
[edit] Overview
Vi can use so called tag files (or tags) to allow for quick navigation (jump) to "interesting" information in a set of files. The most common usage for this is to navigate within source code files. E.g. to jump from the usage of a certain function to the function's definition, possibly in another file.
The mechanism is relatively simple. You tell vi to go to a particular tag. vi looks up the file in which the tag can be found, opens that file and jumps to the location of the tag in that file. In order to find the file and position of a tag, vi consults a tag file. A tag file contains an index of tags. A tag is an item (e.g. some programming language object) for which such an index entry can be found in a tag file. When vi is asked to jump to a particular tag, vi looks up the index entry for that tag, and uses the information to jump to the particular item.
In order to use this feature one first has to create a tag file, or a set of tag files, containing entries for all potentially interesting items. These tag file or files then need to be made known to vi - if the default file name is not used. This can e.g. be done by having appropriate commands in an .exrc file.
Modern IDEs provide similar navigation features, but without the need to build a tag file separately. IDEs build the necessary index on-the-fly or use fast brute-force full-text search algorithms. The need for the extra step of creating a tag file for vi is annoying by modern standards. Still, vi's tag file system works and is usable.
[edit] Tag File Format, Creation & ctags(1)
The creation of a tag file typically requires to use a tool which analyses the input text files (e.g. programming source code) and generates entries for each item of interest found in the input text file. The most common tool is called ctags(1) and is a standard Unix program. Several vi clones come with own versions of ctags, sometimes called differently.
ctags knows the syntax of a number of programming languages and generates index information for items like function names, and macro definitions.
In case ctags is not available, or the available version of ctags does not support the programming language in use it is also possible to generate tag files with text processing tools like awk(1), sed(1) or perl(n) and some clever scipts, because tag files are ASCII files.
Typically an entry in a tag file looks like
tag-name<TAB>file-name<TAB>ex-command
- tag-name
- The name of the item. E.g. a function name or macro name.
- file-name
- The name of the file in which the tag-name item can be found
- ex-command
- An ex editor command indicating how to locate the item in the file. This can be any ex command. But two types of ex commands make the most sense:
- In the simple form ex-command is a line number, which is indeed a valid ex command.
- Usually, however, it is a better idea to use a search pattern like /tag-name/. This provides some flexibility if the file is edited later. It reduces the number of times the tag file has to be re-build, because something moved inside a file. ctags also mostly generates pattern search commands and not line numbers.
Typically vi clones allow for some extensions of this format. Check the particular documentation.
A tag file should be sorted in alphabetic order to speed up operation. If this can't be done, vi's -S command line option can be used.
It is usually not a good idea to generate tag files by manually running ctags or an own tool. Instead the building of tag files is usually better integrated into the software build system. For Unix this means using Makefiles. Typically, the make(1s) targets for generating tag files are called tags, because that's the name of the to be created tag file:
# Makefile snipet
SRCS = ... # all source code
tags: $(SRCS)
ctags -dt $(SRCS)
[edit] Ex Commands
By default, vi looks in a file called tags for any tags. This file name can be changed with the following ex command. In fact, more than one file name can be specified. They are all loaded to find tags. The command is maybe best placed in a project-specific .exrc file.
- :set tags=filename[\ filename ...]<CR>
- Set name of files which contain tag information. The syntax of the command varies a little bit from vi to vi version if more than one tag filename is supposed to be provided. Filenames have either to be separated by "\ " (backslash space) or ";" (semicolon).
Naviation to tags can be done via the following ex command. There is also a vi command to do this.
- :ta tag-name<CR>
- or
- :tag tag-name<CR>
- Look up the tag-name in the tags file(s), open the file named in the index entry and execute the ex-command from the index entry. This effectively positions the user at the file and position where the symbol tag-name is defined. The command also remembers the current file and position on the tag stack.
[edit] Vi Commands
Navigation to tags can be done via the following vi command:
- ^]
- Take the tag-name at the cursor position, look it up in the tag file(s) and navigate to it, similar to the :ta ex command. The command also remembers the current file and position on the tag stack.
The following command uses the tag stack to go back to the previous position. Older vi's don't have it implemented:
- ^T
- Get the previous position and file from the tag stack and return to it. The data is removed from the file.
[edit] Command Line
Vi can also be started with a tag name instead of a file name. See the -t command line option.
[edit] Shell escape
While one is working in vi there might arise a need to run another operating system command. In these modern days this is not a big issue. One can open another terminal window and do as pleased. However, this is not necessary when working with vi. Vi, like many of the older interactive Unix tools, contains features to run operating system commands or start a command line interpreter (shell) from within the editor. This dates back to the times when there were no graphical user interfaces and an editor like vi would take up the complete screen of the terminal (a real terminal of course, not a terminal emulation). Being able to run commands from vi spares one the need to first quit the editor just to look something up, e.g. in a manual page.
In addition, vi provides features to insert the text output of other commands directly into the text under editing.
[edit] Ex Commands
The editor commands to run another command from within vi are in fact implemented as ex commands. That is, they start with the familiar ':' in command mode.
To execute one command from within vi, one would type
:!command<CR> <CR>
At the end of the command one has to hit Return (the second <CR> shown above) to go back to vi. Vi then repaints the screen and continues where editing was left.
In order to repeat the last command, one can simply type
:!!<CR> <CR>
It is possible to append to a previous command by using :!!, followed by whatever should be appended. For example, the second of the following two commands
:!ls<CR> <CR> :!! | more<CR> <CR>
is actually equal to
:!ls | more<CR> <CR>
(Note, ls is the Unix command to list a directory, more is the Unix command to paginate output, so it doesn't just scroll off the screen).
Once something is appended to a command, it becomes part of the last remembered command. So in the example above, another
:!!<CR> <CR>
would be equal to
:!ls | more<CR> <CR>
and not
:!ls<CR> <CR>
Two placeholders can be used in shell escapes to denote the current file name or the name of the previously edited file name:
- %
- is a placeholder for the current file name,
- #
- is a placeholder for the previously edited file name.
For example, if one is editing some shell script and wants to try it out, one could type the following commands to save the file (:w), set the file's attributes to executable (!chmod ...), and run it (!%):
:w<CR> :!chmod 755 %<CR> <CR> :!%<CR> <CR>
If the file's name is, e.g. script.sh, the above would be equal to typing
:w<CR> :!chmod 755 script.sh<CR> <CR> :!script.sh<CR> <CR>
Instead of running a command from within vi it is also possible to start the shell from within vi. vi has an own command for this, which looks up the user's default shell (e.g. the Bourne shell or the C shell) and starts it. It is important to note that a new shell is started. The user is not returned to the shell from which vi was started. The command is called :sh, and it can be used as it follows:
<ESC>:sh<CR> $ #shell commands, when done exit shells: $ exit<CR>
[edit] Vi Commands
It is possible to filter all or parts of a text currently under editing through an external program. The original text is then replaced with the output of the external command.
The classic example for this feature is the usage of the Unix text formatter fmt. vi itself doesn't have any specific formating capabilities, however, by running the text or parts of it through an external formater from within vi, the desired formatting is easily achieved.
The vi command for filtering text is ! (note, as opposite to the ex shell escape command, there is no leading :). ! follows the usual vi command format. So one can specify the scope to which it should apply. E.g. !! means to filter the current line, or !} means to filter the current paragraph.
The ! vi command has to be followed by by the name of the external program to be used for filtering. E.g. in order to format the current paragraph with the already mentioned Unix text formatter fmt, one would type
!}fmt<CR>
! can also be used to just insert the output of some external command into the currently edited text. To do so, one would first create a new empty line (e.g. with o), and then use !! to replace the empty line with the output of a command. For example,
o<ESC>!!ls<CR>
would include a listing of the files in the current directory into the text under Unix.
[edit] Execute command from Buffer
This module is a stub. You can help Wikibooks by fixing it.
- @b
- Execute command stored in buffer b.
[edit] vi for Programmers
Classic vi provides a number of features which are useful for programmers. Vi was made by programmers for programmers -- but at a time when programming was different. Classic vi's programming support is, by today's standards, not too great, but of course still usable. And it is still more convenient to use vi for editing programming code than any of the ...pad editors like notepad (Windows) or dtpad (CDE/Motif). vi probably works best on Unix systems due to the many text filters that come with Unix and the ease with which additional special-purpose filters can be scripted.
Useful features in vi for programmers are:
[edit] Autoindent and manual Shifting of Lines
[edit] Modelines
Modelines to set per-language defaults - if security is not an issue (see Modelines)