Upgrade to Pro — share decks privately, control downloads, hide ads and more …

terminal-api について

terminal-api について

tennashi

May 15, 2019
Tweet

More Decks by tennashi

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

  3. 今日のお話

    View Slide

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

    View Slide

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

    View Slide

  6. vim-in-vim 問題
    URL

    View Slide

  7. 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 を実行するときに
    便利そうなやつを作った で紹介しています

    View Slide

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

    View Slide

  9. drop
    URL

    View Slide

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

    View Slide

  11. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide