EDITING

*editing.txt*   For Vim version 6.4.  最新修改: 2006年2月


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


编辑文件                                                *edit-files*

1.  简介                        |edit-intro|
2.  编辑单个文件                |edit-a-file|
3.  对话框                      |edit-dialogs|
4.  当前目录                    |current-directory|
5.  参数列表                    |argument-list|
6.  写入                        |writing|
7.  写入并退出                  |write-quit|
8.  编辑二进制文件              |edit-binary|
9.  加密                        |encryption|
10. 修改时间                    |timestamps|


1. 简介 *edit-intro*

用 Vim 编辑一个文件意味着: 1. 把该文件读到内部的缓冲区 2. 用编辑器命令修改缓冲区 3. 把缓冲区内容写回文件 *current-file* 只要你不保存缓冲区,原来的文件保持不变。如果你开始编辑一个文件 (把它的内容读到 缓冲区里),该文件名被认作 "当前文件名"。 *alternate-file* 如果已经有了另外一个当前文件名,它会成为轮换文件名。所有文件名都会被记录在文件 列表里。在你输入文件名以便编辑 (例如,用 ":e 文件名") 或者写回 (例如,用 ":w 文件名") 时,此文件名被加入该列表。你可以用这个列表来记住编辑过什么文件并用 CTRL-^ 命令快速的从一个文件切换到另一个 (例如,以便复制文本)。先敲入文件的编号 再敲入 CTRL-^{Vi: 只有一个轮换文件名} CTRL-G*CTRL-G* *:f* *:fi* *:file* :f[ile] 显示当前文件名 (如同输入的那样)、光标位置 (除非置位了 'ruler' 选项) 和文件状态 (只读、已修改、读入错误、新文 件)。参见 'shortmess' 选项,了解如何可以简化该消息。 {Vi 不包括列号} {count}CTRL-GCTRL-G 类似,但显示当前文件名的完整路径。如果计数大 于 1,则同时给出当前缓冲区号。{Vi 无此功能} *g_CTRL-G* *word-count* *byte-count* g CTRL-G 显示当前光标位置,以四种方式表达: 列、行、单词和字节计 数。如果当前行有字符占据多于一个位置 (<Tab> 或其他特殊 字符),"实际" 列和屏幕列同时显示,以连字号分隔。参见 'ruler' 选项。{Vi 无此功能} *v_g_CTRL-G* {Visual}g CTRL-G 和 "g CTRL-G" 类似,但显示可视选择区域的单词、行和字节 计数。在面向列块模式里,列数也同时显示。(关于 {Visual} 见 |Visual-mode|。) {Vi 无此功能} *:file_f* :f[ile] {name} 设置当前文件名为 {name}。 :buffers :files :ls 列出当前已知的文件名。见 'windows.txt' |:files| |:buffers| |:ls|。{Vi 无此功能} vim 会记住你输入文件名的完整路径。大多数情况下,文件名只以你输入的方式显示。但 ":cd" 命令 |:cd| 使用后,就会看到完整路径名。 *home-replace* 如果设置了环境变量 $HOME,而文件名以该字符串开始,它的显示会把 HOME 替换成 "~"。这么做是为了使文件名的显示较为简洁。在读写文件时仍然使用完整路径名,"~" 只供显示文件名用。如果要替换名字实质上只有 "~" 的文件,会使用 "~/" (为了避免在 'backupext' 设为 '~' 时混淆)。 保存缓冲区时,缺省使用当前文件名。这样,如果你给出 "ZZ" 或者 ":wq" 命令,原有 的文件被覆盖。如果你不想如此,给 ":write" 命令给出一个文件名参数,你可以把缓冲 区写到另外一个文件里。例如: vim testfile [用编辑器命令修改缓冲区] :w newfile :q 这会建立文件 "newfile",它是 "testfile" 经过修改的版本。"testfile" 文件保持不 变。无论如何,如果置位 'backup' 选项,Vim 会在原来的文件被覆盖之前改名或复制。 如果你以后发现你需要原来的版本,你可以用这个备份文件。也可参见 'patchmode' 选 项。备份文件名通常是原来的文件加上 'backupext' 后缀。缺省的 "~" 比较奇特,目的 是为了防止意外覆盖现存的文件。如果你喜欢 ".bak",修改 'backupext' 选项。在 MS-DOS 机器上,当 Vim 检测到正在使用的是 MS-DOS 或类似的文件系统 (例如, messydos 或者 crossdos) 或者打开了 'shortname' 选项,多余的点号被替换成 '_'。 通过设置 'backupdir',备份文件也可存在别的目录下。 *auto-shortname* 技术上: 在 Amiga 上文件名可以长达 30 个字符。但在 MS-DOS 兼容的文件系统上只能 用 8+3 个字符。Vim 试图在创建 .swp 文件的时候检测文件系统的类型。如果 怀疑是一个类似 MS-DOS 的文件系统,则置位一个标志位,它和设置 'shortname' 选项有相同的效果。一旦你开始编辑一个新文件,该标志位被复 位。在根据当前文件名创建 ".swp" 和 ".~" 文件时,该标志位起作用。但如果 你在一个正常的文件系统上编辑文件,而写到一个类似于 MS-DOS 的文件系统, 该标志位不会被置位。这种情况下,创建 ".~" 文件可能会失败,你会得到一个 错误消息。这种情况下,用 'shortname' 选项。 当你开始编辑而不给出文件名,会给出 "No File" 消息。如果 ":write" 命令带一个文 件名参数,当前文件名被设为那个名字。这只有在 'cpoptions' 里带 'F' 标志位 (缺省 的确是如此) 时才会发生。这对在空缓冲区里编辑文本后写入到文件有用。如果 'cpoptions' 里包含 'f' 标志位 (缺省_不_包含),在执行 ":read file" 时,文件名被 设置。这可用来先不带参数启动 Vim 再用 ":read file" 编辑文件。 *not-edited* 因为设置文件名并不是真正编辑该文件,你不会覆盖它。这可由设置 "notedited" 标志 位来完成。你可由 CTRL-O 或 ":file" 命令看到该标志位是否设置。如果 "notedited" 标志位已设置,它会包括 "[Not edited]"。当将缓冲区写回当前文件名 (用 ":w!") 时,"notedited" 标志位被重设。 *abandon* Vim 记住你是否修改了缓冲区。你所作的修改不会不小心丢失。如果试图不写回而退出, 或开始编辑别的文件,Vim 会拒绝。要绕过这重保护,在命令后加上 '!'。这样,修改就 会丢失。例如: ":q" 在缓冲区修改后不会工作,但 ":q!" 会。要知道缓冲区是否修改, 用 "CTRL-G" 命令。如果缓冲区被修改,消息里会有字符串 "[Modified]"。 如果你想不经提示而自动写回改动,打开 'autowriteall' 选项。'autowrite' 是相关的 Vi-兼容选项,它并非对所有命令有效。 如果想保留修改了的缓冲区但不写回,打开 'hidden' 选项。参见 |hidden-buffer|。

2. 编辑单个文件 *edit-a-file*

