Cheat Sheet速查表
跳转到主要内容

Vim 脚本编写 速查表

本文根据 Devhints / Vim scripting 翻译。代码示例及版本范围沿用原文。原文标注更新日期:2020-07-05。

开始动手定制

let name = "John"
echo "Hello, " . name

你可以将其放入脚本中(script.vim)并运行它(:source script.vim),或者你也可以在普通模式下逐个输入这些命令,例如: :let 以及 :echo.

通过示例学习

function! SuperTab()
  let l:part = strpart(getline('.'),col('.')-2,1)
  if (l:part =~ '^\W\?$')
      return "\<Tab>"
  else
      return "\<C-n>"
  endif
endfunction

imap <Tab> <C-R>=SuperTab()<CR>

这里是另一个示例,其中包含了 函数, 变量 以及 映射.

变量

定义

let var = "hello"

变量前缀

let g:ack_options = '-s -H'    " g: global
let s:ack_program = 'ack'      " s: local (to script)
let l:foo = 'bar'              " l: local (to function)

该 s: 前缀也可用于函数名称。请参阅 :help local-variables

其他前缀

let w:foo = 'bar'    " w: window
let b:state = 'on'   " b: buffer
let t:state = 'off'  " t: tab
echo v:var           " v: vim special
let @/ = ''          " @  register (this clears last search pattern)
echo $PATH           " $  env

Vim 选项

echo 'tabstop is ' . &tabstop
if &insertmode
echo &g:option
echo &l:option

为 Vim 选项添加前缀 &

运算符

a + b             " numbers only!
'hello ' . name   " concat
let var -= 2
let var += 5
let var .= 'string'   " concat

字符串

字符串

let str = "String"
let str = "String with \n newline"

let literal = 'literal, no \ escaping'
let literal = 'that''s enough'  " double '' => '

echo "result = " . re   " concatenation

另请参阅 :help literal-string 以及 :help expr-quote。参见: 字符串

字符串函数

strlen(str)    " length
len(str)       " same
strchars(str)  " character length

split("one two three")       "=> ['one', 'two', 'three']
split("one.two.three", '.')  "=> ['one', 'two', 'three']

join(['a', 'b'], ',')  "=> 'a,b'

tolower('Hello')
toupper('Hello')

另请参阅 :help functions 参见: 字符串函数

函数

函数

" prefix with s: for local script-only functions
function! s:Initialize(cmd, args)
  " a: prefix for arguments
  echo "Command: " . a:cmd

  return 1
endfunction

参见: 函数

覆盖

function f1()
  echo "f1"
endfunction


function! f1()
  echo "f1 overridden"
endfunction

如果定义了两个同名函数,Vim 会抛出错误,提示该函数 f1 已存在。若要覆盖之前定义的同名函数,请添加 ! (置于 function 关键字之后)。

命名空间

function! myplugin#hello()

调用函数

call s:Initialize()
call s:Initialize("hello")

使用返回值

echo "Result: " . s:Initialize()

可中止

function! myfunction() abort
endfunction

发生错误时中止执行。

可变参数

function! infect(...)
  echo a:0    "=> 2
  echo a:1    "=> jake
  echo a:2    "=> bella

  for s in a:000  " a list
    echon ' ' . s
  endfor
endfunction

infect('jake', 'bella')

参见 :help function-argument。请参阅: 可变参数

循环

for s in list
  echo s
  continue  " jump to start of loop
  break     " breaks out of a loop
endfor
while x < 5
endwhile

自定义命令

自定义命令

command! Save :set fo=want tw=80 nowrap

自定义命令以大写字母开头。 ! 如果命令已存在,则会对其进行重定义。

调用函数的命令

command! Save call <SID>foo()
function! s:foo()
  ...
endfunction

带参数的命令

command! -nargs=? Save call script#foo(<args>)
内容内容
-nargs=00 个参数(默认)
-nargs=11 个参数(包含空格)
-nargs=?0 个或 1 个参数
-nargs=*0 个或多个参数(以空格分隔)
-nargs=+1 个或多个参数(以空格分隔)

Flow

条件判断

let char = getchar()
if char == "\<LeftMouse>"
  " ...
elseif char == "\<RightMouse>"
  " ...
else
  " ...
endif

真值性 (Truthiness)

if 1 | echo "true"  | endif
if 0 | echo "false" | endif
if 1       "=> 1 (true)
if 0       "=> 0 (false)
if "1"     "=> 1 (true)
if "456"   "=> 1 (true)
if "xfz"   "=> 0 (false)

无布尔类型。 0 为假, 1 为真。请参阅: 真值性 (Truthiness)

运算符

if 3 > 2
if a && b
if (a && b) || (c && d)
if !c

参见 :help expression-syntax。参见: 运算符

字符串

if name ==# 'John'     " case-sensitive
if name ==? 'John'     " case-insensitive
if name == 'John'      " depends on :set ignorecase

" also: is#, is?, >=#, >=?, and so on

同一性运算符

a is b
a isnot b

检查是否为同一个实例对象。

正则表达式匹配

"hello" =~ 'xx*'
"hello" !~ 'xx*'
"hello" =~ '\v<\d+>'

