Slide 1

Slide 1 text

terminal-api について Gollira.vim #4

Slide 2

Slide 2 text

自己紹介 職業プログラマ歴: 半年強 Vim歴: 6年くらい 普段は Go/TypeScript(Angular) を書いている その前はネットワークエンジニアをしていた GitHub: @tennashi Twitter: @tnnsh1

Slide 3

Slide 3 text

今日のお話

Slide 4

Slide 4 text

terminal mode Vim 8.0 から追加された Vim から terminal を使える mode VS Code とかでもターミナルが使えますが同じようなことが vim でも できると思っていただければ Neovim でも使える(実装されたのは neovim が先)が使い勝手が微妙に 異なるので注意が必要 参考: reply.vim

Slide 5

Slide 5 text

terminal mode の不便な点 terminal mode をメインの環境にしたいと思うと必ず(?)以下のような問 題にぶつかります terminal mode の中で vim を叩くと vim がネストされてしまう!!!

Slide 6

Slide 6 text

vim-in-vim 問題 URL

Slide 7

Slide 7 text

vim-in-vim 問題 これは vim の場合以下のように回避できる +clientserver で build された vim で vim --remote を使う 今日の本題である terminal-api を利用する また、neovim の場合は --remote が無いので以下を利用し回避できる mhinz/neovim-remote を使用して vim --remote を再現する Vim の clientserver 機能、neovim-remote を使った回避方法は Vim/Neovim の terminal mode の中で Vim/Neovim を実行するときに 便利そうなやつを作った で紹介しています

Slide 8

Slide 8 text

Tapi(terminal-api) について 特殊なエスケープシーケンスを使用して :terminal で動いているジョブ (プロセス)から Vim へ JSON を送信することができる機能(Vim のみ) たとえば ]51;["drop", "README.md"]<07> という形で ["drop", "README.md"] という JSON を送信できる 注) , <07> はそのままの文字列のことではなく文字コード 0x1b , 0x07 のこと 現在、命令は drop と call の 2つだけしかない

Slide 9

Slide 9 text

drop URL

Slide 10

Slide 10 text

drop :drop コマンドと同じように指定したファイルを開く命令 先の例では echo -e "\x1b]51;[\"drop\", \"hoge\"]\x07" で hoge というファイルを親の vim 側で開かせた 挙動としては、同名のファイルがすでに開かれている場合はそのウィン ドウを開き、そうでない場合は新しいウィンドウを開く

Slide 11

Slide 11 text

call ユーザ定義関数を呼び出すことができる命令 ["call", "Tapi_Impression", ["play", 14]] という JSON を送信すると、 Vim 側で Tapi_Impression() という関数を呼び出してくれる 当然 Tapi_Impression() も定義されている必要があるので例えば以下の ように定義しておく function! Tapi_Impression(bufnum, arglist) if len(a:arglist) == 2 echomsg "impression " . a:arglist[0] echomsg "count " . a:arglist[1] endif endfunction

Slide 12

Slide 12 text

call 呼び出される関数は terminal-api 用に書かれたものでは無い可能性もあ るため Tapi_ で始まるものしか呼べないようになっている また第一引数は :terminal のバッファ番号、第二引数には call で渡さ れた引数が入る(先の例では ["play", 14] )

Slide 13

Slide 13 text

terminal-api を使って vim-in-vim 問題 を回避する 単純に vim-in-vim 問題を回避するためには drop を用いれば回避できる しかし、ファイルの開き方にはそれぞれ好みがあると思われる :vsplit :split :edit :tabnew これらに対応した Tapi_ 関数を書く

Slide 14

Slide 14 text

termopen.vim (未リリース!!)

Slide 15

Slide 15 text

termopen.vim 単純に、引数で "開き方" と "ファイル名" を受け取り、指定された開き 方でファイルを開く function! Tapi_open(bufnr, args) if len(args) < 1 return endif call s:open(a:args[0], a:args[1:]) endfunction

Slide 16

Slide 16 text

termopen.vim function s:open(cmd, files) for f in a:files execute a:cmd .. ' ' .. f endfor endfunction

Slide 17

Slide 17 text

termopen.vim これを使えば自分の好きな開き方で terminal mode から親の vim でフ ァイルを開ける!!!

Slide 18

Slide 18 text

terminal-api を使った plugin の注意点 現実的には... echo -e "\x1b]51;... なんて毎回打ってられないので、それ用の外部コ マンドもセットで提供する必要がある

Slide 19

Slide 19 text

参考資料 :h terminal :terminal に関する小さい Tips Vim のレジスタに :terminal のシェル上からアクセスする EDITOR in :terminalを真面目に設定する