Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

Vim script から標準出力に出す

$
0
0

この記事は 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をつけると試す分には辛い)。

Vim_exmode.png

編集用のコマンドは :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 を使っています。技術的興味があっただけで、あまりおすすめしません(面倒なので)。


  1. http://www.slideshare.net/rbtnn/vimconf2015-55367256 

  2. :verbose map Q, :verbose map gQ 

  3. :h Number手元の環境では :echo 0xffffffff(32bit) が -1だった。びっくりした勢いのまま書いた。 


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>