*:e* *:edit* :e[dit] [++opt] [+cmd] 编辑当前文件。可用于在它被 Vim 之外的程序所改变的时候 重新编辑当前文件。 如果当前缓冲区已经被修改而且没有置 位 'autowriteall',或者文件不能被写入,本命令失败。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} *:edit!* :e[dit]! [++opt] [+cmd] 总是编辑当前文件。放弃当前缓冲区任何已有的改变。如果你 想从头来过,这就会很有用。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} *:edit_f* :e[dit] [++opt] [+cmd] {file} 编辑文件 {file}。 如果当前缓冲区已被修改,这会失败,除非置位了 'hidden' 或者 'autowriteall' 并且文件能够写入。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} *:edit!_f* :e[dit]! [++opt] [+cmd] {file} 总是编辑文件 {file}。放弃当前缓冲区任何已有的改变。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} :e[dit] [++opt] [+cmd] #[count] 编辑第 [count] 个轮换文件名 (根据 :files 显示的结果)。 该命令和 [count] CTRL-^ 一样,但是 ":e #" 在轮换缓冲区 没有文件名时不能工作,而 CTRL-^ 则可以。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} *:ene* *:enew* :ene[w] 编辑一个新的无名缓冲区。如果当前缓冲区已被修改,这会失 败,除非置位了 'hidden' 或者 'autowriteall' 并且文件能 够写入。 如果 'fileformats' 非空,其给出的第一个格式将用于新的 缓冲区上。如果 'fileformats' 为空,则使用当前缓冲区的 'fileformat'。 {Vi 无此功能} *:ene!* *:enew!* :ene[w]! 编辑新的无名缓冲区。放弃当前缓冲区任何已有的改变。 'fileformat' 的设置类似于 |:enew|。 {Vi 无此功能} *:fin* *:find* :fin[d][!] [++opt] [+cmd] {file} 在 'path' 里找到 {file},然后编辑 |:edit| 它。 {Vi 无此功能} {only 仅当编译时加入 |+file_in_path| 特 性才有效} :{count}fin[d][!] [++opt] [+cmd] {file} 和 ":find" 类似,但使用 'path' 的第 {count} 个匹配。这 样,":2find file" 会找到 'path' 里的第二个 "file"。如 果 'path' 里文件的匹配不足所需之数,你会得到一个错误消 息。 *:ex* :ex [++opt] [+cmd] [file] 和 |:edit| 相同。 *:vi* *:visual* :vi[sual][!] [++opt] [+cmd] [file] 处于 Ex 模式时: 退出 |Ex-mode|,回到普通模式。否则和 |:edit| 相同。 *:vie* *:view* :vie[w] [++opt] [+cmd] file 处于 Ex 模式时: 退出 |Ex-mode|,回到普通模式。否则和 |:edit| 相同,但为本缓冲区置位 'readonly' 选项。{Vi 无 此功能} *CTRL-^* *CTRL-6* [count]CTRL-^ 编辑第 [count] 个轮换文件 (和 ":e #[count]" 等价)。如 果不给出 count,它会给你前一个编辑的文件。这是一个快速 在两个 (或多个) 文件间切换的方法。 如果 'autowrite' 或 'autowriteall' 选项打开并且缓冲区 被修改,则写入文件。 大多数情况下,^ 字符在键 6 之上,同时按 CTRL 和 6 会给 出我们叫 CTRL-^ 的键码。但在有的非-US 的键盘上 CTRL-^ 须以不同的方式生成。 [count]]f *]f* *[f* [count][f 和 "gf" 一样。它本身已被淘汰。 *gf* *E446* *E447* [count]gf 编辑光标之上或之后的文件名。助记: "goto file"。 使用 'isfname' 选项来决定组成文件名的字符。拖尾的标点 符号 ".,:;!" 被忽略。 在 'path' 选项组成的目录名列表加上相对于当前文件的位置 查找文件。 设置 'suffixsadd' 选项可以用来查找文件所要附加的后缀。 如果文件找不到,用 'includeexpr' 来修改名字,然后再试 一次。 如果给出 [count],'path' 里找到的第 count 个文件被编 辑。 如果 Vim 拒绝放弃 |abandon| 当前文件,该命令失败。 如果你想编辑新文件,用: :e <cfile> 想使得 gf 总是如此工作,可以如此: :map gf :e <cfile><CR> 如果名字是一个超文本链接,也就是看来像 "type://machine/path" 这样的,你需要 |netrw| 插件。 对 Unix 而言,'~' 字符被扩展,比如在 "~user/file" 的场 合。环境变量也得到扩展 |expand-env|。 {Vi 无此功能} {only 仅在编译时加入 |+file_in_path| 特性才有效} *v_gf* {Visual}[count]gf 和 "gf" 相同,但是高亮文本被用来作为要编辑的文件名。 'isfname' 被忽略。开头的空白被忽略,除此以外,所有的空 白和特殊字符被包括在文件名里。 ({Visual} 可参见 |Visual-mode|。) {Vi 无此功能} 这些命令用来开始编辑单独一个文件。这意味着该文件被读入缓冲区里并设置当前文件 名。打开哪个文件和当前目录有关,见 |:cd|。 关于文件读入以后给出的消息,参见 |read-messages|。 如果你把缓冲区内容弄乱了想从头开始编辑,你可以用 ":e!" 命令。":e" 命令只有在你 改变当前文件名的时候有用。 *:filename* *{file}">{file}* 注意 除了 Unix 和 MS-DOS 以外的系统: 在使用接受单个文件名的名字时 (如 ":edit file"),文件名里可以有空格,但是拖尾的空格被忽略。这可用于允许文件名有 内含的空格的系统 (如 Amiga)。示例: 命令 ":e Long File Name " 会编辑文件 "Long File Name"。在使用接受多于一个文件名的命令时 (如 ":next file1 file2"), 内含的空格必须以反斜杠转义。 {file} 里的通配符被扩展。支持什么通配符由系统决定。以下是一些通用的字符: * 匹配任何东西,包括什么都没有 ? 匹配一个字符 [abc] 匹配 'a'、'b' 或 'c' 要避免通配符的特殊含义,在前面加上反斜杠。不过,在 MS-Windows 上,反斜杠是路径 分隔符,"path\[abc]" 在 'isfname' 选项里有 "[" 的时候还是被看作通配符。一个简 单避免该问题的方法是用 "path\[[]abc]"。这样文件名变成 "path[abc]"。 *backtick-expansion* *`-expansion* 在 Unix 上你可以在文件名里用反引号。例如: :e `find . -name ver\\*.c -print` 星号之前需要有反斜杠,以防 "ver*.c" 在执行 find 程序之前被外壳先扩展。 该功能对于多数其他系统也使用,但要求反引号必须包围整个项目。你不能在第一个之前 和最后一个反引号之后有别的文本。 你可以用 `={expr}` 的语法来使用反引号扩展 Vim 表达式,而非外部命令。例如 :let foo='bar' :e `=foo . ".c" ` 编辑 "bar.c"。 注意 该表达式不能含有反引号。 *++opt* *[++opt]* [++opt] 参数可以用来为某个命令强制指定 'fileformat' 或 'fileencoding' 的值。其 形式是: ++{optname}={value} 其中 {optname} 是以下之一: *++ff* *++enc* *++bin* *++nobin* ff 或 fileformat 超越 'fileformat' 之值 enc 或 encoding 超越 'fileencoding' 之值 bin 或 binary 置位 'binary' nobin 或 nobinary 复位 'binary' {value} 不能包含空白。它可以是这些选项任何可取之值。例如: :e ++ff=unix 再次编辑相同的文件,但指定 'fileformat' 为 "unix"。 :w ++enc=latin1 newfile 把当前缓冲区写入到 "newfile",以 latin1 编码。 注意 在读入文件时,'fileformat' 和 'fileencoding' 选项会被设为实际所用的格式。 在写回时,这不会发生。因此下一次写会使用选项的旧值。'binary' 选项也同样如此。 可以用多个 ++opt 参数,以空格分隔。它们都必须在任何 |+cmd| 参数之前。 *+cmd* *[+cmd]* [+cmd] 参数可以用来在新打开的文件定位光标或执行任何其他命令: + 从最后一行开始。 +{num} 从第 {num} 行开始。 +/{pat} 从匹配 {pat} 的第一行开始。 +{command} 打开新文件以后执行 {command}{command} 可以是任何 Ex 命令。 要在 {pat}{command} 里包含空白,在它之前加上反斜杠。反斜杠本身则要加倍。 :edit +/The\ book file :edit +/dir\ dirname\\ file :edit +set\ dir=c:\\\\temp file 注意 最后一个例子里反斜杠减半两次: 一次用于 "+cmd" 参数,一次用于 ":set" 命 令。 *file-formats* 'fileformat' 选项指定文件里的换行符 (<EOL>) 风格: 'fileformat' 字符 名字 "dos" <CR><NL><NL> DOS 格式 *DOS-format* "unix" <NL> Unix 格式 *Unix-format* "mac" <CR> Mac 格式 *Mac-format* 以前还使用 'textmode' 。现在已经废弃了。 在读入文件时,以上列出的字符被解释为换行符。DOS 格式 (MS-DOS、OS/2 和 Win32 缺 省值) 把 <CR><NL><NL> 都解释为换行符。 注意 在以 DOS 格式写入文件时, 会在每个单独的 <NL> 之后加上 <CR> 字符。另见 |file-read|。 当写入文件时,换行符用以上列出的字符写入。DOS 格式使用 <CR><NL>。另见 |DOS-format-write|。 你可以从 DOS 格式读入文件再以 Unix 格式写回。这样所有的 <CR><NL> 对会被换成 <NL> (假设 'fileformats' 包括 "dos"): :e file :set fileformat=unix :w 反之,如果你从 Unix 格式读入文件再以 DOS 格式写回。所有的 <NL> 字符会被换成 <CR><NL> (假设 'fileformats' 包括 "unix"): :e file :set fileformat=dos :w 如果你开始编辑新文件而 'fileformats' 选顶非空 (缺省),Vim 会测试文件以何种格式 分隔行。如果设为 "unix,dos",Vim 会检查每行是带 <NL> (Unix 和 Amiga) 还是带 <CR><NL> 对 (MS-DOS)。只有当_所有_行都以 <CR><NL> 结尾,'fileformat' 才被设为 "dos",否则,它被设为 "unix"。如果 'fileformats' 包含 "mac" 而且文件不含 <NL> 字符,'fileformat' 设为 "mac"。 如果 'fileformat' 选项在非 MS-DOS 的系统上设为 "dos",消息 "[dos format]" 会提 示你发生了不同寻常的事情。 在 MS-DOS 系统上,如果 'fileformat' 设为 "unix",你 也会得到消息 "[unix format]"。除了 Macintosh 以外的所有的系统中,如果 'fileformat' 设为 "mac",你会得到消息 "[mac format]"。 如果 'fileformats' 选项为空而使用了 DOS 格式,但是在读入文件时发现某些行不以 <CR><NL> 结尾,"[CR missing]" 会在文件消息里列出。 如果 'fileformats' 选项为空而使用了 Mac 格式,但是在读入文件时发现某些行有 <NL>,"[NL missing]" 会在文件消息里列出。 如果新文件不存在,则当 'fileformats' 为空时使用当前缓冲区的 'fileformat',否则 使用 'fileformats' 的第一个格式。 在开始编辑二进制、可执行或 Vim 脚本文件时,你应该置位 'binary' 选项。一个简单 的方式是以 "-b" 选项启动 Vim。该选项可以避免使用 'fileformat'。如果不设,你会 有单个 <NL> 字符被莫名其妙地换成 <CR><NL> 的风险。 你可以用 'key' 选项在写回时给文件加密。它提供了相当安全性,防止别人读到你的文 件。|encryption| 文 件 搜 索 *file-searching* {only 仅当编译时加入 |+path_extra| 特性才有效} 文件搜索目前用于 'path'、'cdpath' 和 'tags' 选项。有三种不同类型的搜索: 1) 向下搜索: 向下搜索使用 '*'、'**' 或其他操作系统支持的通配符。'*' 和 '**' 是由 Vim 内 部处理的,以适用于所有操作系统。 '*' 的使用很简单: 匹配 0 个或更多字符。 '**' 则复杂的多: - _只_匹配目录。 - 匹配最多可达 30 层的目录。所以你可以用它整个目录树里查找 - 最大匹配的层数可以通过在 '**' 之后给出数字限定。 这样,'/usr/**2' 可以匹配: /usr /usr/include /usr/include/sys /usr/include/g++ /usr/lib /usr/lib/X11 .... 它_不_匹配 '/usr/include/g++/std',因为这已到了第三层。 允许的数字范围是 0 ('**0' 被直接去掉) 到 255。如果给定的数字小于 0,则 缺省为 30。如果大于 255,则缺省为 255。 - '**' 只能用于路径的尾部,或者后面紧跟一个路径分隔符,或者后面紧跟一个 数字加一个路径分隔符。 你可以用任何顺序混合 '*' 和 '**': /usr/**/sys/* /usr/*/sys/** /usr/**2/sys/* 2) 向上搜索: 这里,你可以给出一个目录,然后沿着目录树向上搜索一个文件。你可以给出若干终 止目录来限制搜索的范围。终止目录附加于路径 (对 'path' 选项而言) 或文件名 (对 'tags' 选项而言) 之后,中间以 ";" 分隔。如果需要多个终止目录,一一列 出,以 ';' 分隔。如果你不想要终止目录 (搜索直到根目录),只要用 ";"。 /usr/include/sys;/usr 会在以下位置搜索: /usr/include/sys /usr/include /usr 如果你用相对路径,则向上搜索始于 Vim 的当前目录或当前文件的目录 (如果相对路 径始于 "./" 并且 'cpoptions' 里不含 'd' 的话)。 如果 Vim 的当前路径是 /u/user_x/work/release 而你用 :set path=include;/u/user_x 然后用 |gf| 搜索文件,则文件在如下位置搜索: /u/user_x/work/release/include /u/user_x/work/include /u/user_x/include 3) 混合向上/向下搜索 如果 Vim 当前路径是 /u/user_x/work/release 而你用 set path=**;/u/user_x 然后用 |gf| 搜索文件,则文件在如下位置搜索: /u/user_x/work/release/** /u/user_x/work/** /u/user_x/** _要小心_!这会消耗大量时间,因为对 '/u/user_x/**' 的搜索包括 '/u/user_x/work/**' 和 '/u/user_x/work/release/**'。因此 '/u/user_x/work/release/**' 被搜索三遍而 '/u/user_x/work/**' 被搜索两遍。 因而,在上例中你可能想如此设置 path: :set path=**,/u/user_x/** 这会搜索: /u/user_x/work/release/** /u/user_x/** 它会搜索相同的目录群,但顺序不同。