\v 启用“扩展”正则表达式模式,支持单词边界(<>), +等。

单行

if empty(a:path) | return [] | endif
a ? b : c

使用 | 用于将多行合并在一起。

布尔逻辑

if g:use_dispatch && s:has_dispatch
  ···
endif

列表 (Lists)

列表 (Lists)

let mylist = [1, two, 3, "four"]

let first = mylist[0]
let last  = mylist[-1]

" Suppresses errors
let second = get(mylist, 1)
let second = get(mylist, 1, "NONE")

函数

len(mylist)
empty(mylist)

sort(list)
let sortedlist = sort(copy(list))

split('hello there world', ' ')

连接

let longlist = mylist + [5, 6]
let mylist += [7, 8]

子列表

let shortlist = mylist[2:-1]
let shortlist = mylist[2:]     " same

let shortlist = mylist[2:2]    " one item

推送 (Push)

let alist = [1, 2, 3]
let alist = add(alist, 4)

映射 (Map)

call map(files, "bufname(v:val)")  " use v:val for value
call filter(files, 'v:val != ""')

字典

字典

let colors = {
  \ "apple": "red",
  \ "banana": "yellow"
}

echo colors["a"]
echo get(colors, "apple")   " suppress error

参见 :help dict

使用字典

remove(colors, "apple")
" :help E715
if has_key(dict, 'foo')
if empty(dict)
keys(dict)
len(dict)
max(dict)
min(dict)
count(dict, 'x')
string(dict)
map(dict, '<>> " . v:val')

迭代

for key in keys(mydict)
  echo key . ': ' . mydict[key]
endfor

前缀

keys(s:)

前缀(s:, g:, l:等)实际上就是字典。

扩展

" Extending with more
let extend(s:fruits, { ... })

类型转换(Casting)

str2float("2.3")
str2nr("3")
float2nr("3.14")

数字

数字

let int = 1000
let int = 0xff
let int = 0755   " octal

参见 :help Number。参见: 数字

浮点数

let fl = 100.1
let fl = 5.4e4

参见 :help Float

算术运算

3 / 2     "=> 1, integer division
3 / 2.0   "=> 1.5
3 * 2.0   "=> 6.0

数学函数

sqrt(100)
floor(3.5)
ceil(3.3)
abs(-3.4)

sin() cos() tan()
sinh() cosh() tanh()
asin() acos() atan()

Vim 特有用法

执行命令

execute "vsplit"
execute "e " . fnameescape(filename)

运行 ex 命令(通常在 Vim 中使用的命令) :. 另请参阅 :help execute。参见: 执行命令

执行按键序列

normal G
normal! G   " skips key mappings

execute "normal! gg/foo\<cr>dd"

使用 :normal 模拟在普通模式(normal mode)下的按键输入。可结合 :execute 使用以实现特殊按键操作。参见: 执行按键序列

获取文件名

echo expand("%")      " path/file.txt
echo expand("%:t")    " file.txt
echo expand("%:p:h")  " /home/you/path/file.txt
echo expand("%:r")    " path/file
echo expand("%:e")    " txt

参见 :help expand

静默处理

silent g/Aap/p

抑制输出。参见 :help silent

回响 (Echo)

echoerr 'oh it failed'
echomsg 'hello there'
echo 'hello'

echohl WarningMsg | echomsg "=> " . a:msg | echohl None

设置

set number
set nonumber
set number!     " toggle
set numberwidth=5
set guioptions+=e

提示符

let result = confirm("Sure?")
execute "confirm q"

内置功能

has("feature")  " :h feature-list
executable("python")
globpath(&rtp, "syntax/c.vim")

exists("$ENV")
exists(":command")
exists("variable")
exists("+option")
exists("g:...")

映射

映射命令

nmap
vmap
imap
xmap
nnoremap
vnoremap
inoremap
xnoremap
...

说明

[nvixso](nore)map
 │       └ don't recurse
 │
 └ normal, visual, insert,
   eX mode, select, operator-pending

参数

<buffer>仅在当前缓冲区(buffer)内生效
<silent>无回显
<nowait>

语法

高亮显示

hi Comment
  term=bold,underline
  gui=bold
  ctermfg=4
  guifg=#80a0ff

文件类型检测

augroup filetypedetect
  au! BufNewFile,BufRead *.json setf javascript
augroup END

au Filetype markdown setlocal spell

隐藏(Conceal)

set conceallevel=2
syn match newLine "<br>" conceal cchar=}
hi newLine guifg=green

区域隐藏

syn region inBold concealends matchgroup=bTag start="<b>" end="</b>"
hi inBold gui=bold
hi bTag guifg=blue

语法

syn match :name ":regex" :flags

syn region Comment  start="/\*"  end="\*/"
syn region String   start=+"+    end=+"+	 skip=+\\"+

syn cluster :name contains=:n1,:n2,:n3...

flags:
  keepend
  oneline
  nextgroup=
  contains=
  contained

hi def link markdownH1 htmlH1

包含保护(Include guards)

if exists('g:loaded_myplugin')
  finish
endif

" ...

let g:loaded_myplugin = 1