Section D.7 vi, vim
Subsection D.7.1 Using vi and PreTeXt together
Any smart editor, and vi is no exception, allows the addition of new commands to make repetitive tasks easier. Since creating documents with PreTeXt markup often is repetitive, it makes sense to explore the techniques of creating additional commands in vi to make editing easier.
The expectation for this section is that the reader is able to use vi to create and edit files, but no greater depth of knowledge is assumed. The term vi is meant to be inclusive, that is, it includes vim, gvim and the like.
Subsubsection D.7.1.1 Modes of vi: Command, Normal, and Insert
One of the most fundamental properties of vi is that every editing task may be accomplished using the keyboard. For different editing contexts, it is advantageous to have the keyboard strokes have different meaning; these different interpretations are called the modes of vi.
Here are the pertinent modes of vi:
- Normal mode: This mode is for changing position within the file. For example,
j
moves down,2w
moves forward two words, and-2}
moves backwards two paragraphs. It is also used for block operations on text:-3dd
is used to delete three previous lines, or2.yy
will yank the next two sentences. Usually vi starts in normal mode. - Insert mode: This mode is for inserting new text into the file. Typing
Galloping Gertie leapt into the air.
causes that text to be inserted at the current position in the file. - Command mode: This mode is to execute commands. Typing
/abc
in normal mode initiates a forward search for the first occurrence of “abc” via the command mode. Similarly:w
will use command mode to write out the current working material (buffer) to the disk.
Now a quick review of the keys used to move between modes: From a given position in a file in Normal mode, using i or a will change to Insert mode and insert text before or after that position. Similarly, I or A will insert text in front of or directly following the current line, and O or o will insert text above or below the current line. Returning to Normal mode is done using Esc.
If /, ?, or : is typed when in normal mode, a small one-line window opens up (called the command line) to receive text. This entered text is terminated by Enter. The / or ? initiates a forward or backward search for the entered text. The : sends the entered text to the vi program for further processing.
Figure D.7.1 show the keys used to move between modes.
An exclamation point prefix
!
in Command mode sends that command to the operating system. For example, entering :!date
will cause the results of the operating system command date
to be displayed on the command line. In addition the percent character %
gets expanded to the name of the file being edited. If your operating system uses ls -l
to list file information, then :!ls -l %
will give the properties of the file being edited.Subsubsection D.7.1.2 Using :set
The Command mode in vi allows users to change their interaction with the editor. (Remember that entering
:
changes to Command mode, and any text string entered in Command mode is terminated by Enter.) For example, entering :set number
will cause line numbers to appear on the left. They are not in the file itself, of course, but are there for the convenience of the user. Entering :set nonumber
will remove these line numbers. Similarly :set autoindent
will cause a new line to preserve the indentation of the previous one and :set expandtab
will replace the tab character by an appropriate number of spaces (both are very useful for writing PreTeXt documents). Some useful set commands are given in Table D.7.2.Command | Resulting change |
:set autoindent | A new line preserves indentation |
:set expandtab | Inserted tabs converted to spaces |
:set rows\(=\)n | Set number of lines displayed |
:set columns\(=\)n | Set the display size of each line |
:set list | Show tabs and carriage returns |
:set tabstops\(=\)n | Tab inserts \(n\) spaces |
:set | Show all current settings |
Subsubsection D.7.1.3 A little editing etiquette
The xml files used with PreTeXt are ordinary text files. This makes it easy for coauthors to email them back and forth in order to expand and improve the content. There are a few potential problems, and hence some useful precautions.
- If a Tab is entered and not expanded to spaces, different editors may display the text with different alignments.
- If there are extra spaces at the end of a line, there may be odd line wrapping.
Fortunately, these are easy to avoid.
- A tab character may be found in the usual manner for searches: : / Tab will find the next tab; it can be removed and replaced by spaces.
- A space before the end of a line can be found with the search : / Space $ (vi will interpret $ as the end of a line rather than as a dollar sign). The spaces at the end of the line can then be removed.
There is another feature of vi that is helpful in this respect. Using
:set list
will make the tab and end of line characters visual as ^I
and $
. This makes the appropriate deletions easy. It is good editing etiquette to do so.Subsubsection D.7.1.4 Abbreviations
The
:abbreviation
command allows the replacement of longer expressions by shorter ones. Try this: in Command mode enter:abbreviate ups University of Puget Sound
and then (in Insert mode) type
I enjoyed my visit to the ups.
If all goes well, the abbreviation is expanded and the text is
I enjoyed my visit to the University of Puget Sound.
Now suppose you want to write
My favourite letter of the Greek alphabet is upsilon.
Looks like trouble with the last word, but in fact all is well. Abbreviations are not expanded until the next character after the abbreviation is read. If the next character after the abbreviation is either a letter or a number, no expansion takes place. Careful observation of the original example reveals that the abbreviation is not expanded until the period is entered. Here is another example: You want to write I love pushups.
What about the end of the last word? No problem! The ups
is expanded only if it is at the beginning of a word.Amusingly enough, when in Command mode, the
abbreviate
command can itself be abbreviated to ab
.The choice of an abbreviation is essentially arbitrary. However, if desiring an abbreviation within “I enjoyed my visit to the Technische Hogeschool Eindhoven”, it would be folly to use
:ab the Technische Hogeschool Eindhoven
. The abbreviation should be mnemonic, but avoid actual words.Now consider the following problem: what if the Enter key is one of the desired characters in the abbreviation? Since that key terminates Command mode, it appears impossible. Not so! The characters
<enter>
(that’s seven of them) will be replaced by a single character equivalent to Enter.There are other characters that are treated in the same manner:
Desired key | Text equivalent (not case sensitive) |
Enter | <enter> or <cr> |
Backspace | <bs> |
Insert | <ins> |
Delete | <del> |
Esc | <esc> |
← | <left> |
→ | <right> |
↑ | <up> |
↓ | <down> |
Home | <home> |
End | <end> |
Ctrl+x | <C-x> |
Alt + y | <M-y> |
Here is a useful PreTeXt example: Define the abbreviation
ab gm <m></m><left><left><left><left>
and then enter (in Insert mode)
It follows from gm\log(\theta)=0 that gm\theta=1.
It will (almost) be expanded to
It follows from <m>\log(\theta)=0</m> that <m>\theta=1</m>.
That’s “almost” because it is necessary to move the cursor past the
</m>
when leaving the mathematics input. It’s pretty easy to see how this abbreviation works. The first seven characters <m></m>
are expanded unchanged and then the cursor moves to the left four times to put it right where it needs to be to enter the mathematics. Careful observation will reveal a little trick used in this example: gm
is followed by a \
and so terminated the abbreviation correctly. If the variable were \(x\text{,}\) then inputting gmx
would not work. A workaround: enter a Space after the gm
. This terminates the abbreviation and it will work as desired. (Actually, there will be an extra space before the \(x\text{,}\) which causes no ill effect, but if true perfection is desired, using gm
Space Backspace will eliminate it.)When
:ab
is used, it is in effect in all modes. When abbreviations are for Input mode only (as is the present case), then iab:
may be used and is usually preferable.Here is another useful (nonmathematical) example. Define (for use in Input mode)
:iab gp <p><cr></p><up>.
Then entering “gpEnter” on a new line will create three lines appearing like:
<p> </p>
That is, the first and third line start and end a paragraph and the cursor, represented by
|
is at the beginning of the second line. If autoindent is set, (see Table D.7.2), the line indentations are preserved. With this definition, the frequent task of starting a new paragraph appropriately formatted may be carried out using only three key strokes.A further example:
:iab gcom <!--<CR><CR>--><Up>
is useful to entering comments. Starting a line with “gcom Tab” will help create nicely indented comments.
Want to know what abbreviations are in effect? Just enter
:ab
and they will be listed.Subsubsection D.7.1.5 Maps
Maps, like abbreviations, are shortcuts that save extra key strokes. There is a difference in method: the
map
command uses key bindings that (re)define the meanings of key strokes. For example, inputting (while in Normal mode) :map <C-X> :w<CR>
will define (map) the Ctrl +X key combination so that it is equivalent to typing the rest of the definition, :w<CR>
. This three-key sequence, of course, just changes to Command mode, writes the current buffer to disk, and returns to Normal mode.Presumably this newly defined key binding is meant to be invoked in Normal mode. To do so in Insert mode would be a mistake; to avoid this, there is an
nmap
command that defines key binding for Normal mode only. Similarly, there is an imap
command for Insert mode only. Thus defining a key binding using :nmap <C-X> :w<CR>
will make it valid only in Normal mode. Unlike abbreviations, the binding takes effect the moment the key is pressed.There is a cute technique to use the same binding in Normal and Insert modes. The key binding
:imap <C-X> <esc><C-X>a
defines a binding for Insert mode. The first character, <esc>
, changes to Normal mode; the next character, <C-X>
, will use the the Normal mode definition of <C-X>
. The final character a
returns to the previous position in Insert mode.We can make special use of the special characters
!
and %
as described at the end of Subsubsection D.7.1.1.The author using PreTeXt usually edits an xml file, say
myfile.xml
. This file is then processed using xsltproc in conjunction with an xsl file, say myfile.xsl
. Often the xsl file is pretext-html.xsl
or pretext-latex.xsl
. The usual command used by the author is xsltproc myfile.xsl myfile.xml
. With this in mind, we could define a map: :nmap <C-X> !xsltproc myfile.xsl myfile.xml<CR>
so that the xml file could be processed with a single keystroke. Even better: :nmap <C-X> :w<cr>:!xsltproc myfile.xsl %<CR>
defines a map that first writes the file being edited to disk and then processes it with xsltproc. This command is independent of the particular file being edited.A final somewhat complicated but very useful definition:
imap <C-A> <Esc>yiwi<<Esc>ea></<Esc>pa><Esc>F<i
which is a truly cryptic sequence of key strokes. Here is what they do:
Key strokes | Interpretation |
<esc> | Leave input mode |
yiw | Save (yank) word above cursor |
i< | Insert <
|
<esc> | Go to to Normal mode |
e | Move to end of word |
a></<esc> | append ></ and return to Normal mode |
p | Paste the saved word |
a><Esc> | append > and leave Insert mode |
F< | Move to preceding < |
i | Go to Insert mode |
The effect of this map: Entering
abc<C-A>
will change abc
to <abc>|</abc>
where |
is the position of the cursor.To list all of your defined maps, just use
:map
.Subsubsection D.7.1.6 Saving abbreviations and maps
The abbreviations and maps defined during an editing session disappear when the session is over. There are a number of ways to retain them over different sessions.
- Ephemeral use in one file: For most versions of vi, after entering Command mode the history may be accessed using the \(\uparrow\) key. Backing up to the previous definition of an abbreviation or map and pressing Enter will reinstate the definition. The line can also be edited if changes are desired (very useful while developing new abbreviations and maps). This history is preserved between editing sessions.
- Repeated use in several files in one directory: The abbreviations and maps can be saved in a text file, say
mymaps.txt
. A line within the file might look like:ab ups University of Puget Sound
Vi is then started with the-s mymaps.txt
option to initialize the definitions. - Repeated use for files in different directories: Put the abbreviations and maps in the file
.vimrc
(_vimrc
for Windows) in your home directory.