3. 对话框 *edit-dialogs*

*:confirm* *:conf* :conf[irm] {command} 执行 {command},如果有操作需要确认,显示对话框。可用于 ":q"、":qa" 和 ":w" 命令 (后者用于超越只读的设定)。 示例: :confirm w foo 如果 "foo" 存在请求确认。 :confirm q 如果有改变请求确认。 :confirm qa 如果有任何修改过的未保存的缓冲区存在,对其中的每个缓冲区提示是保存还是 放弃。还可以选择 "save all" (保存所有) 或 "abandon all" (放弃所有)。 如果你希望总是用 ":confirm",置位 'confirm' 选项。 *:browse* *:bro* *E338* *E614* *E615* *E616* *E578* :bro[wse] {command} 为 {command| 的参数显示文件选择对话框。目前这可用于 |:e|、|:w|、|:r|、|:saveas|、|:sp|、|:mkexrc|、 |:mkvimrc| 和 |:mksession|。 {only 仅对 Win32、Athena、Motif、GTK 和 Mac GUI 有效} 如果不可用 ":browse",你会得到错误消息。如果 |+browse| 特性不存在或者 {command} 不支持该 (浏览) 功能,不显示 对话框,如常执行 {command}。 ":browse set" 和 |:options| 类同。 该语法最好通过若干范例说明之: :browse e $vim/foo 在 $vim/foo 目录里打开浏览器并编辑选择的文件。 :browse e 在 'browsedir' 指定的目录里打开浏览器并编辑选择的文件。 :browse w 在当前缓冲区所在的目录里打开浏览器。缺省使用当前缓冲区的文件 名。把缓冲区写入到指定的文件。 :browse w C:/bar 在 C:/bar 目录里打开浏览器,缺省使用当前缓冲区的文件名,把缓冲 区写入到指定的文件。 另见 |'browsedir'| 选项。 如果所用的 Vim 版本不支持浏览,该命令照原样执行。 *browsefilter* 对 MS Windows 而言,你可以修改浏览对话框的过滤 (filter)。设置 g:browsefilter 或 b:browsefilter 变量,你可以修改全局或局部于缓冲区的过滤设置。该变量应设为符 合如下格式的字符串 "{过滤标签}\t{pattern};{pattern}\n",其中的 {过滤标签} 是出 现 "Files of Type" 组合框里应出现的文字,而 {pattern} 是过滤文件名的模式。可以 给出多个模式,以 ";" 分隔。 Motif 使用相同的格式,但只使用第一个模式 (Motif 只提供一个模式,但可以编辑)。 例如,要使得对话框里只显示 Vim 文件,你可以用以下命令: let g:browsefilter="Vim Scripts\t*.vim\nVim Startup Files\t*vimrc\n" 你可以通过在某个缓冲区上设置 b:browsefilter 变量超越全局过滤的设置。最有可能的 情况是在文件类型插件里设置 b:browsefilter,以便浏览对话框只显示和当前编辑的文 件所属类型相关的项目。缺点是: 无法编辑一个新的不同类型的文件。要克服这一点,你 可以加上 "All Files\t*.*\n" 作为最后的过滤。用户从而拥有访问任何类型文件的选 择。

4. 当前目录 *current-directory*

你也可以用 |:cd| 和 |:lcd| 命令换到别的目录,所以你可以不用总是在文件名前输入 目录名。这也影响到外部命令的执行,例如 ":!ls"。 *:cd* *E472* :cd 在非 Unix 系统上: 显示当前目录名。在 Unix 系统上: 改变 当前目录到主 (home) 目录。在所有的系统上,用 |:pwd| 可 以显示当前目录。 :cd {path} 切换当前目录为 {path}。如果 {path} 是相对路径,则在 |'cdpath'| 列出的目录搜索之。 这不会改变已经打开的文件,因为记住的是它们的完整路径。 但 |arglist| 里的文件则可能会改变! MS-DOS 上这会同时改变当前的驱动器。 要改变到当前文件的目录: :cd %:h *:cd-* *E186* :cd - 切换到上一个当前目录 (在上个 ":cd {path}" 命令之前)。 {Vi 无此功能} *:chd* *:chdir* :chd[ir] [path] 和 |:cd| 相同。 *:lc* *:lcd* :lc[d] {path} 和 |:cd| 类似,但只设置当前窗口的当前目录。别的窗口的 当前目录保持不变。{Vi 无此功能} *:lch* *:lchdir* :lch[dir] 和 |:lcd| 相同。{Vi 无此功能} *:pw* *:pwd* *E187* :pw[d] 显示当前目录名。{Vi: 没有 pwd} 另见 |getcwd()|。 只要没有用过 |:lcd| 命令,所有窗口共享同一个当前目录。切换到别的窗口的命令因此 不会改变当前目录。 当某个窗口用了 |:lcd| 命令,所指定的目录成为该窗口的当前目录。没用过 |:lcd| 的 窗口还是和全局的当前目录同步。跳转到另一个窗口时,当前目录成为上次指定的本地当 前目录。如果没有指定过,则使用全局当前目录。 如果使用 |:cd| 命令,当前窗口会丢失他的本地当前目录,并从此以后使用全局当前目 录。 |:cd| 的完整路径名用于其后的文件读写。在某些网络文件系统中,这可能会引起麻烦。 使用完整路径名的结果是当前使用的文件名还是指向相同的文件。例如: 如果你有文件 a:test 和 目录 a:vim。命令 ":e test" ":cd vim" ":w" 会覆盖文件 a:test 而不是 a:vim/test。但如果你使用 ":w test" 文件 a:vim/test 会被覆盖,因为你给出一个新 的文件名,因而与 ":cd" 之前所指向的文件业已不同。

5. 参数列表 *argument-list* *arglist*

如果你在启动 Vim 的时候给出多个文件名,这些文件将被记住,即参数列表。你可以跳 转到该列表里的任何一个文件。 不要把它和 |:buffers| 命令里的缓冲区列表混淆。参数列表在 Vi 里已经存在,但 缓冲区列表是 Vim 新加入的。参数列表里的文件名也会在缓冲区列表里存在 (除非你用 ":bdel" 将其删除)。 该主题在用户手册的 |07.2| 一节已有介绍。 只有一个全局参数列表,所有窗口缺省都使用它。但可以创建局部于窗口的新参数列表, 见 |:arglocal|。 下面的命令使用参数列表,还有表达式函数 |argc()| 和 |argv()|。他们均作用于当前 窗口的参数列表。 *:ar* *:args* :ar[gs] 显示参数列表,当前文件以方括号表示。 :ar[gs] [++opt] [+cmd] {arglist} *:args_f* 定义 {arglist} 为新的参数列表并编辑其中的第一个。如果 已经作了修改而 vim 不能放弃 |abandon| 当前的缓冲区,该 命令失败。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} :ar[gs]! [++opt] [+cmd] {arglist} *:args_f!* 定义 {arglist} 为新的参数列表并编辑其中的第一个。忽略 任何对当前缓冲区的改动。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} :[count]arge[dit][!] [++opt] [+cmd] {name} *:arge* *:argedit*{name} 加到参数列表里,并编辑之。 如果 {name} 已经在参数列表里存在,只编辑之。 这和用 |:argadd| 然后 |:edit| 类似。 注意 这里只允许单个文件名,文件名里的空格是允许的,就 像 |:edit| 一样。 [count] 的用法和 |:argadd| 一样。 如果当前文件不能被放弃 |abandon|,[!] 是必需的。 另见 |++opt| 和 |+cmd|。 {Vi: 无 ++opt} :[count]arga[dd] {name} .. *:arga* *:argadd* *E479* 将若干文件名 {name} 等加到参数列表里。 如果忽略 [count]{name} 等加入到参数列表的当前项之 后。不然,加到第 [count] 个文件之后。如果参数列表是 "a b c",而 "b" 是当前参数,那么以下命令会导致: 命令 新的参数列表 :argadd x a b x c :0argadd x x a b c :1argadd x a x b c :99argadd x a b c x 这里不会检查重复项,因此一个文件可能加入参数列表两次。 不改变当前编辑的文件。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性才 有效} 注意: 你也可以使用这个方法: :args ## x 这会加入 "x" 项并对新的列表排序。 :argd[elete] {pattern} .. *:argd* *:argdelete* *E480* 从参数列表里删除匹配 {pattern} (可有多个) 的文件。 {pattern} 为文件模式,见 |file-pattern|。"%" 可以用来 删除当前入口项。 即使该命令从参数列表里删除了当前编辑文件,该文件保持被 编辑。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性才 有效} :{range}argd[elete] 从参数列表里删除 {range} 范围里的文件。如果该范围的最 后一个数字过大,删除直到最后一个参数为止。例如: :10,1000argdel 删除第 10 个和其后的参数,保留 1-9。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性才 有效} *:argu* *:argument* :[count]argu[ment] [count] [++opt] [+cmd] 编辑参数列表里的第 [count] 个文件。在忽略 [count] 的时 候,编辑当前入口项。如果已经作了修改而 vim 不能放弃 |abandon| 当前的缓冲区,该命令失败。 另见 |++opt| 和 |+cmd|。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性才 有效} :[count]argu[ment]! [count] [++opt] [+cmd] 编辑参数列表里的第 [count] 个文件。忽略任何对当前缓冲 区的已有修改。在忽略 [count] 的时候,编辑当前入口项。 另见 |++opt| 和 |+cmd|。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性才 有效} :[count]n[ext] [++opt] [+cmd] *:n* *:ne* *:next* *E165* *E163* 编辑向后第 [count] 个文件。如果已经作了修改而 vim 不能 放弃 |abandon| 当前的缓冲区,该命令失败。另见 |++opt| 和 |+cmd|。{Vi 没有 count 和 ++opt} :[count]n[ext]! [++opt] [+cmd] 编辑向后第 [count] 个文件。忽略任何对当前缓冲区的已有 修改。另见 |++opt| 和 |+cmd|。{Vi 没有 count 和 ++opt} :n[ext] [++opt] [+cmd] {arglist} *:next_f* 和 |:args_f| 相同。 :n[ext]! [++opt] [+cmd] {arglist} 和 |:args_f!| 相同。 :[count]N[ext] [count] [++opt] [+cmd] *:Next* *:N* *E164* 编辑向前第 [count] 个文件。如果已经作了修改而 vim 不能 放弃 |abandon| 当前的缓冲区,该命令失败。另见 |++opt| 和 |+cmd|。{Vi 没有 count 和 ++opt} :[count]N[ext]! [count] [++opt] [+cmd] 编辑向前第 [count] 个文件。忽略任何对当前缓冲区的已有 修改。另见 |++opt| 和 |+cmd|。{Vi 没有 count 和 ++opt} :[count]prev[ious] [count] [++opt] [+cmd] *:prev* *:previous* 和 :Next 相同。另见 |++opt| 和 |+cmd|。{Vi: 只有在某些 版本存在} *:rew* *:rewind* :rew[ind] [++opt] [+cmd] 开始编辑参数列表的第一个文件。如果已经作了修改而 vim 不能放弃 |abandon| 当前的缓冲区,该命令失败。另见 |++opt| 和 |+cmd|。{Vi 没有 ++opt} :rew[ind]! [++opt] [+cmd] 开始编辑参数列表的第一个文件。忽略任何对当前缓冲区的已 有修改。另见 |++opt| 和 |+cmd|。{Vi 没有 ++opt} *:fir* *:first* :fir[st][!] [++opt] [+cmd] ":rewind" 的别名。{Vi 无此功能} *:la* *:last* :la[st] [++opt] [+cmd] 开始编辑参数列表的最后一个文件。如果已经作了修改而 vim 不能放弃 |abandon| 当前的缓冲区,该命令失败。另见 |++opt| 和 |+cmd|。{Vi 无此功能} :la[st]! [++opt] [+cmd] 开始编辑参数列表的最后一个文件。忽略任何对当前缓冲区的 已有修改。另见 |++opt| 和 |+cmd|。{Vi 无此功能} *:wn* *:wnext* :[count]wn[ext] [++opt] [+cmd] 写回当前文件并开始编辑向后第 [count] 个文件。另见 |++opt| 和 |+cmd|。{Vi 无此功能} :[count]wn[ext] [++opt] [+cmd] {file} 写入当前文件到 {file} 并开始编辑向后第 [count] 个文 件,除非 {file} 已经存在并且 'writeany' 选项被关闭。另 见 |++opt| 和 |+cmd|。{Vi 无此功能} :[count]wn[ext]! [++opt] [+cmd] {file} 写入当前文件到 {file} 并开始编辑向后第 [count] 个文 件。另见 |++opt| 和 |+cmd|。{Vi 无此功能} :[count]wN[ext][!] [++opt] [+cmd] [file] *:wN* *:wNext* :[count]wp[revous][!] [++opt] [+cmd] [file] *:wp* *:wprevious* 和 :wnext 相同,向前编辑而不是向后。{Vi 无此功能} 以上命令的 [count] 缺省为一。对有些命令可以使用两个计数。后者 (右面那个) 被使 用。 如果没有给出 [+cmd] 参数,光标定位于文件最后一个已知的位置。如果置位了 'startofline',光标会定位于该行第一个非空白字符,不然,则使用最后一个已知列。 如果没有最后已知的光标位置,光标会定位在第一行 (Ex 模式下则是最后一行)。 参数列表里的通配符会扩展,文件名会排序。这样你可以用命令 "vim *.c" 编辑所有的 C 文件。在 Vim 里面,":n *.c" 命令会做同样的事。在 Unix 上你还可以使用反引号, 例如: :n `find . -name \\*.c -print` 星号之前的反斜杠是必要的,它用来防止 "*.c" 在执行 find 程序之前被外壳扩展。 *arglist-position* 如果有参数列表,你可以在窗口的标题上看到正在编辑哪个文件 (如果有一个窗口,而且 'title' 被置位),或者通过 "CTRL-G" 命令,在文件消息里看到。你会看到类似于 (file 4 of 11) 的东西。如果 'shortmess' 包含 'f',它会成为 (4 of 11) 如果你还没有编辑参数列表当前位置的文件,它会是 (file (4) of 11) 这表示你在参数列表的第四个位置,不过还没有开始编辑之。这发生于你刚做 ":e file" 的时候。 局 部 参 数 列 表 {Vi 无此功能} {only 仅在编译时加入 |+windows| 和 |+listcmds| 特性时才有效} *:arglocal* :argl[ocal] 复制一个全局参数列表的局部备份。并不开始编辑另外一个文 件。 :argl[ocal][!] [++opt] [+cmd] {arglist} 定义一个新的局部于当前窗口的参数列表。除此以外,和 |:args_f| 列表。 *:argglobal* :argg[lobal] 当前窗口使用全局参数列表。并不开始编辑另外一个文件。 :argg[lobal][!] [++opt] [+cmd] {arglist} 当前窗口使用全局参数列表。和 |:args_f| 一样,定义一个 新的全局参数列表。所有使用全局参数列表的窗口都会看到这 个新的列表。 可以有多个参数列表。他们可以在窗口之间共享。如果他们共享,在其中一个窗口修改参 数列表就会改变另一个窗口的列表。 如果一个窗口被分割,新的窗口从原来的窗口继承参数列表。两个窗口因而共享该列表, 直到其中一个窗口使用 |:arglocal| 或 |:argglobal| 来使用另外一个参数列表。 使 用 参 数 列 表 *:argdo* :argdo[!] {cmd} 对参数列表里的每个文件执行 {cmd}。 它的工作方式大致如下: :rewind :{cmd} :next :{cmd} 等等 如果当前文件不能被放弃 |abandon| 而且不存在 [!],该命 令失败。 如果一个文件检测到错误,参数列表里的其余文件将不再被操 作。 参数列表里的最后一个文件 (或发生错误的那个) 成为当前文 件。 {cmd} 可以包含 '|',从而连接多个命令。 {cmd} 不可修改参数列表。 注意: 当命令执行时,Syntax 自动命令事件被加到 'eventignore' 里,从而被屏蔽。这样显著提高了编辑每个文 件的速度。 {Vi 无此功能} {only 仅当编译时加入 |+listcmds| 特性时 才有效} 另见 |:windo| 和 |:bufdo|。 示例: :args *.c :argdo set ff=unix | update 它把 'fileformat' 选项设为 "unix",并写回现在已改变的所有的 *.c 文件。 示例: :args *.[ch] :argdo %s/\<my_foo\>/My_Foo/ge | update 它把所有 *.c 和 *.h 文件里的单词 "my_foo" 换成 "My_Foo"。"e" 标志位使得 ":substitute" 命令对没有使用 "my_foo" 的文件不提示错误。":update" 只有在发生改 变的时候才写入文件。

