この記事は Vim script Advent Calendar 2015の 16日目の記事です。
Shell から特定の target.vim
を実行した時に何かしらの出力を得たい。
実行自体は次のようにすることで可能です。
$ vim -S target.vim -c 'qa!'
あるいは、
$ vim -c 'so target.vim | qa!'
-N
と -u NONE
が必要かは場合によります。
詳細はヘルプを見ましょう。(--cmd
という選択肢もある 1)
:h-N:h-u:h-S
:h-c:h--cmd
:h :so:h :bar
さて、おもむろに次のヘルプを見ましょう。
:h Q
:h gQ
:h-E
:h-s-ex:h :put:h :print
:h [range]
簡単に説明すると、Q
, gQ
というのは Ex モード
に入るキーバインドです。あまり使う機会がないので別のマッピングをしている人も多いと思います2。そのような場合は vim -E
などで試すことができます(-s
をつけると試す分には辛い)。
編集用のコマンドは :h inserting-ex
, :h change.txt
などで /^:
を探すのが参考になります。
なお、途中で :redraw
を用いることでバッファの表示を更新することができます。
さて、上記のスクリーンショットでは Vim
のコマンドラインウィンドウによる対話環境で実行されていますが -s
オプションをつけると Shell
で実行されるようになります。その際に Vim
は標準出力を用いるわけです。
実践
つまり、こうです。
hello.vim
put='Hello, world!'
watiko@local $ vim -NEsS hello.vim -c '2,$print | qa!'Hello, world!
これを次のスクリプトで試してみます。
fib.vim
lets:fib = {
\ 'memo' : [0,1]
\ }
fu!s:fib.calc(to)letl:from = len(self.memo)foriin range(l:from,a:to)letl:next = self.memo[i-1] + self.memo[i-2]
call add(self.memo,l:next)endfor
endfu
fu!s:fib.get(n)letl:last_index = len(self.memo)-1ifl:last_index <a:ncalls:fib.calc(a:n)endifreturn self.memo[a:n]
endfu
put=s:fib.get(10)put=s:fib.get(45)put=s:fib.get(46)put=s:fib.get(47)
watiko@local $ vim -NEsS fib.vim -c '2,$print | qa!'5511349031701836311903-1323752223
?!3
fib_big.vim
lets:save_cpo =&cpoletv:errors = []
setcpo&vimlets:BASE =10fu!s:add_positives(r0, r1)letl:i= len(a:r0)-1letl:j= len(a:r1)-1letl:carry =0letl:r2 =''whilel:i>=0ifl:j<0letl:sum =a:r0[l:i] +l:carry
elseletl:sum =a:r0[l:i] +a:r1[l:j] +l:carry
endififl:sum >=s:BASE
letl:carry =1letl:sum -=s:BASE
elseletl:carry =0endifletl:r2 =l:sum . l:r2
letl:i-=1letl:j-=1endwifl:carry !=1returnl:r2
elsereturnl:carry . l:r2
endif
endfu
fu!s:fib(n)letl:a='0'letl:b='1'letl:count=0whilel:count<a:nletl:count+=1letl:tmp =s:add_positives(l:b,l:a)letl:a=l:bletl:b=l:tmp
endwreturnl:a
endfu
call assert_equal('200',s:add_positives('191','9'))call assert_equal('55',s:fib(10))put=string(v:errors)put=s:fib(45)put=s:fib(46)put=s:fib(47)put=s:fib(1000)let&cpo=s:save_cpo
watiko@local $ vim -NEsS fib_big.vim -c '2,$print | qa!'[]11349031701836311903297121507343466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
注: 普段は QuickRun を使っています。技術的興味があっただけで、あまりおすすめしません(面倒なので)。