VimScript 速查表
VimScript 速查表
譯註:折騰 Vim 當然要能看懂和改寫相關指令碼,而中文資料匱乏,缺一個提綱挈領的教程。本文翻譯自 Andrew Scala 的 《Five Minute Vimscript》,立足於讓你用最短的時間掌握 VimScript 的基礎和要點,你可以把它看成一份語言速查表。
Vim有著豐富的內建文件系統,使用 :h <關鍵詞> 就可以閱讀,如果你想在方便的嘗試各種 vimscript ,你可以通過 NORMAL 模式下使用 gQ 命令進入 VimScript 的互動式環境除錯命令。
注意:下面的例子中會包含一些形如 <符號> 的符號,意味著正式使用時應該被完全替換成真實的東西,包括左右兩邊的尖括號。而單獨的 < 和 > 在 VimScript 中被用作比較符號。
變數
let 命令用來對變數進行初始化或者賦值。
unlet 命令用來刪除一個變數。
unlet! 命令同樣可以用來刪除變數,但是會忽略諸如變數不存在的錯誤提示。
預設情況下,如果一個變數在函式體以外初始化的,那麼它的作用域是全域性變數;而如果它是在函式體以內初始化的,那它的作用於是區域性變數。同時你可以通過變數名稱前加冒號字首明確的指明變數的作用域:
g:var - 全域性 a:var - 函式引數 l:var - 函式區域性變數 b:var - buffer 區域性變數 w:var - window 區域性變數 t:var - tab 區域性變數 s:var - 當前指令碼內可見的區域性變數 v:var - Vim 預定義的內部變數
你可以通過 $name 的模式讀取或者改寫環境變數,同時可以用 &option 的方式來讀寫 vim 內部的設定值。
資料型別
Number:32 位有符號整數
-123
0x10
0177
Float: 浮點數,需要編譯 Vim 的時候,有 +float 特性支援
123.456
1.15e-6
-1.1e3
String: NULL 結尾的 8位無符號字串
"ab\txx\"--"
'x-z''a,c'
Funcref: 函式引用,函式引用型別的變數名必須以大寫字母開頭
:let Myfunc = function("strlen") :echo Myfunc('foobar') " Call strlen on 'foobar'. 6
List: 有序列表
:let mylist = [1, 2, ['a', 'b']]
:echo mylist[0]
1
:echo mylist[2][0]
a
:echo mylist[-2]
2
:echo mylist[999]
E684: list index out of range: 999
:echo get(mylist, 999, "THERE IS NO 1000th ELEMENT")
THERE IS NO 1000th ELEMENT
Dictionary: 無序的 Key/Value 容器
:let mydict = {'blue': "#0000ff", 'foo': {999: "baz"}}
:echo mydict["blue"]
#0000ff
:echo mydict.foo
{999: "baz"}
:echo mydict.foo.999
baz
:let mydict.blue = "BLUE"
:echo mydict.blue
BLUE
沒有布林型別,整數 0 被當作假,其他被當作真。字串在比較真假前會被轉換成整數,大部分字串都會被轉化為 0,除非以非零開頭的字串才會轉化成非零。
(譯註:可以呼叫 type(varname) 來取得變數的型別,最新版 Vim 8.1 中已經包含 Boolean 型別,並且有 v:true, v:false 兩個值)
VimScript 的變數屬於動態弱型別。
:echo 1 . "foo"
1foo
:echo 1 + "1"
2
:function! TrueFalse(arg)
: return a:arg? "true" : "false"
:endfunction
:echo TrueFalse("foobar")
false
:echo TrueFalse("1000")
true
:echo TrueFalse("x1000")
false
:echo TrueFalse("1000x")
true
:echo TrueFalse("0")
false
字串比較
<string> == <string>: 字串相等
<string> != <string>: 字串不等
<string> =~ <pattern>: 匹配 pattern
<string> !~ <pattern>: 不匹配 pattern
<operator>#: 匹配大小寫
<operator>?: 不匹配大小寫
注意:設定選項 ignorecase 會影響 == 和 != 的預設比較結果,可以在比較符號新增 ? 或者 # 來明確指定大小寫是否忽略。
. : 字串連結
:function! TrueFalse(arg)
: return a:arg? "true" : "false"
:endfunction
:echo TrueFalse("X start" =~ 'X$')
false
:echo TrueFalse("end X" =~ 'X$')
true
:echo TrueFalse("end x" =~# 'X$')
false
If, For, While, and Try/Catch
條件判斷:
if <expression>
...
elseif <expression>
...
else
...
endif
迴圈:
for <var> in <list>
continue
break
endfor
複雜迴圈:
for [var1, var2] in [[1, 2], [3, 4]]
" on 1st loop, var1 = 1 and var2 = 2
" on 2nd loop, var1 = 3 and var2 = 4
endfor
While 迴圈:
while <expression>
endwhile
異常捕獲:
try
...
catch <pattern (optional)>
" HIGHLY recommended to catch specific error.
finally
...
endtry
函式
使用 function 關鍵字定義一個函式,使用 function! 覆蓋一個函式的定義,函式和變數一樣也有作用範圍的約束。需要注意函式名必須以大寫字母開頭。
function! <Name>(arg1, arg2, etc)
<function body>
endfunction
delfunction <function> 刪除一個函式
call <function> 呼叫一個函式,函式呼叫前的 call 語句是必須的,除非在一個表示式裡。
例如:強制建立一個全域性函式(使用感嘆號),引數使用 ... 這種不定長的引數形式時,a:1 表示 ... 部分的第一個引數,a:2 表示第二個,如此類推,a:0 用來表示 ... 部分一共有多少個引數。
function! g:Foobar(arg1, arg2, ...)
let first_argument = a:arg1
let index = 1
let variable_arg_1 = a:{index} " same as a:1
return variable_arg_1
endfunction
有一種特殊的呼叫函式的方式,可以指明該函式作用的文字區域是從當前緩衝區的第幾行到第幾行,按照 1,3call Foobar() 的格式呼叫一個函式的話,該函式會在當前檔案的第一行到第三行每一行執行一遍,再這個例子中,該函式總共被執行了三次。
如果你在函式宣告的引數列表後新增一個 range 關鍵字,那函式就只會被呼叫一次,這時兩個名為 a:firstline 和 a:lastline 的特殊變數可以用在該函式內部使用。
例如:強制建立一個名為 RangeSize 的函式,用來顯示被呼叫時候的文字範圍:
function! b:RangeSize() range
echo a:lastline - a:firstline
endfunction
面向物件
Vim 沒有原生的類的支援,但是你可以用字典模擬基本的類。為了定義一個類的方法,可以在函式宣告時使用 dict 關鍵字來將內部字典暴露為 self 關鍵字:
let MyClass = {"foo": "Foo"}
function MyClass.printFoo() dict
echo self.foo
endfunction
類的實現更類似於 singleton,為了在 VimScript 中建立類的例項,我們對字典使用 deepcopy() 方法進行拷貝:
:let myinstance = deepcopy(MyClass)
:call myinstance.printFoo()
Foo
:let myinstance.foo = "Bar"
:call myinstance.printFoo()
Bar
接下來做什麼?
現在既然你已經知道了大致原理,下面給你推薦一些好的資源
教程:
Vim 中文幫助文件(usr_41) - 編寫 Vim 指令碼和 API 列表
Vim 指令碼指北
Vim 指令碼開發規範
其他:
知乎:Vim 專欄
感謝
希望你覺得本文對你有用,感謝閱讀。
https://github.com/skywind3000/awesome-cheatsheets/blob/master/languages/vimscript.md