6. 写入 *writing* *save-file*

注意: 如果 'write' 选项关闭,你不能写入任何文件。 *:w* *:write* *E502* *E503* *E504* *E505* *E512* *E514* *E667* :w[rite] 将整个缓冲区写入当前文件。这是保存文件更动最普通的方 式。如果置位了 'readonly' 选项或者其他原因不能写入文 件,它会失败。 :w[rite]! 和 ":write" 类似,但即使 'readonly' 已置位或者有其他原 因写入被拒绝,还是强制写入。 注意: 这可能会改变文件的权限和所有者,或者破坏 (符号) 连接。在 'cpoptions' 里加上 'W' 标志位可以避免这一点。 :[range]w[rite][!] 将指定行写入当前文件。这是很特别的,因为文件里将不会包 含缓冲区的所有行。 *:w_f* *:write_f* :[range]w[rite] {file} 将指定行写入文件 {file},除非该文件已存在并且未置位 'writeany' 选项。 *:w!* :[range]w[rite]! {file} 将指定行写入文件 {file}。覆盖已存在的文件。 *:w_a* *:write_a* *E494* :[range]w[rite][!] >> 将指定行附加到当前文件后。 :[range]w[rite][!] >> {file} 将指定行附加到文件 {file} 之后。'!' 强制写入,即使该文 件还不存在。 *:w_c* *:write_c* :[range]w[rite] !{cmd} 执行命令 {cmd},以 [range] 指定的行作为它的标准输入。 (注意 ! 之前的空格)。{cmd} 以 ":!{cmd}" 类似的方式被执 行,任何 '!' 被替换成前一个命令 |:!|。 ":w" 命令缺省的 [range] 是整个缓冲区 (1,$)。如果 ":w" 给出一个文件名,它成为轮 换文件。这可以用来,比如说,当写入失败而你想再迟些再试一次: ":w #"。该功能可以 通过从 'cpoptions' 选项里去掉 'A' 标志位来关闭。 *:sav* *:saveas* :sav[eas][!] {file} 用文件名 {file} 保存当前缓冲区,并设置当前缓冲区的文件 名为 {file}。前一个名字用作轮换文件名。[!] 用以覆盖已 存在的文件。 {Vi 无此功能} *:up* *:update* :[range]up[date][!] [>>] [file] 和 ":write" 类似,但只有在缓冲区已修改的时候才写入。 {Vi 无此功能} 写 入 多 个 缓 冲 区 *buffer-write* *:wa* *:wall* :wa[ll] 保存所有已修改的缓冲区。没有文件名或者只读的缓冲区不在 此列。{Vi 无此功能} :wa[ll]! 保存所有已修改的缓冲区。即使是只读的。但没有文件名的缓 冲区仍不会写入。{Vi 无此功能} 如果你试图覆盖在别的地方修改的文件,Vim 会警告你。参见 |timestamp|。 *backup* *E207* *E506* *E507* *E508* *E509* *E510* 如果你写入已存在的文件 (但非附加) 而打开了 'backup'、'writebackup' 或者 'patchmode' 选项,原来文件的一个备份会被建立。该文件或者由复制,或者由换名得 到 (见 'backupcopy')。在文件被成功写入后,当置位 'writebackup' 选项而没有置位 'backup' 时,该备份文件被删除。当 'patchmode' 选项打开时,备份文件可能被改名。 *backup-table* 'backup' 'writebackup' 动作 关 关 没有备份 关 开 备份当前文件,写入后删除 (缺省) 开 关 删除旧的备份,备份当前文件 开 开 删除旧的备份,备份当前文件 当 'backupskip' 模式匹配被写入的文件名,备份文件不会被创建。此时,'backup' 和 'writebackup' 被忽略。 如果 'backup' 选项置位,旧的备份文件 (与新的备份文件同名) 被删除。如果没有置位 'backup' 但置位了 'writebackup',已有的备份文件不会被删除。文件写入时使用的是 另外一个文件名。 有些文件系统的崩溃可能导致备份文件和新写入的文件同时丢失 (可能还在但包含不正确 数据)。这种情况下可以尝试修复功能 |:recover|,因为交换文件在盘上保持一个同步的 备份,可能还有用。 'backupdir' 选项给出的目录用于存放备份文件 (缺省在写入文件的相同目录)。 不管备份文件是否新建,它是否原始文件复制还是换名得来由 'backupcopy' 选项决定。 该选项的描述解释了何时使用复制,何时使用换名。 如果备份文件创建失败,写入不会进行。除非命令中加上 '!'。 *write-readonly* 如果 'cpoptions' 选项里包含 'W',Vim 拒绝覆盖只读文件。如果没有该标志位,":w!" 可以用来覆盖只读文件, 如果系统支持的话 (目录本身必须是可写的)。 *write-fail* 如果新文件写入失败,要小心不要同时丢失了你的修改内容_和_原始的文件。如果没有 备份文件而写入新文件失败的话,原始的文件已经没有了!除 非 你 写 了 文 件,不 要 退 出 VIM!如果创建了备份,它保存了原始文件的内容 (如果可能的话)。如果你退 出 Vim 并丢失了修改的部分,原始的文件很有可能还在。如果原始文件的保存也失败的 话,你会得到一个错误信息,提示丢失了原始文件。 *DOS-format-write* 如果 'fileformat' 为 "dos",<CR><NL> 用作换行符 <EOL>。这是 MS-DOS,Win32 和 OS/2 的缺省行为。在其他系统中,"[dos format]" 信息会提示你使用了不同寻常的 <EOL>*Unix-format-write* 如果 'fileformat' 为 "unix",<NL> 用作换行符 <EOL>。在 MS-DOS,Win32 和 OS/2 上会显示 "[unix format]"。 *Mac-format-write* 如果 'fileformat' 为 "mac",<CR> 用作换行符 <EOL>。在非 Mac 的系统上会显示 "[mac format]" 消息。 另见 |file-formats| 和 'fileformat' 以及 'fileformats' 选项。 *ACL* ACL 代表访问控制表 (Access Control List)。这是控制文件访问权限一个高级方法。在 新的 MS-Windows 和 Unix 系统上,如果有文件系统的支持,可以使用之。 Vim 试图在写入文件时保留 ACL 信息。备份文件会用和原始文件相同的 ACL 信息。 ACL 信息也用来检查文件是否只读 (在打开文件时)。 *read-only-share* 当 MS-Windows 共享网络驱动器时,可以指定其为只读。这意味着即使文件本身没有只读 属性,你也不能写入该文件。Win32 平台上的 Vim 会检测只读的网络驱动器,并标记其 上的文件为只读。你不能用 |:write| 修改。 *write-device* 如果文件名其实是设备名,Vim 不会建立备份 (这也不可能)。你需要使用 "!",因为设 备已经存在。Unix 上的示例: :w! /dev/lpt0 MS-DOS 或 MS-Windows 上: :w! lpt0 Unix 上当文件名不引用一个普通文件或者目录时,检测为设备。fifo 和命令管道对 Vim 而言视同设备。MS-DOS 和 MS-Windows 上以下名字检测为设备: AUX CON CLOCK$ NUL PRN COMn n=1,2,3... 等 LPTn n=1,2,3... 等 名字大小写均可。

