名字
Vim Script 是 Vim 用的脚本语言. 似乎正常来说被称为 Vim Script, 而也有的时候被称为 VimL. 反正不管叫啥, 都是指的这个脚本语言就是了.
单引号 / 双引号
单引号和双引号在 Vim Script 中还是有所不同的, 简单来说就是双引号中存在转义, 而单引号中不存在转义, 会原样输出, 简单举例:
:echo "\s" # print "s"
:echo '\s' # print "\s"
这个区别会导致在使用正则表达式的时候出现一些意料之外的情况.
稍后会提到这个问题.
正则表达式
在 Vim 的正则中, 很多元字符比如 +
必须写成 \+
才能生效, 一直不是很理解, 直到看到了下面的话. 虽然也是在别处看到的, 但是感觉很受用:
首先, Vim 是一个编辑器, 大家在编辑器中做一些查询的时候, 可能真的就只是做一些简单的查询. 虽然 Vim 查询的时候支持正则表达式, 但是人们使用时很多时候不需要用到正则表达式的效果.
比如, 你在 Vim 中输入 /foo(int)
, 那你大概率就是想查询名字叫 foo
, 参数是一个int
的函数, 而不是要把 int
放入到一个分组中. 也就是说, 人们在 Vim 中查询的时候, 即使用到了元字符, 其实很多时候也并不是想让它作为元字符生效.
所以为了避免类似的干扰, Vim 直接就规定在使用正则的时候所有的元字符前必须加上反斜杠才能生效, 于是 +
在 Vim 中就成为了 \+
.
另外还有一点, 如果在 Vim Script 中使用正则表达式的时候, 需要注意应该尽量使用单引号. 原因如上一节所述, 双引号中的字符会被转义.
举例来说, 你想匹配一个或者多个 1
, 那么你这样写 line =~ "1\+"
, 看起来没问题, 你还注意了需要使用 \+
来让元字符生效. 然而结果却肯定达不到你的预期. 因为双引号中的 \+
被转义成了一个 +
, 还是不能生效. 你真想在双引号中生效的话, 不得不写成 line =~ "1\\+"
. 很麻烦.
所以简单的做法就是直接使用单引号: line =~ '1\+'
.
一些小代码示例;
line = "123"
" 匹配符 =~
line =~ "1\\+" # true
line =~ '1\+' # true
" 不匹配符 !~
line !~ '5\+' # true
ex command
:
开头的都是 ex
命令, 比如 :echo hello world
. 事实上 VIM
底层就是基于 ex
的, VIM
是它的可视化版本. 在 vim script 中, 默认都是以 ex
命令执行的, 所以写 :
或者不写都是可行的.
" 以下等效
:echo hello world
echo hello world
注意上面字符串没有加引号. 因为 ex
命令正常是不需要引号的. 但是如果涉及到 exec
等命令的时候, 后面就需要跟带引号的字符串了.
exec "echo 'hello world'"
变量
b:
A variable recognized in a single Vim buffer
w:
A variable recognized in a single Vim window
t:
A variable recognized in a single Vim tab
g:
A variable recognized globally—i.e., it can be referenced anywhere
l:
A variable recognized within the function (a local variable)
s:
A variable recognized within the sourced Vim script
a:
A function argument
v:
A Vim variable—one controlled by Vim (these are also global variables)
函数
" Vim user-defined function names must begin with a capital letter.
function MyFunction (arg1, arg2...)
line of code
another line of codej
endfunction
autocmd && augroup
" autocmd [group] event pattern [nested] command
" autocmd event pattern command
" pattern for filetype
autocmd CursorMoved * call CheckFileType()
" define an autocmd within a group
augroup newFileDetection
autocmd CursorMoved * call CheckFileType()
augroup END
" show autocmds in given group
autocmd newFileDetection
" delete autocmds in given group
autocmd! newFileDetection
" delete given group(the group, not autocmds in it)
augroup! newFileDetection