読者です 読者をやめる 読者になる 読者になる

Vim 8.0 で強化された機能 辞書関数

Vim

さて、以前の辞書関数は次のように call() と辞書を経由して呼び出す必要がありました。

let s:dict = { "value" : 0 }
function! s:dict.up()
    let self.value += 1
    return self.value
endfunction

let s:f = s:dict.up
echo call(s:f, [], s:dict)
" => 1
echo call(s:f, [], s:dict)
" => 2
echo call(s:f, [], s:dict)
" => 3

Vim 8.0 ではこの縛りが緩和されて、辞書関数を直接呼び出すことができるようになりました。

let s:dict = { "value" : 0 }
function! s:dict.up()
    let self.value += 1
    return self.value
endfunction

let s:f = s:dict.up
echo s:f()
" => 1
echo s:f()
" => 2
echo s:f()
" => 3

めちゃくちゃ便利…。

Vim 8.0 で追加された Vim script の機能 Lambda

Vim

Vim 8.0 ではついに Vim script に Lambda が追加されました! Lambda を定義する場合は { args -> expr } という構文を使用します。

" Lambda は関数参照を返す
" epxr にはその名の通り "式" のみ書くことができる
let F = { a, b -> a + b }

echo F(1, 2)
" => 3

また filter() 関数などに直接 Lambda を渡すことも出来ます。

echo filter(range(1, 10), { index, val -> val % 2 == 0 })
" => [2, 4, 6, 8, 10]

[変数のキャプチャ]

次のように Lambda 外のローカル変数もキャプチャされます。

function! s:main()
    let value = 10
    let F = { a -> value + a }
    echo F(5)
   " => 15
endfunction
call s:main()

[Lambda 内では式しか定義できない]

Lambda 内では式のみ定義できるので、コマンドなどを直接呼び出すことは出来ません。

" このような使い方は出来ない
let Nonumber = { -> set nonumber }

この場合は、同じく Vim 8.0 で追加された execute() 関数を使用します。 execute() は引数のコマンドを実行する関数になります。

" execute() を経由してコマンドを呼び出す
let Nonumber = { -> execute("set nonumber") }

このように execute() を経由することでコマンドを式として呼び出すことが出来ます。

[引数に a: をつける必要はない]

Lambda 内で使用する引数には a: をつける必要はありません。 ですので次のように外部の引数を参照することも出来ます。

function! s:main(arg)
    let F = { a -> a:arg + a }
    echo F(5)
   " => 15
endfunction
call s:main(10)

Vim 8.0 で追加された新しいシンタックス

Vim

Vim 8.0 では新しく以下の言語に対応しました。

New Syntax/Indent/FTplugin files:

AVR Assembler (Avra) syntax
Arduino syntax
Bazel syntax and indent and ftplugin
Dockerfile syntax and ftplugin
Eiffel ftplugin
Euphoria 3 and 4 syntax
Go syntax and indent and ftplugin
Godoc syntax
Groovy ftplugin
HGcommit ftplugin
Hog indent and ftplugin
Innovation Data Processing upstream.pt syntax
J syntax and indent and ftplugin
Jproperties ftplugin
Json syntax and indent and ftplugin
Kivy syntax
Less syntax and indent
Mix syntax
Motorola S-Record syntax
R ftplugin
ReStructuredText syntax and indent and ftplugin
Registry ftplugin
Rhelp indent and ftplugin
Rmd (markdown with R code chunks) syntax and indent
Rmd ftplugin
Rnoweb ftplugin
Rnoweb indent
Scala syntax and indent and ftplugin
SystemVerilog syntax and indent and ftplugin
Systemd syntax and indent and ftplugin
Teraterm (TTL) syntax and indent
Text ftplugin
Vroom syntax and indent and ftplugin

メジャーどころだと GoJsonScalaGroovy あたりですかねえ。

Vim 8.0 で追加された機能 function() 関数

Vim

Vim 8.0 では function() 関数の引数が新たに追加されました。

[引数の束縛]

function() の第二引数に第一引数に渡す関数の引数を渡すことで、引数の束縛を行うことができるようになりました。

function! Plus(a, b)
    return a:a + a:b
endfunction

" 第一引数を束縛
let s:Plus3 = function("Plus", [3])

echo s:Plus3(2)
" => 5
echo s:Plus3(-5)
" => -2

[関数が参照する辞書を指定]

第三引数に辞書を渡すことで、関数が参照する辞書を指定することが出来ます。

function! Disp() dict
    return self.name . " : " . self.age
endfunction

let s:data = { "name" : "homu", "age" : 14 }
let s:Disp = function("Disp", [], s:data)
echo s:Disp()

関数の束縛がかなり便利。

Vim 8.0 で追加された機能 uniq() 関数

Vim 8.0 で『配列の隣り合う同じ値の要素を削除する』uniq() 関数が追加されました。

echo uniq([1, 1, 3, 2, 2, 3, 3, 1])
" => [1, 3, 2, 3, 1]

また、重複する要素をすべて削除したい場合は、 sort() と併用して使用します。

" sort() してから uniq() する
echo uniq(sort([1, 1, 3, 2, 2, 3, 3, 1]))
" => [1, 2, 3]

Vim 8.0 で追加された機能 :smile

Vim

Vim 8.0 で :smile というコマンドが追加されました。
このコマンドを実行すると以下のような出力がされます。

それだけ。

[コマンドが追加された経緯]

:smile コマンドは次のような経緯で追加されたらしいです。

twitter.com

Vim 8.0 で追加された機能 EndOfBuffer ハイライトグループ

Vim

Vim 8.0 で EndOfBuffer というハイライトグループが追加されました。 これはバッファ外に表示されてる ~ の部分を制御するハイライトグループになります。
以下のようにハイライトを設定することで ~ のハイライトを無効にすることが出来ます。

highlight link EndOfBuffer Ignore