7. 写入并退出 *write-quit*

*:q* *:quit* :q[uit] 退出当前窗口。如果是最后的一个,退出 Vim。如果已经有 修改而且 Vim 拒绝放弃 |abandon| 当前的缓冲区,或者 如果参数列表的最后一个文件还没有被编辑,该操作失败。 :conf[irm] q[uit] 退出,但如果已经有修改或者参数列表的最后一个文件还未被 编辑,给出提示。参见 |:confirm| 和 'confirm'。 {Vi 无 此功能} :q[uit]! 退出不保存,即使有可见的缓冲区发生了修改。不适用于隐 藏的缓冲区。为了保证总能退出,用 ":qall!"。 :cq[uit] 在任何情形下,退出不保存,并返回一个错误代码。参见 |:cq|。此功能可用于 Manx 的 QuickFix 模式 (参见 |quickfix|)。 {Vi 无此功能} *:wq* :wq 写回当前的文件并且退出。如果文件只读或者该缓冲区无名, 写回操作将失败。如果参数列表的最后一个文件还没有编辑, 那么退出操作将会失败。 :wq! 写回当前的文件并且退出。如果当前缓冲区无名,则写回操作 将失败。 :wq {file} 写入到 {file} 并且退出。 如果参数列表的最后一个文件还 没有编辑, 那么退出操作将会失败。 :wq! {file} 写入到 {file} 并且退出。 :[range]wq[!] [file] 同上,但只写入 [range] 界定的那些行。 *:x* *:xit* :[range]x[it][!] [file] 和 ":wq" 类似, 但只有文件已修改时写入才会实际进行。 如果 'hidden' 被设置并且还有其他窗口,当前缓冲区会在 写入后被隐藏。 *:exi* *:exit* :[range]exi[t][!] [file] 同 :xit。 *ZZ* ZZ 如果文件被修改,写回当前文件。然后退出。(和 :x 相 同)。(注意: 如果有当前文件有多个窗口,该文件在被修改 时会被写回,当前窗口会被关闭)。 *ZQ* ZQ 退出,不检查是否发生了修改 (等同于 ":q!")。 {Vi 无此功能} 多 个 窗 口 和 缓 冲 区 *window-exit* *:qa* *:qall* :qa[ll] 退出 Vim,除非存在修改过的缓冲区。(可以使用 ":bmod" 跳转 到下一个修改过的缓冲区)。如果置位了 'autowriteall',所有 被修改的缓冲区将被保存,一如调用了 |:wqall|。{Vi 无此功能} :conf[irm] qa[ll] 退出 Vim。如果存在修改过的缓冲区,给出提示。参见 |:confirm|。 {Vi 无此功能} :qa[ll]! 退出 Vim,不会保存任何的修改。 {Vi 无此功能} *:quita* *:quitall* :quita[ll][!] 等同于 ":qall"。{Vi 无此功能} :wqa[ll] *:wqa* *:wqall* *:xa* *:xall* :xa[ll] 保存所有修改过的缓冲区并退出 Vim。如果其中有无名的、只读的、 或者其他原因写入失败的缓冲区,Vim 不会退出。{Vi 无此功能} :conf[irm] wqa[ll] :conf[irm] xa[ll] 保存所有修改过的缓冲区并退出 Vim。如果其中有只读或者其他原因 写入失败的缓冲区,给出提示。参看 |:confirm|。{Vi 无此功能} :wqa[ll]! :xa[ll]! 保存所有修改过的缓冲区,甚至包括只读的,然后退出 Vim。不过, 如果有无名或者其他原因写入失败的缓冲区,Vim 仍然不会退出。 {Vi 无此功能}

