免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: projl
打印 上一主题 下一主题

《Learning the vi editor》 [复制链接]

论坛徽章:
0
121 [报告]
发表于 2008-06-11 15:02 |只看该作者
You could also use W instead of w.

3. Save a file and edit the next one in a series:
:map q :w^M:n^M

Notice that you can map keys to ex commands, but be sure to
finish each ex command with a carriage return. This sequence
makes it easy to move from one file to the next and is useful
when you've opened many short files with one vi command.
Mapping the letter q helps you remember that the sequence is
similar to a "quit."

4. Put troff emboldening codes around a word:
:map v i\fB^[e\fP^[

This sequence assumes that the cursor is at the beginning of
the word. First, you enter insert mode, then you type the
code for the bold font. In map commands, you don't need to
type two backslashes to produce one backslash. Next, you
return to command mode by typing a "quoted" ESC. Finally,
you append the closing troff code at the end of the word, and
you return to command mode. Notice that when we appended
to the end of the word, we didn't need to use ea, since this
sequence is itself mapped to the single letter e. This shows
you that map sequences are allowed to contain other mapped
commands. (The ability to use nested map sequences is
controlled by vi's remap option, which is normally enabled.)

5. Put troff emboldening codes around a word, even when the
cursor is not at the beginning of the word:
:map V lbi\fB^[e\fP^[

This sequence is the same as the previous one, except that it
uses lb to handle the additional task of positioning the cursor
at the beginning of the word. The cursor might be in the
middle of the word, so you want to move to the beginning
with the b command. But if the cursor were already at the
beginning of the word, the b command would move the cursor
to the previous word instead. To guard against that case, type
an l before moving back with b, so that the cursor never
starts on the first letter of the word. You can define variations
of this sequence by replacing the b with B and the e with Ea.
In all cases, though, the l command prevents this sequence

论坛徽章:
0
122 [报告]
发表于 2008-06-11 15:02 |只看该作者
from working if the cursor is at the end of a line. (You could
append a space to get around this.)

6. Repeatedly find and remove parentheses from around a word
or phrase: [5]
[5] From the article by Walter Zintz, in UNIX World, April 1990.
:map = xf)xn

This sequence assumes that you first found an open
parenthesis, by typing /( followed by RETURN.


If you choose to remove the parentheses, then use the map
command: delete the open parenthesis with x, find the closing
one with f), delete it with x, and then repeat your search for
an open parenthesis with n.

If you don't want to remove the parentheses (for example, if
they're being used correctly), then don't use the map
command: press n instead to find the next open parenthesis.

You could also modify the map sequence above to handle
matching pairs of quotes.

7. Place C/C++ comments around an entire line:
:map g I/* ^[A */^[

This sequence inserts /* at the line's beginning and appends
*/ at the line's end. You could also map a substitute
command to do the same thing:

:map g :s;.*;/* & */;^M

Here, you match the entire line (with .*), and when you
replay it (with &), you surround the line with the comment
symbols. Note the use of semicolon delimiters, to avoid
having to escape the / in the comment.

8. Safely repeat a long insertion:
:map ^J :set wm=0^M.:set wm=10^M

We mentioned in Chapter 2, that vi occasionally has difficulty
repeating long insertions of text when wrapmargin is set. This
map command is a useful workaround. It temporarily turns off
the wrapmargin (by setting it to 0), gives the repeat

论坛徽章:
0
123 [报告]
发表于 2008-06-11 15:03 |只看该作者
command, and then restores the wrapmargin. Note that a
map sequence can combine ex and vi commands.

In the previous example, even though ^J is a vi command (it moves
the cursor down a line), this key is safe to map because it's really
the same as the j command. There are many keys that either
perform the same tasks as other keys or that are rarely used.
However, you should be familiar with the vi commands before you
boldly disable their normal use by using them in map definitions.

7.3.6 Mapping Keys for Insert Mode
Normally, maps apply only to command mode鈥攁fter all, in insert
mode, keys stand for themselves and shouldn't be mapped as
commands. However, by adding an exclamation mark (!) to the mapcommand, you can force it to override the ordinary meaning of a
key and produce the map in insert mode. This feature is useful
when you find yourself in insert mode but need to escape briefly to
command mode, run a command, and then return to insert mode.

For example, suppose you just typed a word but forgot to italicize it
(or place quotes around it, etc.). You can define this map:

:map! + ^[bi<I>^[ea</I>

Now, when you type a + at the end of a word, you will surround the
word with HTML italicization codes. The + won't show up in the text.

The sequence above escapes to command mode (^[), backs up to
insert the first code (bi<I>, escapes again (^[), and moves ahead
to append the second code (ea</I>. Since the map sequence
begins and ends in insert mode, you can continue entering text
after marking the word.

Here's another example. Suppose that you've been typing your text,
and you realize that the previous line should have ended with a
colon. You can correct that by defining this map sequence:[6]

[6] From an article by Walter Zintz, in UNIX World, April 1990.
:map! % ^[kA:^[jA

Now, if you type a % anywhere along your current line, you'll
append a colon to the end of the previous line. This command
escapes to command mode, moves up a line, and appends the colon
(^[kA. The command then escapes again, moves down to the line
you were on, and leaves you in insert mode (^[jA).

论坛徽章:
0
124 [报告]
发表于 2008-06-11 15:04 |只看该作者
Note that we wanted to use uncommon characters (% and +) for the
previous map commands. When a character is mapped for insert
mode, you can no longer type that character as text.

To reinstate a character for normal typing, use the command:

:unmap! x

where x is the character that was previously mapped for insert
mode. (Although vi will expand x on the command line as you type
it, making it look like you are unmapping the expanded text, it will
correctly unmap the character.)

Insert-mode mapping is often more appropriate for tying character
strings to special keys that you wouldn't otherwise use. It is
especially useful with programmable function keys.

7.3.7 Mapping Function Keys
Many terminals have programmable function keys (which are
faithfully emulated by today's terminal emulators on bitmapped
workstations). You can usually set up these keys to print whatever
character or characters you want using a special setup mode on the
terminal. However, keys programmed using a terminal's setup
mode only work on that terminal; they may also limit the action of
programs that want to set up those function keys themselves.

ex allows you to map function keys by number, using the syntax:

:map #1 commands

for function key number 1, and so on. (It can do this because the
editor has access to the entry for that terminal found in either the
terminfo or termcap database and knows the escape sequence
normally put out by the function key.)

As with other keys, maps apply by default to command mode, but
by using the map! commands as well, you can define two separate
values for a function key鈥攐ne to be used in command mode, the
other in insert mode. For example, if you are an HTML user, you
might want to put font-switch codes on function keys. For example:

:map #1 i<I>^[
:map! #1 <I>

If you are in command mode, the first function key will enter insert
mode, type in the three characters <I>, and return to command

论坛徽章:
0
125 [报告]
发表于 2008-06-11 15:04 |只看该作者
mode. If you are already in insert mode, the key will simply type
the three-character HTML code.


If function keys have been redefined in the
terminal's setup mode, the #n syntax might not
work since the function keys no longer put out the
expected control or escape sequence as described in
its terminal database entry. You will need to
examine the terminfo source (or termcap entry) for
your terminal and check the definitions for the
function keys. In addition, there are some terminals
whose function keys perform only local actions and
don't actually send any characters to the computer.
Such function keys can't be mapped.

The terminal capabilities k1, k2 through k0 describe the first ten
function keys. The capabilities l1, l2 through l0 describe the
remaining function keys. Using your terminal's setup mode, you can
change the control or escape sequence output by the function key
to correspond with the terminfo or termcap entry. (For more
information, see termcap & terminfo, published by O'Reilly &
Associates.)

If the sequence contains ^M, which is a carriage return, press CTRL


M. For instance, in order to have function key 1 available for
mapping, the terminal database entry for your terminal must have a
definition of k1, such as:
k1=^A@^M

In turn, the definition:

^A@^M

must be what is output when you press that key.

To see what the function key puts out, use the od (octal dump)
command with the -c option (show each character). You will need
to press RETURN after the function key, and then CTRL-D to get od
to print the information. For example:

$ od -c
^[[[A^D

0000000 033 [ [ A \n
0000005

论坛徽章:
0
126 [报告]
发表于 2008-06-11 15:05 |只看该作者
Here, the function key sent Escape, two left brackets, and an A.

7.3.8 Mapping Other Special Keys
Many keyboards have special keys, such as HOME, END, PAGE UP,
and PAGE DOWN that duplicate commands in vi. If the terminal's
terminfo or termcap description is complete, vi will be able to
recognize these keys. But if it isn't, you can use the map command
to make them available to vi. These keys generally send an escape
sequence to the computer鈥攁n escape character followed by a string
of one or more other characters. In order to trap the escape, you
should press ^V before pressing the special key in the map. For
example, to map the HOME key on the keyboard of an IBM PC to a
reasonable vi equivalent, you might define the following map:

:map CTRL-V HOME 1G

This appears on your screen as:

:map ^[[H 1G

Similar map commands display as follows:

:map CTRL-V END G

displays

:map ^[[Y G:map CTRL-V PAGE UP ^F
displays

:map ^[[V ^F:map CTRL-V PAGE DOWN ^B
displays

:map ^[[U ^B

You'll probably want to place these maps in your .exrc file. Note
that if a special key generates a long escape sequence (containing
multiple non-printing characters), ^V quotes only the initial escape
character, and the map doesn't work. You will have to find the
entire escape sequence (perhaps from the terminal manual) and
type it in manually, quoting at the appropriate points, rather than
simply pressing ^V and then the key.

7.3.9 Mapping Multiple Input Keys
Mapping multiple key strokes is not restricted just to function keys.
You can also map sequences of regular keystrokes. This can help
make it easier to enter certain kinds of text, such as SGML or HTML.

论坛徽章:
0
127 [报告]
发表于 2008-06-11 15:05 |只看该作者
Here are some :map commands, thanks to Jerry Peek, co-author of
O'Reilly's Learning the UNIX Operating System, which make it
easier to enter SGML markup. (The lines beginning with a double
quote are comments. This is discussed below in Section 7.4.4.)

" ADR: need this
:set noremap
" bold:
map! =b </emphasis>^[F<i<emphasis role=bold>
map =B i<emphasis role=bold>^
[
map =b a</emphasis>^
[
" Move to end of next tag:
map! =e ^[f>
a
map =e f>
" footnote (tacks opening tag directly after cursor in
text-input mode)
:
map! =f <footnote>^M<para>^M</para>^M</footnote>^[kO
" Italics ("emphasis")
:
map! =i </emphasis>^[F<i<emphasis>
map =I i<emphasis>^
[
map =i a</emphasis>^
[
" paragraphs:
map! =p ^[jo<para>^M</para>^[
O
map =P O<para>^
[
map =p o</para>^
[
" less-than:
map! *l &lt;
..
.


Using these commands, to enter a footnote you would enter insert
mode, and type =f. vi would then insert the opening and closing
tags, and leave you in insert mode between them:

All the world's a stage.<footnote>


<para>
_
</para>
</footnote>


Needless to say, these macros proved quite useful during the
development of this book.

7.3.10 @-Functions
Named buffers provide yet another way to create "macros"鈥

论坛徽章:
0
128 [报告]
发表于 2008-06-11 15:06 |只看该作者
If you type a command line in your text (either a vi sequence or an
ex command preceded by a colon), then delete it into a named
buffer, you can execute the contents of that buffer with the @
command. For example, open a new line and enter:


This will appear as:

cwgadfly^[

on your screen. Press ESC again to exit insert mode, then delete the
line into buffer g by typing "gdd. Now whenever you place the
cursor at the beginning of a word and type @g, that word in your
text will be changed to gadfly.

Since @ is interpreted as a vi command, a dot (.) will repeat the
entire sequence, even if the buffer contains an ex command. @@
repeats the last @, and u or U can be used to undo the effect of @.

This is a simple example. @-functions are useful because they can
be adapted to very specific commands. They are especially useful
when you are editing between files, because you can store the
commands in their named buffers and access them from any file
you edit. @-functions are also useful in combination with the global
replacement commands discussed in Chapter 6.

7.3.11 Executing Buffers from ex
You can also execute text saved in a buffer from ex mode. In this
case, you would enter an ex command, delete it into a named
buffer, and then use the @ command from the ex colon prompt. For
example, enter the following text:

ORA publishes great books.
ORA is my favorite publisher.
1,$s/ORA/O'Reilly \& Associates/
g


With your cursor on the last line, delete the command into the gbuffer: "gdd. Move your cursor to the first line: kk. Then execute
the buffer from the colon command line: gRETURN. Your screen
should now look like this:

O'Reilly & Associates publishes great books.
O'Reilly & Associates is my favorite publisher.

论坛徽章:
0
129 [报告]
发表于 2008-06-11 15:06 |只看该作者
Some versions treat * identically to @ when used from the ex
command line. In addition, if the buffer character supplied after the
@ or * command is *, the command will be taken from the default
(unnamed) buffer.

7.4 Using ex Scripts
Certain ex commands you use only within vi, such as maps,
abbreviations, and so on. If you store these commands in your .exrc
file, the commands will automatically be executed when you invoke

vi. Any file that contains commands to execute is called a script.
The commands in a typical .exrc script are of no use outside vi.
However, you can save other ex commands in a script, and then
execute the script on a file or on multiple files. Mostly you'll use
substitute commands in these external scripts.

For a writer, a useful application of ex scripts is to ensure
consistency of terminology鈥攐r even of spelling鈥攁cross a document
set. For example, let's assume that you've run the UNIX spellcommand on two files and that the command has printed out the
following list of misspellings:

$ spell sect1 sect2chmod
ditroff
myfilethier
writeable

As is often the case, spell has flagged a few technical terms and
special cases it doesn't recognize, but it has also identified two
genuine spelling errors.

Because we checked two files at once, we don't know which files the
errors occurred in or where they are in the files. Although there are
ways to find this out, and the job wouldn't be too hard for only two
errors in two files, you can easily imagine how time-consuming the
job could grow to be for a poor speller or for a typist proofing many
files at once.

To make the job easier, you could write an ex script containing the
following commands:

%s/thier/their/g%s/writeable/writable/gwq

论坛徽章:
0
130 [报告]
发表于 2008-06-11 15:07 |只看该作者
Assume you've saved these lines in a file named exscript. The script
could be executed from within vi with the command:

:so exscript

or the script can be applied to a file right from the command line.
Then you could edit the files sect1 and sect2 as follows:

$ ex - sect1 < exscript$ ex - sect2 < exscript

The minus sign following the invocation of ex tells it to suppress the
normal terminal messages.[7]

[7] According to the POSIX standard, ex should use -s instead of - as shown here. Typically, for backwards
compatibility, both versions are accepted.
If the script were longer than the one in our simple example, we
would already have saved a fair amount of time. However, you
might wonder if there isn't some way to avoid repeating the process
for each file to be edited. Sure enough, we can write a shell script
that includes, but generalizes, the invocation of ex, so that it can be
used on any number of files.

7.4.1 Looping in a Shell Script
You may know that the shell is a programming language as well as
a command-line interpreter. To invoke ex on a number of files, we
use a simple type of shell script command called the for loop. A for
loop allows you to apply a sequence of commands for each
argument given to the script. (The for loop is probably the single
most useful piece of shell programming for beginners. You'll want to
remember it even if you don't write any other shell programs.)

Here's the syntax of a for loop:

for variable in list
do

command(s)

done

For example:

for file in $*
do
ex - $file < exscriptdone
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP