现在的位置: 首页 > 综合 > 正文

使用Vim脚本

2019年10月31日 ⁄ 综合 ⁄ 共 3847字 ⁄ 字号 评论关闭

4. 使用 Vim 脚本 *using-scripts*

参阅用户手册第 41 章 |usr_41.txt| 了解如何写 Vim 脚本。

*:so* *:source* *load-vim-script*
:so[urce] {file} 从 {file} 里读取 Ex 命令,即 ":" 开头的命令,并执行。
激活 |SourcePre| 自动命令。

:so[urce]! {file} 从 {file} 里读取 Vim 命令,就像你在普通模式下键入的命
令一样。
如果要执行的命令在 |:glboal|、|:argdo|、|:windo| 或
|:bufdo| 之后、在循环体内、或者有另外一个命令紧跟其
后,那么执行时不会更新屏幕显示。
{Vi 无此功能}

*:ru* *:runtime*
:ru[ntime][!] {file} ..
从 'runtimepath' 指定的目录里查找 {file}。从匹配的文件
里读取 Ex 命令。如果没有匹配的文件,不报错。例如: >
:runtime syntax/c.vim

< 可以指定多个以空格分隔的 {file} 参数。每个 {file} 都从
'runtimepath' 指定的第一个目录开始查找,然后是第二个、
第三个,等等。{file} 里可以通过加反斜杠来包含空格 (不
过,为了避免麻烦,最好不要在文件名里使用空格)。

如果使用了 [!],所有找到的文件都被执行。否则,只执行第
一个找到的文件。