8. 编辑二进制文件 *edit-binary*

尽管 Vim 是用来编辑文本文件的,它也可用来编辑二进制文件。Vim 的 |-b| 参数 (b 代表二进制 (binary)) 使 Vim 以二进制模式进行文件读写操作,并设置二进制文件编辑 相关的一些选项 ('binary' 打开,'textwidth' 为 0,'modeline' 关闭,'expandtab' 关闭)。置位 'binary' 选项效果相同。不要忘记应在读入文件之前进行该操作。 编辑二进制文件时要注意以下几点: - 在编辑可执行文件时,不要修改字符数。只用 "R" 或 "r" 命令来修改文本。不要用 "x" 或退格键删除字符。 - 设置 'textwidth' 选项为 0。不然,行会被意外的截为两段。 - 如果 <EOL> 符不多,行会很长。如果你希望编辑屏幕显示不下的行,重设 'wrap' 选 项,使用横向滚动。如果一行过长 (Amiga 上超过 32767 个字符,32 位系统中则大得 多,见 |limits|),你不能编辑该行。该行在读入时会被截断。也可能读入发生 "out of memory" 错误。 - 确保在读入文件_前_置位 'binary' 选项。不然,<CR><NL><NL> 都被认为行尾, 从而在写回时,<NL> 会被 <CR><NL> 取代。 - <Nul> 字符会在屏幕上显示为 ^@。你可以用 "CTRL-V CTRL-@" 或 "CTRL-V 000" 输入 之 {Vi 不能处理文件里的 <Nul> 字符} - 插入 <NL> 字符会截断一行。在将缓冲区写入到文件时,<NL> 会作为 <EOL> 被写入。 - 如果文件尾没有 <EOL>,Vim 通常会自己加上。置位 'binary' 选项会禁止这一行 为。你也可以读取该选项的值来知道最后一行是否有 <EOL> (文本上你是看不到的)。

