vim script で遊ぶなら知っておきたい 10 の組み込み関数
vim script で遊ぶ時によく使う組み込み関数とか。
vimプラグインを作る場合だとまた違ってくると思います。
むしろ、そっちの方が誰かが書いてくれると嬉しいな(チラチラッ。
あと当然ながら詳細は help を参照してください。
☆まえがき
関数の可変長引数
関数の可変長引数は、リストで受け取ることが出来ます。
function! s:func(...) " a:0 は可変長引数の数 echo a:0 " a:000 可変長引数のリスト型 echo a:000 endfunction call s:func(42, 3.14, "hoge") " 3 " [42, 3.14, 'hoge']
辞書型の関数定義
辞書には、関数も定義することが出来ます。
let s:dict = {} let s:dict.value = 10 function! s:dict.func(value) " self で自分を参照する事ができる echo self.value + a:value endfunction " 関数の呼び出し call s:dict.func(5) " 15
☆type({expr})
{expr}の型を示す数値を返します。
数値 | 0 |
---|---|
文字列 | 1 |
Funcref | 2 |
リスト | 3 |
辞書 | 4 |
浮動小数点数 | 5 |
let s:value = 10 echo type(0) == type(s:value) " 1
☆eval({string})
文字列{string}を評価して、値を返します。
let s:value = 10 echo eval("s:value + 3") " 13 echo eval("type(s:value) == type('')") " 0
☆function({name})
関数{name}を参照する値を返します。
function! s:plus(a, b) return a:a + a:b endfunction " ユーザ定義関数 let s:func = function("s:plus") echo s:func(4, 1) " 5 " 組み込み関数 let s:func = function("type") echo s:func(s:func) == type(s:func) " 1
☆call({func}, {arglist} [, {dict}])
リスト{arglist} を引数として関数{func}を呼びます。
function! s:plus(a, b) return a:a + a:b endfunction " s:plus(3, 6) を呼ぶ echo call("s:plus", [3, 6]) " 9 " function で定義した値を渡す事も可 let s:func = function("s:plus") " s:plus(-6, 2) echo call(s:func, [-6, 2]) " -4 " 辞書の関数を呼ぶ let s:dict = {} let s:dict.value = 9 function! s:dict.func(value) return self.value + a:value endfunction let s:func = s:dict.func " 辞書の呼ぶ場合は、辞書も渡す必要がある echo call(s:func, [4], s:dict) " 13
☆keys({dict})/values({dict})
辞書{dict}のキー/値のリストを返します。
let s:dict = { "zero" : 0, "one" : 1, "two" : 2 } echo values(s:dict) " [1, 2, 0] " for 文で使用する for var in keys(s:dict) echo var endfor " one " two " zero
☆range({expr} [, {max} [, {stride}]])
連続した数値のリストを返します。
echo range(4) " [0, 1, 2, 3] echo range(2, 4) " [2, 3, 4] echo range(2, 9, 3) " [2, 5, 8] echo range(2, -2, -1) " [2, 1, 0, -1, -2] echo range(0) " [] " echo range(2, 0) " エラー
☆map({expr}, {string})
{expr}(リスト、辞書)の各要素を{string}で評価した結果で置き換えます。
{string}内では、v:val(要素の値)と v:key(辞書のキー)を使用することが出来ます。
{expr}は破壊的に変更されるので注意する必要があります。
let s:list = range(10) call map(s:list, "v:val * v:val") " s:list が直接変更される echo s:list " [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] " s:list を変更して欲しくない場合は、copy を使用する let s:result = map(copy(s:list), "v:val + v:val") echo s:result " [0, 2, 8, 18, 32, 50, 72, 98, 128, 162] echo s:list " [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
☆filter({expr}, {string})
{expr}(リスト、辞書)の各要素に対して、{string}を評価し、その結果が 0 ならば削除します
map と同様に{string}内では、v:val(要素の値)と v:key(辞書のキー)を使用することが出来ます。
{expr}は破壊的に変更されるので注意する必要があります。
let s:list =range(10) call filter(s:list, "v:val % 2 == 0") echo s:list " [0, 2, 4, 6, 8] " s:list を変更して欲しくない場合は、copy を使用する let s:result = filter(copy(s:list), "v:val > 4") echo s:result " [6, 8] echo s:list " [0, 2, 4, 6, 8]
☆join({list} [, {sep}])
リスト{list}の要素を連結し、文字列として返します。
{sep}が指定された時は、要素の間に{sep}を挿入します。
let s:list = range(10) let s:result = join(s:list, ", ") echo s:result " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
☆has_key({dict}, {key})
辞書{dict}が{key}の要素を持つなら1,持たないなら0を返します。
let s:dict = { "zero" : 0, "one" : 1, "two" : 2 } echo has_key(dict, "zero") " 1 echo has_key(dict, "three") " 0
☆その他、応用
[FizzBuzz]
let s:fizzbuzz = 'v:val % 15 == 0 ? "FizzBuzz" : v:val % 3 == 0 ? "Fizz" : v:val % 5 == 0 ? "Buzz" : v:val' echo map(range(1, 50), s:fizzbuzz) " [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz', 16, 17, 'Fizz', 19, 'Buzz', 'Fizz', 22, 23, 'Fizz', 'Buzz', 26, 'Fizz', 28, 29, 'FizzBuzz', 31, 32, 'Fizz', 34, 'Buzz', 'Fizz', 37, 38, 'Fizz', 'Buzz', 41, 'Fizz', 43, 44, 'FizzBuzz', 46, 47, 'Fizz', 49, 'Buzz']
[foldl]
function! s:foldl(op, state, list) return eval(join(insert(a:list, a:state), a:op)) endfunction echo s:foldl("+", 0, [1, 2, 3]) " 6 echo s:foldl("-", 0, [1, 2, 3]) " -6 echo s:foldl(".", "'list:'", [1, 2, 3]) " list:123
[apply]
function! s:apply(func, ...) return call(a:func, a:000) endfunction function! s:plus(...) return eval(join(copy(a:000), "+")) endfunction echo s:apply("s:plus", 3, 1, -5, 4) " 3