如果 {file} 包含通配符,它被扩展为所有的匹配文件名。例
如: >
:runtime! plugin/*.vim
< 这是 Vim 启动的时候启动插件所使用的命令。类似的: >
:runtime plugin/*.vim
< 只会执行其中的第一个文件。

当 'verbose' 至少为一时,如果没有文件找到,会显示信息。
当 'verbose' 至少为二时,对每个搜索到的文件都会提示信
息。
{Vi 无此功能}

:scripte[ncoding] [encoding] *:scripte* *:scriptencoding* *E167*
指定脚本使用的字符编码。后续以 [encoding] 编码的脚本行
会被转换成 'encoding' 选项所指定的编码,如果两者不同的
话。如: >
scriptencoding iso-8859-5
scriptencoding cp932
<
如果 [encoding] 为空,则不作任何转换。这可以用来避免对
一些行进行转换: >
scriptencoding euc-jp
... 被转换的行 ...
scriptencoding
... 不被转换的行 ...

< 如果系统不支持所需的转换,不会有错误信息,但转换也不会
发生。

不要用 "ucs-2" 或者 "ucs-4"。Vim 不能用这些编码的脚本
(因为其中会有 NUL 字节)。如果一个待执行的脚本以一个
BOM (Byte Order Mark 字节顺序标记) 开头,Vim 会识别其
为 utf-8 编码,从而无须指定 ":scriptencoding utf-8"。

如果编译时没有指定 |+multi_byte| 特性,这个命令会被忽
略。
{Vi 无此命令}

*:scrip* *:scriptnames*
:scrip[tnames] 列出所有执行过的脚本名字,以它们初次执行之顺序排列。排
列的次序号码被用作相应的脚本 ID |<SID>|。
{Vi 无此功能} {仅当编译时加入 |+eval| 特性才有功能}

*:fini* *:finish* *E168*
:fini[sh] 停止执行脚本。只能用在 Vim 脚本中,来快速跳过脚本的其
余内容。如果出现在 |:try| 之后但在相应的 |:finally|
(如果存在的话) 之前,":finally" 到 |:endtry| 的内容还
会执行。执行完所有嵌套的 ":try" 层的 ":finally" 代码
后,最外层的 ":endtry" 才会最终真正停止脚本的执行。
{Vi 无此功能}

所有的命令和命令序列可以通过把它们放在命名的寄存器里执行来重复调用。有两个方法
可以把命令放在寄存器里:
- 用记录命令 "q"。可以键入一串命令,在执行的同时它们被存入一个寄存器里。这很简
  明,因为你能看见你所做的事情。如果你敲错了,用 "p" 把寄存器的内容 "放置" 在
  一个文件里,然后编辑这个命令序列,把它们再次放回到 (比如,用删除命令) 寄存器
  里。你也可以用大写名字的寄存器名来附加命令,从而继续上次的纪录。
- 删除 (delete) 或者抽出 (yank) 命令序列到寄存器。

常用的命令序列可以用 ":map" 命令映射到一个功能键上。

另外一个办法则是把命令写到一个文件里,用 ":source!" 命令执行之。这对很长的命令
序列有用。你甚至可以把它和 ':map' 命令混合使用,从而用一个功能键来储存复杂的功
能。

':source' 命令从文件里逐行读取 Ex 命令。如果其间需要键盘输入,你需要自己键入。
'source!' 命令从脚本里逐字读取命令,就像你自己敲入每一个字符一样。

示例: 如果你给出一个 ':!ls' 命令,你得到一个 |hit-enter| 提示。如果你用
':source' 执行包含 '!ls' 一行的文件,你必须按一个回车。不过如果你用 ':source!'
来执行包含 ':!ls' 的文件,其后的字符会依次读入,直到遇到一个 <CR> 为止。你不需
要通过键盘键入这个 <CR>,除非 ":!ls" 是文件的最后一行。

在脚本里当然也可以有 ':source[!]' 命令,从而可以建立一个自顶而下的脚本调用树。
':source' 命令允许的嵌套深度由同时打开的最大的文件数目决定 (大概 15 个左右),
':source!' 命令许可的嵌套深度则最多为 15 层。

在被执行的文件里,你可以在需要文件名的地方用 "<sfile>" 字符串 (直接的文本,不
是一个特殊的键)。它会被被执行的文件的名字来代替。例如,如果你在 ".vimrc" 文件
相同的目录里有一个 "other.vimrc" 文件,你可以在 ".vimrc" 里如此调用它: >
:source <sfile>:h/other.vimrc

在脚本文件里,依赖于终端的键码由不依赖于终端的两个字符码代表。这样,他们就能在
不同的终端里代表相同的意义。这里,第一个字符码是 0x80 或者 128,屏幕上显示
为 "~@"。第二个字符可以在 |key-notation| 列表里找到。这些编码也可以用 CTRL-V
加上一个三位数字的十进制码来键入。这个方法_不_适用于 <t_xx> termcap 代码,它们
只能用在映射里。

*:source_crnl* *W15*
MS-DOS、Win32 和 OS/2: 用 ":source" 执行的文件通常每行以 <CR><NL> 结尾。这没有
问题。在 'fileformats' 非空并且第一行不以 <CR> 结尾的时候,用 <NL> 的行结尾
(比如,Unix 编写的文件) 会被识别。不过,如果第一行里有 ":map <F1> :help^M" 这
样的内容 (其中 ^M 是一个 <CR>),这个机制会失败。如果第一行以
<CR> 结尾,但其后的行不是,那你会得到错误信息,因为第一行里的 <CR> 会丢失。

Mac Classic: 用 ":source" 执行的文件通常每行以 <CR> 结尾。这没有问题。在
'fileformats' 非空并且第一行不以 <CR> 结尾的时候,用 <NL> 的行结尾 (比如,Unix
编写的文件) 会被识别。如果用 <NL> 行结尾的时候,要小心第一行不要有 <CR>。

在别的系统上,Vim 期待 ":source" 执行的文件以 <NL> 行结尾。这没有问题。如果你
的文件用 <CR><NL> 结束行 (比如,MS-DOS 编写的文件),所有的行都会有一个附尾的
<CR>。有些命令 (比如映射命令) 会因此有问题。这里不使用自动换行符识别机制,因为
第一行出现以 <CR> 结尾的映射命令很常见,自动机制这时容易出错。

*line-continuation*
":source" 执行的 Ex 命令脚本里的长行可以用通过在下一行的开始插入续行符 "\" (反
斜杠) 来分开。反斜杠之前可以出现空格,它们将被忽略。

示例: 如下几行 >
:set comments=sr:/*,mb:*,el:*/,
    \://,
    \b:#,
    \:%,
    \n:>,
    \fb:-
会被解读为一行: >
:set comments=sr:/*,mb:*,el:*/,://,b:#,:%,n:>,fb:-

每行反斜杠之前的所有引导空白字符会被忽略。注意: 在此之前的一行的行尾的空格可能
不能随便添加;这由命令分开的位置决定,那里也许可以也许不可以有额外的空格。

需要空格时最好放在反斜杠之后。行尾的空格很难注意到,很可能会被意外删除掉。 >
:syn match Comment
\ "very long regexp"
\ keepend

在用 ":append" 和 ":insert" 命令时,有一个问题: >
   :1append
   \asdf
   .
反斜杠被看作续行符,所以这等价于以下命令: >
   :1appendasdf
   .
要避免这一点,在 'cpoptions' 选项里加上 'C' 标志位: >
   :set cpo+=C
   :1append
   \asdf
   .
   :set cpo-=C

要 注意 在函数里的命令里用到这些命令时,你需要在定义函数的时候加上 'C' 标志
位,不是在执行函数的时候。 >
   :set cpo+=C
   :function Foo()
   :1append
   \asdf
   .
   :endfunction
   :set cpo-=C

原理:
许多程序用行尾的反斜杠来指示行要继续。如果这样,Vim 会和 Vi 不兼容。例
如下面的 Vi 映射: >
:map xx  asdf\
< 因此,只能用特殊形式的出现在行首的反斜杠。

抱歉!评论已关闭.