📄 usr_41.cnx
字号:
*usr_41.txt* For Vim version 6.3. 最近更新:2004年6月 VIM USER MANUAL - by Bram Moolenaar (译者:lang2 http://vimcdoc.sf.net) 编写 Vim 脚本Vim 脚本语言在很多地方用到,包括 vimrc 文件, 语法文件, 等等。本章讨论 Vim 脚本相关的知识。这样的内容有很多,所以本章也比较长。|41.1| 简介|41.2| 变量|41.3| 表达式|41.4| 条件语句|41.5| 执行一个表达式|41.6| 使用函数|41.7| 定义一个函数|41.8| 异常|41.9| 其它讨论|41.10| 编写插件|41.11| 编写文件类型插件|41.12| 编写编译器插件 下一章: |usr_42.txt| 添加新的菜单 前一章: |usr_40.txt| 创建新的命令 目录: |usr_toc.txt|==============================================================================*41.1* 简介 *vim-script-intro*你最初接触到 Vim 脚本是在 vimrc 文件里。当 Vim 启动时它将读取该文件的内容并执行其中的命令。你可以在其中设置可选项。你可以在其中使用任何冒号命令 (以":" 开头的命令; 这些命令有时也被称作 Ex 命令或命令行命令)。 语法文件其实也是 Vim 脚本。专为某种文件类型设定选项的文件也是。一个很复杂的宏可以被单独的定义在一个 Vim 脚本文件中。你还可以想到其它的应用。让我们从一个简单的例子开始: > :let i = 1 :while i < 5 : echo "count is" i : let i = i + 1 :endwhile< Note:(注意) 那些 ":" 字符并非必须的。它们只是在当你键入命令时才需要。在编写 Vim 脚本是可以去掉。在这里使用一是为了清楚,二是为了区别于普通模式命令。":let" 命令给一个变量赋值。通常的用法是: > :let {变量} = {表达式}在例子中变量名是 "i" 而表达式是一个简单的数值 -- 1。 ":while" 命令开始一个循环。通常的用法是: > :while {条件} : {语句} :endwhile只要条件为真,"while" 和 ":endwhile" 包围的语句总被执行。在例子中使用的条件是表达式 "i < 5"。这个条件在变量 i 小于五时总是真的。 ":echo" 命令打印它的参数。在这个例子中的参数是字符串 "count is" 和变量 i 的值。因为开始时 i 的值是一, 所以将会打印: count is 1 ~接着是另一个 ":let i =" 命令。所用的表达式是 "i + 1"。这将在变量 i 上加一并将新的值赋给同一个变量。 本例的输出是: count is 1 ~ count is 2 ~ count is 3 ~ count is 4 ~ Note: (注意) 如果你碰巧写了一个死循环语句,你可以用 CTRL-C 来终止 (在 MS-Windows 中使用 CTRL-Break)。三 种 数 字数字可以是十进制,十六进制,或者八进制的。以 "0x" 或 "0X" 开始的数字是十六进制的。例如 "0x1f" 代表 31。以零开始的数字是八进制的。"017" 代表 15。注意:不要在十进制数前加零,那样该数字将会被作为八进制数对待! ":echo" 命令总以十进制格式打印数字。例: > :echo 0x7f 036< 127 30 ~在一个数字前加上减号会将其变为负值。十六进制数和八进制数亦然。减号也用于减法操作。将下例与前面的比较: > :echo 0x7f -036< 97 ~表达式中的空白字符将被忽略。然而,为了增加表达式的易读性,建议在不同项之间使用。例如,为了不和负号混淆,在减号和之后的数字前加入一个空格: > :echo 0x7f - 036==============================================================================*41.2* 变量一个变量名可以由 ASCII 字符,数字和下划线组成。但是变量名不能以数字开始。以下是几个有效的变量名: counter _aap3 very_long_variable_name_with_dashes FuncLength LENGTH"foo+bar" 和 "6var" 都是无效的变量名。 这些变量都是全局的。要列出当前定义的所有变量可以用这个命令: > :let你可以在任何地方使用全局变量。这同时也意味着: 当一个脚本文件使用 "count"变量时,可能另一个脚本文件也使用了这个变量。这至少会引起混乱,严重时会导致脚本无法正常工作。为避免这种情况发生,你可以在变量名前加上 "s:" 使其变成脚本文件的本地变量。例如,一脚本包含以下代码: > :let s:count = 1 :while s:count < 5 : source other.vim : let s:count = s:count + 1 :endwhile由于 "s:count" 是本地变量,你可以确信调用 (source) "other.vim" 脚本不会改变它的值。如果 "other.vim" 也使用一个 "s:count"变量,该变量将会是仅在脚本内有效的本地变量。更多关于脚本本地变量可以在这里读到: |script-variable|.还有很多其他类型的变量, 参阅 |internal-variables|. 最常用的几类有: b:name 缓冲的本地变量 w:name 窗口的本地变量 g:name 全局变量 (也用于函数中) v:name Vim 预定义的变量删 除 变 量变量不仅仅可以在 ":let" 命令显示,同时也占用内存空间。为了删除一个变量可以使用":unlet" 命令。例: > :unlet s:count这将删除 "s:count" 这个脚本本地变量并释放其占用的内存。如果你并不确定这个变量是否存在,但并不希望系统在它不存在时报错,可以在命令后添加 !: > :unlet! s:count当一个脚本结束时,它使用的本地变量不会自动被删除。下一次脚本被执行时,旧的变量仍可能被使用。例: > :if !exists("s:call_count") : let s:call_count = 0 :endif :let s:call_count = s:call_count + 1 :echo "called" s:call_count "times""exists()" 函数检查一个变量是否已经被定义过了。它的参数是你想检查的变量的名字。而不是变量本身!如果你这样做: > :if !exists(s:call_count)那么变量 s:call_count 的值将被用来做检测。那不是你想要到的。 惊叹号 ! 将一个值取反。当该值为真时,表达式的值为假。当该值为假时,表达式的值为真。你可以把它读作 "not"。这样 "if !exists()" 可以被读作 "if not exists()". Vim 把任何非零的值当作真。只有零才是假。字 符 串 变 量 和 常 量到目前为止我们只用到了数值作为变量的值。同样的我们可以使用字符串。Vim 仅仅支持这两种变量类型。变量的类型是动态的。每当我们通过 ":let" 语句为变量赋值时,变量的类型才被确定。 你需要使用字符串常量来为字符串变量赋值。字符串常量有两种。第一种是由双引号括起来的: > :let name = "peter" :echo name< peter ~如果你想在这样的字符串内使用双引号,在之前加上反斜杠即可: > :let name = "\"peter\"" :echo name< "peter" ~如果你不想使用反斜杠,用单引号括起来的字符串也可以: > :let name = '"peter"' :echo name< "peter" ~所有的字符在单引号内都保持其本来面目。这样做的缺点是无法在字符串中包括一个单引号。因为反斜杠在其中也被作为其本身来对待,你无法使用它来改变其后的字符的意义。 在双引号括起来的字符转中可以使用特殊字符。这里有一些有用的例子: \t <Tab> \n <NL>, 换行 \r <CR>, <Enter> \e <Esc> \b <BS>, 退格 \" " \\ \, 反斜杠 \<Esc> <Esc> \<C-W> CTRL-W最后两个只是用来举例子的。"\<name>" 的形式可以被用来表示特殊的键 "name"。 在 |expr-quote| 中列出了全部的特殊字符。==============================================================================*41.3* 表达式Vim 脚本支持的表达式很丰富,也很容易使用。你可以在这里读到表达式的定义:|expression-syntax|。这里我们只看看常用的几个。 已经提到的那些数值,字符串常量和变量都属于表达式。因此任何可以使用表达式的地方,数值,字符串变量和常量都可以使用。其它基本的表达式有: $NAME 环境变量 &name 选项 @r 寄存器例子: > :echo "The value of 'tabstop' is" &ts :echo "Your home directory is" $HOME :if @a > 5&option 这种形式可以被用来暂时改变一个选项的值。例: > :let save_ic = &ic :set noic :/The Start/,$delete :let &ic = save_ic这样既确保了在匹配 "The Start" 模式时 'ignorecase' 选项是关闭的,同时也保留了用户原来的选项值。算 术我们把这些基本的东西都混合起来用就更有趣了。先来看看算术运算: a + b 加 a - b 减 a * b 乘 a / b 除 a % b 余先乘除,后加减。例如: > :echo 10 + 5 * 2< 20 ~括号内的先计算。这也没什么奇怪的。例如: > :echo (10 + 5) * 2< 30 ~用 "." 可以把两个字符串联结起来。例如: > :echo "foo" . "bar"< foobar ~一般的,当 ":echo" 命令遇到多个参数时,会在它们之间加入空格。但上例中参数是是一个表达式,所以不会有空格。下面的条件表达式很显然是从 C 语言里借来的: a ? b : c如果 "a" 为真用 "b",否则用 "c"。例如: > :let i = 4 :echo i > 5 ? "i is big" : "i is small"< i is small ~在整个表达式被求值前,结构中的三部分总是先被求值的。因此你可以将其视为: (a) ? (b) : (c)==============================================================================*41.4* 条件语句":if" 命令在条件满足的前提下,执行其后直到 ":endif" 的所有语句。常用的形式为: :if {condition} {statements} :endif语句 {statements} 仅当表达式 {condition} 为真(非零)时才被执行。这些语句还必须是有效的。否则 Vim 无法找到相应的 ":endif". 你也可以使用 ":else". 常用形式为: :if {condition} {statements} :else {statements} :endif语句 {statements} 仅当第一个条件不满足时被执行。 最后还有 ":elseif": :if {condition} {statements} :elseif {condition} {statements} :endif这种形式就像 ":else" 接着 "if" 一样,但是少出现一个 ":endif". 下面是一个有用的例子(可以用在你的 vimrc 文件里):它检查 'term' 选项并根据不同的值做不同的操作: > :if &term == "xterm" : " Do stuff for xterm :elseif &term == "vt100" : " Do stuff for a vt100 terminal :else : " Do something for other terminals :endif逻 辑 操 作实际上我们在前面的几个例子中已经是用到了。下面是几个最常用的形式: a == b 等于 a != b 不等于 a > b 大于 a >= b 大于等于 a < b 小于 a <= b 小于等于如果条件满足,结果为 1,否则为 0。例如: > :if v:version >= 600 : echo "congratulations" :else : echo "you are using an old version, upgrade!" :endif这里 "v:version" 是 Vim 定义的变量,用来存放 Vim 的版本号。600 意为 6.0 版。6.1 版的值为 601。这对编写可以在不同版本的 Vim 上运行的脚本很有用。参阅|v:version|对数字和字符串都可以做逻辑操作。两个字符串的算术差被用来比较他们的值。差是通过字节值来计算的,对于某些语言可能无法得到正确的结果。 在比较一个字符串和一个数字时,该字符串将先被转换成一个数值。这有些复杂,因为当一个字符串看起来不像数字时,它会被当作 0 对待。例如: > :if 0 == "one" : echo "yes" :endif上面的例子将显示 "yes", 因为 "one" 看起来不像一个数字所以被转换为 0 了。对于字符串来说还有两种操作: a =~ b 匹配 a !~ b 不匹配左边的 "a" 被当作一个字符串。右边的 "b" 被当作一个匹配模式,正如做查找操作一样。例如: > :if str =~ " " : echo "字符串包括空格" :endif :if str !~ '\.$' : echo "字符串以句号结尾" :endif注意在匹配模式中用单引号是很有用的。因为匹配模式中通常有很多反斜杠,而反斜杠在双引号字符串中必须双写才有效。在做字符串比较时 'ignorecase' 选项被用到。如果你不希望使用该选项,可以在比较是加上 "#" 或 "?"。"#" 表示大小写敏感;"?" 表示忽略大小写。因此 "==?" 比较
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -