INSERT

*insert.txt*    For Vim version 6.4.  最近更新: 2006年2月


                  VIM 参考手册    by Bram Moolenaar
                                译者: Willis
                                http://vimcdoc.sf.net


                                                *Insert* *Insert-mode*
插入和替换文本                                  *mode-ins-repl*

本文件主要讨论插入和替换模式。最后讨论一些其它方式插入文本的命令。

最常用的命令的总览可以在用户手册第 24 章 |usr_24.txt| 找到。

1. 特殊键                                               |ins-special-keys|
2. 特殊的特殊键                                         |ins-special-special|
3. 'textwidth' 和 'wrapmargin' 选项                     |ins-textwidth|
4. 'expandtab'、'smarttab' 和 'softtabstop'  选项       |ins-expandtab|
5. 替换模式                                             |Replace-mode|
6. 虚拟替换模式                                         |Virtual-Replace-mode|
7. 插入模式补全                                         |ins-completion|
8. 插入模式命令                                         |inserting|
9. Ex 插入命令                                          |inserting-ex|
10. 插入文件                                            |inserting-file|

关于如何移动光标到没有字符的位置,另见 'virtualedit'。对编辑表格有用。


1. 特殊键 *ins-special-keys*

在插入和替换模式里,以下字符有特殊含义;其它字符被直接插入。要插入这些特殊字符 到缓冲区里,在前面加上 CTRL-V。要插入 <Nul> 字符,使用 "CTRL-V CTRL-@" 或者 "CTRL-V 000"。在有的系统上,你必须使用 "CTRL-V 003" 来插入 CTRL-C注意: 如果 CTRL-V 被映射,你也许会经常使用 CTRL-Q 来代替 |i_CTRL-Q|。 如果插入时你在特殊的语言模式下工作,参见 'langmap' 选项 |'langmap'| 了解如何避 免反复进出这些模式。 如果置位了 'insertmode',<Esc> 和一些其它的键有另外的含义。见 |'insertmode'|。 字符 动作

                                                *i_CTRL-[* *i_<Esc>*
<Esc>CTRL-[ 结束插入或替换模式,回到普通模式。结束缩写。
                注意: 如果你很难在键盘上敲上 <Esc> 键,训练自己使用 CTRL-[*i_CTRL-C*
CTRL-C          退出插入模式,回到普通模式。不检查缩写。

                                                *i_CTRL-@*
CTRL-@          插入最近插入的文本,并停止插入 {Vi: 仅当敲入第一个字符时,而且
                只限于前 128 个字符}
                                                *i_CTRL-A*
CTRL-A          插入最近插入的文本。{Vi 无此功能}

                                                *i_CTRL-H* *i_<BS>* *i_BS*
<BS>CTRL-H  删除光标前的字符 (关于连接行,见 |i_backspacing|)。
                如果你的 <BS> 键不正确,见 |:fixdel|。{Vi: 不删除自动的缩进}
                                                *i_<Del>* *i_DEL*
<Del>           删除光标下的字符。如果光标在行尾,并且 'backspace' 选项包括
                "eol",删除 <EOL>; 下一行就此附加于当前行之后。.
                如果你的 <Del> 键不正确,见 |:fixdel|。{Vi: 不删除自动的缩进}
                {Vi 无此功能}
                                                *i_CTRL-W*
CTRL-W          删除光标前的单词 (关于连接行,见 |i_backspacing|)。关于单词的
                定义,见 |word-motions| 关于 "单词动作" 的定义。
                                                *i_CTRL-U*
CTRL-U          删除光标所有输入的字符 (关于连接行,见 |i_backspacing|)。

                                                *i_CTRL-I* *i_<Tab>* *i_Tab*
<Tab>CTRL-I 插入制表。如果打开 'expandtab' 选项,等价数目的空格被插入 (使
                用 CTRL-V <Tab> 避免这种扩展: 如果 CTRL-V 被映射,可以使用
                CTRL-Q <Tab>。|i_CTRL-Q|)。另见 'smarttab' 选项和
                |ins-expandtab|。
                                                *i_CTRL-J* *i_<NL>*
<NL>CTRL-J  开始新行。
                                                *i_CTRL-M* *i_<CR>*
<CR>CTRL-M  开始新行。
                                                *i_CTRL-K*
CTRL-K {char1} [char2]
                输入二合字母 (见 |digraphs|)。当 {char1} 为特殊字符时,该键的
                键码以 <> 形式插入。例如字符串 "<S-Space>" 可以这样输入:
                <C-K><S-Space> (两个键)。两个键都不考虑映射。 {Vi 无此功能}

CTRL-N          查找下一个关键字 (见 |i_CTRL-N|)。{Vi 无此功能}
CTRL-P          查找上一个关键字 (见 |i_CTRL-P|)。{Vi 无此功能}

CTRL-R {0-9a-z"%#*+:.-=}                                        *i_CTRL-R*
                插入寄存器内容。在输入 CTRL-R 和第二个字符之间,'"' 会显示出
                来,以提示你需要输入寄存器的名字。文本插入方式和直接输入相同,
                但不使用映射和缩写。如果设置了 'textwidth'、'formatoptions' 或
                'autoindent',插入的结果会受到影响。这和使用 "p" 命令和用鼠标
                粘贴文本不同。
                特殊寄存器:
                        '"'     无名寄存器,包含最近删除或抽出的文本
                        '%'     当前文件名
                        '#'     轮换文件名
                        '*'     剪贴板内容 (X11: 主选择)
                        '+'     剪贴板内容
                        '/'     最近的搜索模式
                        ':'     最近的命令行
                        '.'     最近插入的文本
                        '-'     最近的行内 (少于一行) 删除
                        '='     表达式寄存器;你会被提示输入一个表达式 (见
                                |expression|)
                关于寄存器见 |registers|。{Vi 无此功能}

CTRL-R CTRL-R {0-9a-z"%#*+/:.-=}                        *i_CTRL-R_CTRL-R*
                插入寄存器内容。和单个 CTRL-R 类似,但是文本按本义插入,而不是
                像键盘输入那样。这意味着如果寄存器包含 <BS> 这样的字符,结果会
                不同。例如,如果寄存器包含 "ab^Hc":
        CTRL-R a                产生 "ac"。
        CTRL-R CTRL-R a         产生 "ab^Hc"。
                'textwidth'、'formatoptions' 等等选项仍然适用。如果你连这些都
                想避免,使用 "<C-R><C-O>r",见下。
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                {Vi 无此功能}

CTRL-R CTRL-O {0-9a-z"%#*+/:.-=}                        *i_CTRL-R_CTRL-O*
                按本义插入寄存器内容,并且不进行自动缩进。和鼠标粘贴文本相同
                |<MiddleMouse>|。
                不会替换字符!
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                {Vi 无此功能}

CTRL-R CTRL-P {0-9a-z"%#*+/:.-=}                        *i_CTRL-R_CTRL-P*
                按本义插入寄存器内容,修正缩进,和 |[<MiddleMouse>| 类似。
                不会替换字符!
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                {Vi 无此功能}

                                                *i_CTRL-T*
CTRL-T          在当前行开始处插入一个 shiftwidth 的缩进。缩进总是取整到
                'shiftwidth' 的倍数 (这是 vi 兼容的)。{Vi: 只有在缩进内部才能用}
                                                *i_CTRL-D*
CTRL-D          在当前行开始处删除一个 shiftwidth 的缩进。缩进总是取整到
                'shiftwidth' 的倍数 (这是 vi 兼容的)。{Vi: CTRL-D 只有在使用自
                动缩进之后才有效}
                                                *i_0_CTRL-D*
0 CTRL-D        删除所有当前行的缩进。{Vi: CTRL-D 只有在使用自动缩进之后才有
                效}
                                                *i_^_CTRL-D*
^ CTRL-D        删除当前行的所有缩进。缩进在下一行上恢复。这可以用于插入卷标。
                {Vi: CTRL-D 只有在使用自动缩进之后才有效}

                                                *i_CTRL-V*
CTRL-V          如果下一个是非数字,按本义插入。对特殊键而言,插入其终端代码。
                不然,输入的是字符的十、八或十六进制值。|i_CTRL-V_digit|。
                CTRL-V 之后紧接着输入的字符不经过映射。{Vi: 没有十进制字节输
                入}
                注意: 当 CTRL-V 被映射时 (例如,用来粘贴文本),你可能经常需要
                使用 CTRL-Q 来代替。|i_CTRL-Q|。

                                                *i_CTRL-Q*
CTRL-Q          Same as CTRL-V.
                注意: 有的终端连接会吃掉 CTRL-Q,这时它就能工作了。在 GUI 上没
                有问题。

CTRL-X          进入 CTRL-X 模式,一个子模式。那里你可以给出命令来补全单词或者
                滚动窗口。见 |i_CTRL-X| 和 |ins-completion|。{Vi 无此功能}

                                                *i_CTRL-E*
CTRL-E          插入光标下面的字符。{Vi 无此功能}
                                                *i_CTRL-Y*
CTRL-Y          插入光标上面的字符。{Vi 无此功能}
                注意 CTRL-ECTRL-Y 不使用 'textwidth',从而可以从长行里复制
                字符。

                                                *i_CTRL-_*
CTRL-_          切换语言,如下:
                -  在从右到左的窗口里,切换 revins 和 nohkmap,因为在这种情况
                   下英语的输入可能就是倒过来的。
                -  在非从右到左的窗口里,切换 revins 和 hkmap。因为希伯来语等
                   语种可能是倒过来输入的。

                CTRL-_ 移动光标到输入文本的尾部。

                该命令只有在 'allowrevins' 选项置位的时候才有效。
                请参考 |rileft.txt|,那里可以了解到更多有关从右到左模式的信
                息。{Vi 无此功能}
                只有在编译时加入 |+rightleft| 特性才有效 (这不是缺省)。
                                                *i_CTRL-^*
CTRL-^          切换语言字符输入的使用方式。
                如果定义了语言映射 |:lmap|:
                - 如果 'iminsert' 为 1 (使用 langmap 映射),变成 0 (不使用
                  langmap 映射)。
                - 如果 'iminsert' 为其它值,变成 1,这样打开了 langmap 映射。
                如果没有定义语言映射:
                - 如果 'iminsert' 为 2 (使用输入方法 (Input Method)),变成 0
                  (不使用输入方法)。
                - 如果 'iminsert' 为其它值,变成 2,从而打开输入方法。
                如果 "b:keymap_name" 变量的值设为 1,'keymap' 选项或者
                "<lang>" 出现在状态行上。语言映射通常用来输入不同于键盘上能直
                接产生的字符。'keymap' 选项用来安装若干完整的映射表。{Vi 无此
                功能}

                                                *i_CTRL-]*
CTRL-]          切换缩写,不插入字符。{Vi 无此功能}

                                                *i_<Insert>*
<Insert>        切换插入和替换模式。{Vi 无此功能}


                                                *i_backspacing*
<BS>CTRL-WCTRL-U 的效果决定于 'backspace' 选项 (除非置位了 'revins')。这
时一个逗号分隔的项目列表:

项目        动作 
indent      允许退格删除自动缩进
eol         允许退格删除换行符 (连接行)
start       允许退格删除插入开始之前的位置;CTRL-WCTRL-U 在开始位置停止

如果 'backspace' 为空,则使用 Vi 兼容的退格方式。不能退格删除自动缩进、回到第
一列之前、或者超过插入开始的地方。

为了后向兼容起见,取值 "0"、"1" 和 "2" 也是允许的,见 |'backspace'|。

如果 'backspace' 选项的确包含 "eol",光标在第一列,而使用了这三个键中的一个,
当前行会和上一行连接。这实际上删除了光标之前的 <EOL>{Vi: 不会跨行,不会删除插入开始位置之前的内容}

                                                *i_CTRL-V_digit*
使用 CTRL-V,字符的十、八、十六进制值可以直接输入。这样你可以输入任何字符,除
了换行符 (<NL>,其值为 10)。有五个方法可以输入字符值:

第一个字符      模式           最大字符数   最大值 
(无)            十进制             3            255
o 或 O          八进制             3            255
x 或 X          十六进制           2            ff       (255)
u               十六进制           4            ffff     (65535)
U               十六进制           8            7fffffff (2147483647)

通常你会输入最大数目的字符数。这样,要输入空格 (值为 32),你需要键入
<C-V>032。你可以忽略开头的零,这时,数字之后的字符必须不能再是数字。其它模式下
也一样: 一旦你输入在该模式下不合法的字符,那么这之前的值就会被使用,而 "非法"
的这个字符以正常的方式继续处理。

如果你输入的值为 10,在文件中最后会以 0 出现。10 是 <NL>,内部被用来代表 <Nul>
字符。在写入文件时,<NL> 字符被翻译成 <Nul>。而在每行的最后写入 <NL>。所以,如
果你想在文件中插入 <NL> 字符,你需要使用换行。

                                                *i_CTRL-X* *insert_expand*
CTRL-X 进入一个子模式,那里可以使用若干命令。绝大多数命令执行关键字补全;见
|ins-completion|。只有在 Vim 编译时加入 |+insert_expand| 特性才能使用这些功能。

有两个命令可以在不退出插入模式的前提下上下滚动窗口:

                                                *i_CTRL-X_CTRL-E*
CTRL-X CTRL-E           窗口滚动上移一行。

                                                *i_CTRL-X_CTRL-Y*
CTRL-X CTRL-Y           窗口滚动下移一行。

按了 CTRL-X 以后,每个 CTRL-E (CTRL-Y) 滚动窗口上 (下) 移一行,除非这使得光标
不得不离开当前文件中所在的位置。一旦按了另外一个键,CTRL-X 模式就会退出,而回
到插入模式下解释该键。



2. 特殊的特殊键 *ins-special-special*

一些的键是特殊的。它们停止当前的插入,做一些事情,然后重新插入。这意味着你可以 不脱离插入模式的情况下做一些事情。这适合于经常使用插入模式的用户,就像编辑器没 有单独的普通模式一样。这时,也可以设置 'backspace' 选项为 "indent,eol,start" 还有置位 'insertmode' 选项。如果你想给功能键映射到一个命令,你可以使用 CTRL-O。 这些键前后的改动 (插入或者删除字符) 可以分别撤销。只有最后的改动可以重做,而其 行为和 "i" 命令相当。 字符 动作

<Up>            光标上移一行                                 *i_<Up>*
<Down>          光标下移一行                                 *i_<Down>*
CTRL-G <Up>     光标上移一行,到插入开始时所在的列           *i_CTRL-G_<Up>*
CTRL-G k        光标上移一行,到插入开始时所在的列           *i_CTRL-G_k*
CTRL-G CTRL-K   光标上移一行,到插入开始时所在的列           *i_CTRL-G_CTRL-K*
CTRL-G <Down>   光标下移一行,到插入开始时所在的列           *i_CTRL-G_<Down>*
CTRL-G j        光标下移一行,到插入开始时所在的列           *i_CTRL-G_j*
CTRL-G CTRL-J   光标下移一行,到插入开始时所在的列           *i_CTRL-G_CTRL-J*
<Left>          光标左移一个字符                             *i_<Left>*
<Right>         光标右移一个字符                             *i_<Right>*
<S-Left>        光标反向一个单词 (像 "b" 命令那样)           *i_<S-Left>*
<C-Left>        光标反向一个单词 (像 "b" 命令那样)           *i_<C-Left>*
<S-Right>       光标正向一个单词 (像 "w" 命令那样)           *i_<S-Right>*
<C-Right>       光标正向一个单词 (像 "w" 命令那样)           *i_<C-Right>*
<Home>          光标移到该行第一个字符                       *i_<Home>*
<End>           光标移到该行最后一个字符                     *i_<End>*
<C-Home>        光标移到该文件第一个字符                     *i_<C-Home>*
<C-End>         光标移到该文件最后一个字符                   *i_<C-End>*
<LeftMouse>     光标移动鼠标点击处                           *i_<LeftMouse>*
<S-Up>          上翻窗口一页                                 *i_<S-Up>*
<PageUp>        上翻窗口一页                                 *i_<PageUp>*
<S-Down>        下翻窗口一页                                 *i_<S-Down>*
<PageDown>      下翻窗口一页                                 *i_<PageDown>*
<MouseDown>     向下滚动三行                                 *i_<MouseDown>*
<S-MouseDown>   向下滚动一个整页                             *i_<S-MouseDown>*
<MouseUp>       向上滚动三行                                 *i_<MouseUp>*
<S-MouseUp>     向上滚动一个整页                             *i_<S-MouseUp>*
CTRL-O          执行命令,然后返回到插入模式                 *i_CTRL-O*
CTRL-G u        打断撤销序列,开始新的改变                   *i_CTRL-G_u*


注意: 如果光标键把你带出插入模式,查查 'noesckeys' 选项。

CTRL-O 命令有时有副作用: 如果光标在行尾之后,它会先被移动该行最后一个字符上。
在映射里,通常更好的方法是使用 <Esc>  (先在文本中放一个 "x",<Esc> 这时总会把
光标放到它的上面)

不是在所有的终端上都能用 Shift + 光标键。

另外一个副作用是 "i" 或 "a" 命令之前指定的计数会被忽略。这是因为要实现 CTRL-O
之后的命令的重复执行太复杂了。

一个使用 CTRL-G u 的例子:

        :inoremap <C-H> <C-G>u<C-H>

它重定义退格键开始新的撤销序列。你可以撤销退格键的效果,而不会改变你之前输入的
内容,就像  CTRL-O u 那样。

如果正确设置 'whichwrap' 选项,在一行的第一个/最后一个字符上按 <Left><Right> 键使得光标回绕到上一行/下一行。

CTRL-G j 和 CTRL-G k 命令可以用来在某一列前插入文本。例如:
   int i;
   int j;
把光标定位在第一个 "int" 上,输入 "istatic<C-G>j       "。结果是:
   static int i;
          int j;
要把相同的文本插入在每行的某列之前,使用可视列块命令 "I" |v_b_I|。


3. 'textwidth' 和 'wrapmargin' 选项 *ins-textwidth*

'textwidth' 选项可以用来在行变得很长之前自动断行。设置 'textwidth' 选项为希望 的最大行长。如果你输入更多字符 (不是空格或者制表),最后一个单词会放在一个新行 上 (除非这是该行唯一一个单词)。如果你设置 'textwidth' 为 0,关闭该特性。 'wrapmargin' 选项做的事情基本相同。区别在于 'textwidth' 是一个固定的宽度,而 'wrapmargin' 根据屏幕的宽度设置。如果设置 'wrapmargin',这等价于 'textwidth' 设为 (columns - 'wrapmargin'),其中 columns 是屏幕的宽度。 如果同时设置 'textwidth' 和 'wrapmargin',使用 'textwidth'。 如果你并不真的想断开行,而只是想文本行在合适的位置回绕,见 'linebreak' 选项。 文本行只有在插入模式下或者附加到行后的时候才会自动断开。在替换模式下,只要行的 长度没有变,就不会断行。 长行在你输入一个出现在边界之后的非空白字符的时候断开。什么时候断行的限制还可以 通过在 'formatoptions' 选项增加如下字母决定: "l" 断行只有在插入开始时文本行的长度不超过 'textwidth' 才会发生。 "v" 只有在当前插入命令中输入的空白字符上才会断行。这是和 Vi 最兼容的行为。 "lv" 断行只有在插入开始时文本行的长度不超过 'textwidth' 并且在当前插入命令中输 入的空白字符上才会发生。和 "l" 唯一的不同在超过 'textwidth' 边界之后输入 非空白字符的时候。 如果你想排版文本块,可以使用 "gq" 操作符。输入 "gq" 和可以移动光标到块尾的移动 命令。在许多情况下,命令 "gq}" 会做你想要做的事情 (排版直到段落尾部)。或者,你 可以使用 "gqap"。它会排版整个段落,和当前光标所在的位置无关。或者,你可以使用 可视模式: 敲击 "v",移动到块尾,然后输入 "gq"。另见 |gq|。

4. 'expandtab'、'smarttab' 和 'softtabstop' 选项 *ins-expandtab*

如果打开 'expandtab' 选项,空格可以用来填充制表键的空白位置。如果你需要输入一 个真正的 <Tab>,先输入 CTRL-V (用 CTRL-Q 如果 CTRL-V 被映射的话 |i_CTRL-Q|)。 缺省 'expandtab' 选项是关闭的。注意 在替换模式里,一个字符被多个空格字符所代 替。结果是,行内的字符数会增加。退格键只会一次删一个空格键。原来的字符只有在一 个空格 (最后一个) 上退格才能得回来 {Vi 没有 'expandtab' 选项} *ins-smarttab* 当 'smarttab' 选项打开时,<Tab> 在行首插入 'shiftwidth' 个位置,而在其它地方插 入 'tabstop' 个。这意味着经常会插入空格而不是 <Tab> 字符。当 'smarttab' 关闭 时,<Tab> 总是插入 'tabstop' 个位置,而 'shiftwidth' 只有在 ">>" 和类似的命令 中才会用到。{Vi 无此功能} *ins-softtabstop* 如果 'softtabstop' 选项不为零,<Tab> 插入 'softtabstop' 个位置,而过去用来删除 空格的 <BS>,现在会删除 'softtabstop' 个位置。感觉上, 'tabstop' 被设成了 'softtabstop' 的值,但实际上一个真正的 <Tab> 字符还是占据 'tabstop' 个位置。从 而,你的文件在别的应用程序里看起来还是正确的。 如果 'softtabstop' 不为零,<BS> 会试图删除尽量多的空白,以便能够回到往前 'softtabstop' 的位置,除非前面一个插入的字符正好就是一个空格,这时它只会删除光 标前的那个字符。否则,你不一定总能删除光标前的一个字符。你需要先删除 'softabstop' 个字符,然后再输入额外的空格,以到达你想要的地方。

5. 替换模式 *Replace* *Replace-mode* *mode-replace*

在普通模式里输入 "R" 命令进入替换模式。 在替换模式里,行内的单个字符在你输入字符的时候被删除。如果没有字符可以删了 (在 行尾),输入的字符被附加 (和插入模式一样)。这样,一行内的字符数保持不变,直到你 到达行尾为止。如果输入了 <NL>,插入一个换行符,但不会删除任何字符。 要小心 <Tab> 字符。如果你输入一个正常的打印字符在它上面,字符数仍然一样,但是 列数看起来少了。 如果你在替换模式下删除字符 (用 <BS>CTRL-WCTRL-U),实际发生的事是你删除了 改变。被替换的字符被复原了。如果你的输入超过已有的部分,新增的字符被删除了。实 际上,这可以看作是一次一个字符的撤销。 如果打开了 'expandtab' 选项,<Tab> 会用多个空格替换一个字符。结果是,行内的字 符数增加了。退格键只能一次删一个空格。原来的字符只有在一个空格 (最后一个) 上退 格才能得回来 {Vi 没有 'expandtab' 选项}

6. 虚拟替换模式 *vreplace-mode* *Virtual-Replace-mode*

在普通模式里输入 "gR" 命令进入虚拟替换模式。 {only 只有在编译时加入 +vreplace 特性才会有效} {Vi 没有虚拟替换模式} 虚拟替换模式和替换模式类似,但不是替换文件里的实际字符,而是替换屏幕的领地。这 样,文件里的字符看起来不会移动。 所以,如果你输入了 <Tab>,它会替换多个普通的字符,而如果你在 <Tab> 上输入字 母,它可能什么都没有代替,因为 <Tab> 还是会占据相同的位置。 输入 <NL> 不是导致文件后面的字符看起来在移动。结果是,当前行的后面部分被 <NL> 所替换 (也就是,它们被删除),而替换继续在下一行进行。新行_不_会被插入,除非你 到达文件尾部之后。 输入 CTRL-TCTRL-D 会看到有趣的效果。光标前面的字符向一边移动,跟平常一样, 但是光标后面的字符保持不动。CTRL-T 会隐藏一些被移动字符遮盖的旧行,但是 CTRL-D 会重新让它们显现出来。 和替换模式一样,使用 <BS> 等会恢复被替换的字符。即使和 'smartindent'、CTRL-TCTRL-D、'expandtab'、'smarttab'、'softtabstop' 等一起使用的效果也是如此。 在 'list' 模式下,虚拟替换模式的行为和不在 'list' 模式下一样,除非 'cpoptions' 里设置了 "L"。 注意 唯一不在光标位置上的字符看起来在移动的可能是在 'list' 模式下,偶尔也会在 置位 'wrap' 的时候出现 (这时行改变长度,使得比屏幕宽度更窄或者更宽),难得也会 在输入 CTRL 字符的时候。CTRL 字符占据两个屏幕位置。如果用两个普通字符替换,第 一个会被插入,而第二个会替换 CTRL 字符。 该模式对编辑 <Tab> 分隔表格列的时候很有用,因为输入新的数据的时候同时还能保持 所有的列对齐。

7. 插入模式补全 *ins-completion*

在插入和替换模式下,有若干命令可以补全输入的部分关键字或者行。这可以用于使用复 杂关键字的场合 (例如,函数名里有大写字母或者下划线)。 如果编译时关闭了|+insert_expand| 特性,这些功能都不可用。 补全可以是针对: 1. 整行 |i_CTRL-X_CTRL-L| 2. 当前文件内的关键字 |i_CTRL-X_CTRL-N| 3. 'dictionary' 的关键字 |i_CTRL-X_CTRL-K| 4. 'thesaurus' 的关键字,同义词风格 |i_CTRL-X_CTRL-T| 5. 当前和头文件内的关键字 |i_CTRL-X_CTRL-I| 6. 标签 |i_CTRL-X_CTRL-]| 7. 文件名 |i_CTRL-X_CTRL-F| 8. 定义或宏 |i_CTRL-X_CTRL-D| 9. Vim 命令 |i_CTRL-X_CTRL-V| 10. 'complete' 的关键字 |i_CTRL-N| 所有这些 (除了 10 以外) 都通过 CTRL-X 模式完成。这是插入和替换模式的一个子模 式。你可以输入 CTRL-X 和一个 CTRL-X 命令进入 CTRL-X 模式。要退出,输入不合法的 CTRL-X 模式的命令。合法的键包括 CTRL-X 命令本身,CTRL-N (下一个) 和 CTRL-P (前 一个)。 如果你想调整匹配的大小,另见 'infercase' 选项。 注意: CTRL-X 模式下合法的键不经过映射。这使得 ":map ^F ^X^F" 能够工作 (其中 ^F 是 CTRL-F 而 ^X 是 CTRL-X)。能够退出的 CTRL-X 模式的键 (任何不合法 CTRL-X 模式 命令的键) 则经过映射。 另外,通过 'complete' 的补全也使用映射。 建议使用以下映射来使得输入补全命令简单一点 (不过它们可能屏蔽其它的命令): :inoremap ^] ^X^] :inoremap ^F ^X^F :inoremap ^D ^X^D :inoremap ^L ^X^L 一个特例是,执行寄存器插入的 CTRL-R (见 |i_CTRL-R|) 不会退出 CTRL-X 模式。这主 要是为了允许通过使用 '=' 寄存器来调用若干函数来决定下一个操作。如果该寄存器的 内容 (或者 '=' 寄存器计算的结果) 不是合法的 CTRL-X 模式键,那么就会退出 CTRL-X 模式,如同键盘输入这些内容一样。 例如,下面的程序会如此映射 <Tab>: 如果当前行只有空白,就插入 <Tab>,不然就开始 或继续 CTRL-N 补全操作: function! CleverTab() if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$' return "\<Tab>" else return "\<C-N>" endfunction inoremap <Tab> <C-R>=CleverTab()<CR> 补全整行 *compl-whole-line* *i_CTRL-X_CTRL-L* CTRL-X CTRL-L 反向搜索和当前行光标前字符序列完全相同的行。忽略缩进。 找到的行插入在光标的前面。 'complete' 选项用来决定匹配在哪个缓冲区里搜索。但只限 于已载入的缓冲区。 CTRL-LCTRL-P 反向搜索前一个匹配行。替换上一次匹配的行。 CTRL-N 正向搜索下一个匹配行。替换上一次匹配的行。 CTRL-X CTRL-L 在扩展一行以后,你可以通过接着输入 CTRL-X CTRL-L 得到 紧接着匹配行之后的行,直到见到两个 CTRL-X 为止。 补全当前文件内的关键字 *compl-current* *i_CTRL-X_CTRL-P* *i_CTRL-X_CTRL-N* CTRL-X CTRL-N 正向搜索以光标前面的关键字开始的单词。找到的关键字插入 在光标的前面。 CTRL-X CTRL-P 反向搜索以光标前面的关键字开始的单词。找到的关键字插入 在光标的前面。 CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。 CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。 CTRL-X CTRL-NCTRL-X CTRL-P 继续使用 CTRL-X CTRL-NCTRL-X CTRL-P 会复制上次本类 型补全在其它上下文里扩展的单词之后紧跟的单词,直到见到 两个 CTRL-X 为止。 如果在光标的前面有一个关键字 (由字母字符和 'iskeyword' 指定的字符组成的名字), 它的前面再加上 "\<" (含义: 单词开始) 就被用作搜索模式。否则 "\<\k\k" 被用作搜 索模式 (任何包含至少两个字符的关键字的开始)。 在替换模式里,替换的字符数目决定于匹配字符串的长度。这和直接在替换模式下键盘输 入经过替换的字符串类似。 如果光标前面不是一个合法的关键字字符,则匹配任何至少有两个字符的关键字。 例如,要得到: printf("(%g, %g, %g)", vector[0], vector[1], vector[2]); 只需输入: printf("(%g, %g, %g)", vector[0], ^P[1], ^P[2]); 相同的补全内容多次重复会被跳过;这样每次 CTRL-NCTRL-P 都会插入不同的匹配 (除非只有一个匹配的关键字)。 永远不会得到单个字符的匹配,因为它们通常不是你真想要的。 例如,要得到: printf("name = %s\n", name); 或者: printf("name = %s\n", n^P); 甚至: printf("name = %s\n", ^P); '\n' 中的 'n' 被跳过。 在扩展完一个词后,你可以使用 CTRL-X CTRL-PCTRL-X CTRL-N 得到紧跟在扩展词 之后的单词。这些序列搜索刚刚扩展的文本,并且继续扩展之,使之包括另外一个词。这 可以用于你需要重复一系列复杂的单词的场合。尽管 CTRL-PCTRL-N 只找至少两个字 符的字符串,CTRL-X CTRL-PCTRL-X CTRL-N 可以用来扩展只有一个字符的单词。 例如,要得到: M&eacute;xico 你可以输入: M^N^P^X^P^X^P CTRL-N 开始一个扩展,而 CTRL-P 回到单个字符 "M",然后后面的两个 CTRL-X CTRL-P 分别得到 "&eacute" 和 ";xico"。 如果上次的扩展因为超过 'textwidth' 被分割,则只会使用当前行的文本。 如果匹配在行尾,那么下一行的第一个单词会被插入,而且显示消息 "word from next line"。如果该词被接受,那么下个 CTRL-X CTRL-P 或者 CTRL-X CTRL-N 会搜索那些以 这个单词开始的行。 补全 'dictionary' 的关键字 *compl-dictionary* *i_CTRL-X_CTRL-K* CTRL-X CTRL-K 根据 'dictionary' 选项给出的文件搜索光标前关键字开始的 单词。这和 CTRL-N 类似,只不过搜索的是字典文件,而不是 当前文件。找到的关键字插入在光标之前。这可能很慢,因为 在第一个匹配用到之前,所有的匹配都会被找到。缺省, 'dictionary' 选项为空。 要得到哪里能找单词列表的建议,见 'dictionary' 选项。 CTRL-KCTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。 CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。 *i_CTRL-X_CTRL-T* CTRL-X CTRL-TCTRL-X CTRL-K,类似,但稍有不同。它使用 'thesaurus' 选项,而不是 'dictionary'。如果匹配在同义词字典里找 到,同一行里其余单词也在匹配里列出,即使它们并不真的匹 配。这样一个单词可以被完全替换。 举一个例子,假想 'thesaurus' 文件有一行形如: angry furious mad enraged 把光标放在字母 "ang" 之后并输入 CTRL-X CTRL-T 会匹配单 词 "angry";继续按会把单词改为 "furious"、"mad" 等等。 其它的使用包括两种语言之间的翻译,或者用关键字给 API 函数归类。 CTRL-TCTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。 CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。 补全当前和头文件内的关键字 *compl-keyword* 'include' 选项指定如何找到含有头文件名字的行。'path' 选项用来搜索头文件。 *i_CTRL-X_CTRL-I* CTRL-X CTRL-I 搜索当前和头文件里第一个以光标前面的字母序列开始的关键 字。找到的关键字插入在光标的前面。 CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。 注意: CTRL-I<Tab> 相同,而这可能会在成功的补全之后 输入,因此不使用 CTRL-I 来搜索下一个匹配。 CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。 CTRL-X CTRL-I 继续使用 CTRL-X CTRL-I 会复制上次本类型补全在其它上下 文里扩展的单词之后紧跟的单词,直到见到两个 CTRL-X 为 止。 补全标签 *compl-tag* *i_CTRL-X_CTRL-]* CTRL-X CTRL-] 搜索第一个以光标前面的字母序列开始的标签。匹配的标签插 在光标前面。标签名可以包含字母字符和由 'iskeyword' 决 定的字符 (和关键字相同)。另见 |CTRL-]|。 'showfulltag' 选项可以用来增加标签定义前后的上下文。 CTRL-]CTRL-N 正向搜索下一个匹配的标签。替换上一次匹配的标签。 CTRL-P 反向搜索前一个匹配的标签。替换上一次匹配的标签。 补全文件名 *compl-filename* *i_CTRL-X_CTRL-F* CTRL-X CTRL-F 搜索第一个以光标前面的字母序列开始的文件。匹配的文件插 在光标前面。标签名可以包含字母字符和由 'isfname' 决 定的字符 (和关键字相同)。注意,(目前) 这里不使用 'path' 选项。 CTRL-FCTRL-N 正向搜索下一个匹配的文件名。替换上一次匹配的文件名。 CTRL-P 反向搜索前一个匹配的文件名。替换上一次匹配的文件名。 补全定义或宏 *compl-define* 'define' 选项用来指定包含定义的行。'include' 选项用来指定包含头文件名的行。 'path' 选项用来搜索头文件。 *i_CTRL-X_CTRL-D* CTRL-X CTRL-D 搜索当前和头文件里第一个以光标前面的字母序列开始的 定义 (或宏)。找到的定义名插入在光标的前面。 CTRL-DCTRL-N 正向搜索下一个匹配的定义。替换上一次匹配的定义。 CTRL-P 反向搜索前一个匹配的定义。替换上一次匹配的定义。 CTRL-X CTRL-D 继续使用 CTRL-X CTRL-D 会复制上次本类型补全在其它上下 文里扩展的单词之后紧跟的单词,直到见到两个 CTRL-X 为 止。 补全 Vim 命令 *compl-vim* 这里,补全是上下文敏感的,和命令行上的情况相似。它既能补全 Ex 命令,又能补全它 的参数。 *i_CTRL-X_CTRL-V* CTRL-X CTRL-V 猜测光标前的项目的条目,并找到第一个匹配。 注意: 如果 CTRL-V 被映射,你通常可以用 CTRL-Q 来代替 |i_CTRL-Q|。 CTRL-VCTRL-N 正向搜索下一个匹配。替换上一次匹配。 CTRL-P 反向搜索前一个匹配。替换上一次匹配。 CTRL-X CTRL-V 继续使用 CTRL-X CTRL-VCTRL-V 一样。这允许映射键来 执行 Vim 命令补全,例如: :imap <Tab> <C-X><C-V> 从不同的来源补全关键字 *compl-generic* *i_CTRL-N* CTRL-N 在 'complete' 选项给出的地方搜索下一个以光标前面的关键 字开始的单词。找到的关键字名插入在光标的前面。 *i_CTRL-P* CTRL-P 在 'complete' 选项给出的地方搜索上一个以光标前面的关键 字开始的单词。找到的关键字名插入在光标的前面。 CTRL-N 正向搜索下一个匹配的关键字。替换上一次匹配的关键字。 CTRL-P 反向搜索前一个匹配的关键字。替换上一次匹配的关键字。 CTRL-X CTRL-NCTRL-X CTRL-P 继续使用 CTRL-X CTRL-NCTRL-X CTRL-P 会复制上次本类 型补全在其它上下文里扩展的单词之后紧跟的单词,直到见到 两个 CTRL-X 为止。

8. 插入模式命令 *inserting*

下列命令可以用来在缓冲区里插入新的文本。它们都可以撤销,也可以通过 "." 命令重 复。 *a* a 在光标后附加文本 [count] 次。如果光标在空行的第一列, 启动插入模式。但在置位了 'virtualedit' 以后就不是! *A* A 在行尾附加文本 [count] 次。 <insert>*i* *insert* *<Insert>* i 在光标前插入文本 [count] 次。在插入模式里使用 CTRL-O 的时候,|i_CTRL-O| 不支持计数。 *I* I 在本行第一个非空白字符之前插入文本 [count] 次。 *gI* gI 在第一列插入文本 [count] 次。{Vi 无此功能} *gi* gi 在当前缓冲区最近一次插入模式停止的位置继续插入文本。 该位置记在 |'^| 位置标记里。如果标记在行末之后,和 "`^i" 有所差异。 该位置在插入/删除行时会自动修正。但_不_在插入/删除字符 时被修正。 使用 |:keepjumps| 命令修饰符时,不改变 |'^| 位置标记。 {Vi 无此功能} *o* o 在光标下方开启新行,并插入文本,重复 [count] 次。{Vi: 清空 [count] 个屏幕行} *O* O 在光标上方开启新行,并插入文本,重复 [count] 次。{Vi: 清空 [count] 个屏幕行} 这些命令用以开始插入文本。你可以用 <Esc> 退出插入模式。关于插入模式里的其它特 殊字符,见 |mode-ins-repl|。[count] 的效果只有在退出插入模式以后才会发生。 如果打开 'autoindent',新行的缩进从上一行得到。打开 'smartindent' 或 'cindent' 时,行的缩进根据 C 程序的要求自动调整。 'textwidth' 可以设置一行的最大宽度。如果一行过长,在添加字符时会自动添加换行 符。

9. Ex 插入命令 *inserting-ex*

*:a* *:append* :{range}a[ppend] 在指定行下方添加若干行。如果没有给出 {range},文本会在 当前行之后插入。 *:i* *:in* *:insert* :{range}i[nsert] 在指定行上方添加若干行。如果没有给出 {range},文本会在 当前行之前插入。 这两个命令会继续要求行,直到你输入了只包含 "." 的一行。小心反斜杠开始的行,见 |line-continuation|。 注意: ":append" 和 ":insert" 在 ":if" 和 ":endif" 之间不能很好的工作。 *:start* *:startinsert* :star[tinsert][!] 在执行完本命令后,启动插入模式。和普通模式下输入 "i" 类似。如果包含 !,和 "A" 类似,附加到行后。否则,就从 光标当前位置开始插入。 注意 在函数或者脚本里使用本命令时,插入只会在函数和脚 本结束的时候才会开始。 {Vi 无此功能} {only 只有在编译时带 +ex_extra 特性时才可用} *:stopi* *:stopinsert* :stopi[nsert] 尽快停止插入模式。和在插入模式时输入 <Esc> 类似。可以 用在自动命令里。示例: :au BufEnter scratch stopinsert

10. 插入文件 *inserting-file*

*:r* *:re* *:read* :r[ead] [name] 在光标下方插入文件 [name] (缺省: 当前文件)。 :{range}r[ead] [name] 在指定行下方插入文件 [name] (缺省: 当前文件)。 *:r!* *:read!* :r[ead] !{cmd} 执行 {cmd} 并把它的标准输出插入到光标下方。临时文件会 建立来保存命令输出的结果,并被读到缓冲区里。 'shellredir' 用来保存命令的输出结果,它可以设置是否包 含标准错误的输出。{cmd} 的执行和 ":!{cmd}" 类似,任何 的 '!' 会被替换成以前的命令 |:!|。 这些命令插入文件的内容,或者命令的输出结果到缓冲区里。两者都可以撤销。但不能用 "." 命令重复。它们是基于行工作的,插入从光标所在行或指定行的下方开始。要在第一 行之上插入文本,使用命令 ":0r {name}"。 在 ":read" 命令之后,光标留在第一个新行的第一个非空白处。和 Ex 模式不一样。那 里光标留在最后一个新行上 (对不起,那是为了和 Vi 兼容)。 如果文件名字通过 ":r" 给出,它成为轮换文件。这可以用来,比如说,你想编辑那个文 件的时候: ":e! #"。该特性可以通过删除 'cpoptions' 选项里的 'a' 标志位来关闭。 *file-read* 'fileformat' 选项设置文件的 <EOL> 风格: 'fileformat' 字符 名称 "dos" <CR><NL><NL> DOS 格式 "unix" <NL> Unix 格式 "mac" <CR> Mac 格式 以前使用 'textmode'。现在已经废弃了。 如果 'fileformat' 为 "dos",在 <NL> 之前的 <CR> 被忽略,而在文件尾部的 CTRL-Z 被忽略。 如果 'fileformat' 为 "mac",文件里的 <NL> 被内部表示为 <CR>。这是为了避免和用 来表示 <NUL><NL> 引起混淆。见 |CR-used-for-NL|。 如果 'fileformats' 选项不为空,Vim 试图识别 <EOL> 的类型 (见 |file-formats|)。 不过,'fileformat' 选项的值不会被改变,检测到的格式只会在读入文件时使用。 'fileencodings' 与此情形类似。 在非 MS-DOS、Win32 和 OS/2 系统上,消息 "[dos format]" 会在读入 DOS 格式的文件 时给出,以提醒你发生了不寻常的事情。 在 Macintosh、MS-DOS、Win32 和 OS/2 系统上,消息 "[unix format]" 会在读入 Unix 格式的文件时给出。 在非 Macintosh 的系统上,消息 "[Mac format]" 会在读入 Mac 格式的文件时给出。 关于如何使用 ":r !" 的一个例子: :r !uuencode binfile binfile 该命令读入 "binfile",用 uuencode 进行编码,并读入当前缓冲区。可以用于编辑包含 附带的二进制的文件的 e-mail。 *read-messages* 在读入文件时,Vim 会显示消息,显示读入文件的相关信息。以下的表格给出一些项目的 解释。其它的项目都不言自明。使用长格式还是短格式取决于 'shortmess' 选项的设 置。 长 短 含义 [readonly] {RO} 文件被写保护 [fifo/socket] 使用流 [fifo] 使用 fifo 流 [socket] 使用套接字 (socket) 流 [CR missing] 使用 "dos" 'fileformat' 读入文件的时候 出现没有前导的 CR 的 NL [NL found] 使用 "mac" 'fileformat' 读入文件的时候 出现 NL (可能是 "unix" 格式) [long lines split] 至少一行以上被分割 [NOT converted] 期待从 'fileencoding' 到 'encoding' 的 转换但是做不到 [converted] 从 'fileencoding' 到 'encoding' 的转换 完成 [crypted] 文件被解密 [READ ERRORS] 不是文件所有部分都被成功读入 vim:tw=78:ts=8:ft=help:norl:

Generated by vim2html on 2006年 07月 02日 星期日 22:43:25 UTC