9. 加密 *encryption*

Vim 可用加密的方式写入文件并读回。没有正确的密钥,加密文本不能被读取。 注意: 交换文件和内存里的文本是不加密的。系统管理员因此可以在你编辑时看到你的文本。 用 ":!filter" 或者 ":w !command" 过滤的文本也是不加密的,这些都可能造成文本泄 露。 _警告_: 如果在输入密钥时发生错误而且写入文件后退出,这些文本就永远丢失了。 使用加密的通常方法是用 ":X" 命令,它会提示你输入一个密钥。其后的一个写入命令会 使用该密钥加密文件。如果你以后编辑该文件,Vim 会要求你输入密钥。如果你的输入正 确,文件是可读的,不然,文本会显示为乱码。 *:X* :X 提示加密密钥。输入时不会反显输入的内容。别人即使看到屏幕,也不能看见你 的密钥。输入的字符保存在 'key' 选项里,它的值用来在写入文件时加密该文 件。在写入之前,该文件保持不变。另见 |-x|。 'key' 选项里的值在文件写入时使用。如果该选项非空,写入的文件会用它的值作为密钥 加密。加密过的文件的头部有个魔术数字,使得 Vim 可以识别这是加密文件。 要关闭加密,复位 'key' 选项为空值: :set key= 读入加密文件时如果该选项非空,它被用作解密的密钥。如果该值为空,你会得到提示, 输入密钥。如果你不输密钥,该文件以未解密的形式被编辑。 如果要以不同的密钥读入别的文件,设置 'key' 选项为空串,从而让 Vim 给出提示输入 新值。不要用 ":set" 命令输入该值,否则别人在你身后就能看到了。 因为 'key' 选项的值应该是个秘密,永远不要看它的值,也不要在 vimrc 文件里设置。 如果你把如下这行加到 "/etc/magic"、"/usr/share/misc/magic" 或者你系统支持的 "magic" 文件里,你的加密文件可以被 "file" 命令识别: 0 string VimCrypt~ Vim encrypted file 注意: - 如果用 'charconvert' 转换,不能实施加密。 - 你复制或者删除的文本保存在编号的寄存器中。寄存器可以保存在 .viminfo 文件里, 从而可以读到。修改你的 'viminfo' 选项以确保安全。 - 如果你走开一会儿,别入可能在 Vim 里输入命令,他不可能得到你的密钥。 - 如果你输入密钥时发生错误,你就无法取回你的文本了! - 如果你用 ":set key=value" 命令输入密钥,它会保存在历史里,从而在 viminfo 文 件里显示 'key' 的值。 - 没有 100% 的安全。Vim 的加密算法没有经过健壮性的严格测试。 - 我们用的算法是可以破解的。一个 4 字符的密钥需要大概一个小时,6 字符的密钥需 要一天 (在一台 Pentinum 133 PC 上)。这需要你知道文件里一定会出现的若干文本。 专家可以破解任何密钥,如果文本已经被解密,则密钥可以被推算出,而其他以相同密 钥加密的文件也能被解出。 - Pkzip 使用相同的加密方法,美国政府对其出口不持异议。 Pkzip 的公共文件 APPNOTE.TXT 详细描述了这一算法。 - Vim 起源于荷兰。这是源代码的出处。因此,加密代码并非从美国出口。

