Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ゴリラ.vim #1

Vimと外部コマンド

ゴリラ.vim #1

自己紹介

daisuzu(@dice_zu)

  • 執筆

    • Software Design
      • 2012年7月号: エンジニアはなぜエディタにこだわるのか? VimとEmacs
      • 2013年10月号: Vimを使いこなしていますか? Vim至上主義
    • 仕事ですぐ役立つ Vim&Emacsエキスパート活用術
  • 登壇

    • VimConf
      • 2017: How ordinary Vim user contributed to Vim
      • 2018: Migrating plugins to standard features

Vimと外部コマンドは相性が良い

  • 専用のコマンドがある

    • :diff
    • :grep
    • :make
  • 汎用的なコマンドがある

    • :!
    • :read!
  • Vim scriptから使える

    • system()
    • job

:diff

ウィンドウを分割して、

:windo diffthis

を実行すると簡単に差分を表示できる。

'diffopt' 'dip'		文字列 (既定では "internal,filler")
>
※最近のVimは内部diffが使われる。

:grep

:grep [arguments]

:set grepprgで使用するコマンドを変更できる。

  • ag
  • pt
  • jvgrep
  • ripgrep

履歴は:chistoryで確認できる。

:make

:make [arguments]

:set makeprgで使用するコマンドを変更できる。

例えばgithub.com/daisuzu/gsc(自作のlinter)。

" 以下のコードのおかしいところをチェックする。
" ~/go/src/github.com/daisuzu/gsc/rangeptr/testdata/src/a/a.go
:set makeprg=gsc
:make %

:! :read!

" 任意のコマンドを実行する
:!gotype -ast %

" 新規バッファを作成して実行結果を挿入する
:new | r! gotype -ast %<Tab>

" バッファ全体を実行結果で書き換える
:%!gotype -ast

system()

system({expr} [, {input}])
" 結果は文字列
let result = system('tree -J ~/go/src/github.com/daisuzu/gsc')
let json = json_decode(result)
echo json

" 結果はリスト
let result = systemlist('tree -J ~/go/src/github.com/daisuzu/gsc')
new
call setline(1, result)

job

job_start({command} [, {options}])
  • commandは文字列でもリストでもOK
  • optionsは↓
{
    *_mode: channel-mode参照,
    'noblock': 1,
    'callback': {channel, msg -> msg},
    'drop': 'auto',
    'timeout': 2000,
    'stoponexit': 'term',
    'term': 'open',
    in_*: stdin関連,
    out_*: stdout関連,
    err_*: stderr関連,
    'env': {},
    'cwd': expand('%:p:h'),
}

callback

実行結果を受け取って様々な処理をすることができる。

" コールバック用の関数を渡す
call job_start(cmd, {'callback': Callback})

function! Callback(channel, msg)
  " msgを適当な変数に入れても良いし、
  " 加工してsetbufline()などを呼んでも良い。
  echo msg
endfunction

" ラムダ式を渡す
call job_start(cmd, {'callback': {channel, msg -> msg}})

※Vim script詳しい人向け

stdout

実行結果を手軽にバッファに挿入できる。 しかも非同期!

call job_start(cmd, {'out_io': 'buffer', 'out_name': '[stdout]'})

go-tree

https://github.com/daisuzu/go-tree

golang.tokyo #21のDevQuizで作ったツール。 ↓のように使うとtree.vimを非同期化できる。

vnew | set filetype=tree
call job_start(['go-tree', '-V', expand('$HOME/go/src')],
      \ {'out_io': 'buffer', 'out_buf': bufnr('%')})

:terminal

ファイルタイプ無し版は:terminalでも可。

:vertical terminal go-tree -V $HOME/go/src<Tab>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.