Vim 8.0 で追加された機能 タイマーを一時停止する
前回書き忘れたので追記。
timer_pause()
を使用します。
" 一時停止 call timer_pause(timer_id, 1) " 再開 call timer_pause(timer_id, 0)
これで一時的にタイマーを停止したり、任意のタイミングで再開する事が出来ます。
Vim 8.0 で追加された機能 タイマー
Vim 8.0 ではついに Vim script にタイマー機能が追加されました!
この機能を使用することで処理をブロックしないで関数を呼び出すことが出来ます。
[基本的な使い方]
タイマーは timer_start()
関数を使用して任意の関数を n 時間後に呼び出す事が出来ます。
function! s:disp(timer) echo "callback" endfunction " 第一引数に時間、第二引数に呼び出す関数参照を渡す " 1000ミリ秒後に s:disp をブロックしないで呼び出す call timer_start(1000, function("s:disp"))
[タイマーを止める]
タイマーを止めたい場合、timer_start()
が返した ID と timer_stop()
を利用します。
" タイマーIDを受け取る function! s:disp(timer) echo "callback" endfunction let s:id = timer_start(1000, function("s:disp")) " ID のタイマーを止める call timer_stop(s:id)
コールバック関数が受け取る timer
は timer_start()
で生成された ID になります。
また、timer_stopall()
ですべてのタイマーを止める事が出来ます。
[回数を指定する]
timer_start()
の第三引数にリピートする回数を指定する事が出来ます。
let s:counter = { "value" : 0 } function! s:counter.count(...) echo self.value let self.value += 1 endfunction " 1000ms ごとに s:counter.count() を 3回呼び出す call timer_start(1000, s:counter.count, { "repeat" : 3 })
また、-1
をすることでタイマーを止めるまで呼ばれ続けます。
let s:counter = { "value" : 0 } function! s:counter.count(timer) echo self.value let self.value += 1 " 5回呼ばれたら止める if self.value >= 5 call timer_stop(a:timer) endif endfunction " 1000ms ごとに s:counter.count() を呼び出し続ける call timer_start(1000, s:counter.count, { "repeat" : -1 })
かなり便利。
Vim 8.0 で強化された機能 辞書関数
さて、以前の辞書関数は次のように 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
めちゃくちゃ便利…。
RSpec で not_change マッチャを定義する
通常、Rspec で『変更されないことを検証する』場合、change
マッチャを使用します。
# subject を呼び出しても hoge が変更されないことを検証する
it { is_expected.not_to change{ hoge } }
[not_change
マッチャを定義する]
上記のコードでも問題ないのですが、 RSpec::Matchers.define_negated_matcher
を使用すると書き方を変えることができます。
# change マッチャの否定を定義する RSpec::Matchers.define_negated_matcher :not_change, :change # to を呼び出し、マッチャの名前を変更する it { is_expected.to not_change{ hoge } }
おもしろい
Ruby の ObjectSpace を利用して、オブジェクト名からクラスオブジェクトを探す
Ruby で例えば "String"
という文字列からその名前のクラスオブジェクトを取得したい場合があるとします。
そういう場合は ObjectSpace
から逆算して検出することができます。
# クラスオブジェクトの一覧を取得する classes =ObjectSpace.each_object(::Class) # クラスオブジェクトの一覧から該当するクラスオブジェクトを探す target = "String" result = classes.find { |klass| klass.name == target } p result == String # => truk
また、Rails では String#constantize
というメソッドが定義されており、上記と同等の機能があります。
"String".constantize # => String
[参照]
Vim 8.0 で追加された Vim script の機能 Lambda
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 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
メジャーどころだと Go
、Json
、Scala
、Groovy
あたりですかねえ。