10. 修改时间 *timestamp* *timestamps*

Vim 记住文件开始编辑时的修改时间。这用来防止 (在你自己知道之前) 你有同一个文件 的不同版本。 在执行了外壳命令 (|:!cmd| |suspend| |:read!| |K|) 以后,Vim 会对窗口里的所有缓 冲区的修改时间进行比较。Vim 会对在此期间被修改的文件执行相关的 |FileChangedShell| 自动命令或者显示警告。GUI 上,在 Vim 取回输入焦点的时候也会 发生。 *E321* *E462* 如果你想自动重新载入在 Vim 之外被修改的文件的新内容,置位 'autoread' 选项。如 果你已经在 Vim 里修改过这个文件,这不会工作。 注意 如果定义了 FileChangedShell 自动命令,你不会得到警告信息或者提示。该自动 命令应负责处理。 对目录的修改也不会有警告 (例如在 |file-explorer| 里),除非你开始编辑一个新文 件,但它在外部被建立为一个目录。 当 Vim 注意到一个文件的修改时间被修改并且该文件正在缓冲区里等待编辑但还未经修 改,会先检查文件内容是否相同,这是通过再次读入该文件 (到一个隐藏缓冲区,该缓冲 区事后被立即删除),并比较两个缓冲区的文本完成的。如果相同,你不会得到警告。 如果你觉得警告不够及时或不够充分,你可以使用如下命令。 *:checkt* *:checktime* :checkt[ime] 检查是否有缓冲区在 Vim 之外被改变。 该命令检查你是否有 文件的两个版本并给出警告。 如果它在自动命令、":global" 命令或者任何非键盘输入中调 用,实际的检查会延迟,直到副作用 (重新读入文件) 不会有 任何问题。 每个已读入的缓冲区会检查相关的文件是否被改变。如果是, 则 Vim 会采取行动。如果缓冲区没有修改过而且置位了 'autoread',缓冲区被重新读入。否则,你会被询问是否重新 读入文件。如果文件被删除,你会得到一个错误信息。如果文 件过去不存在但现在已经存在,你会得到一个警告。 一旦检查过某个文件,他的修改时间被重置。因而,你不会被 重复警告。 :[N]checkt[ime] {filename} :[N]checkt[ime] [N] 检查某个特定缓冲区的修改时间。该缓冲区可以用名字、编号 或者模式指定。 在你写入文件的时候,修改时间被检查。如果发生了改变,Vim 会提示你是否要真的覆盖 该文件: WARNING: The file has been changed since reading it!!! Do you really want to write to it (y/n)? 如果你按 'y',Vim 会继续写入文件。如果你按 'n',写入操作被取消。如果你用 ":wq" 或者 "ZZ",Vim 因而不会退出。从而你还有机会写入文件。 通常,该消息意味着有人在编辑会话开始后,写入到该文件里。这可能是别人,这时你可 能想检查你的修改和别人的修改是否可以合并。将文件写到别的名字然后比较两者的差 异 (可以用 "diff" 程序)。 当然也有可能你自己在另外一个编辑会话中或者用别的命令 (例如一个过滤命令) 修改了 该文件。这样,你自己知道希望保留文件的哪个版本。 vim:tw=78:ts=8:ft=help:norl:

Generated by vim2html on 2006年 06月 24日 星期六 00:27:59 UTC