一般:ターミナルモードでvimマッピングを使用する

一般:ターミナルモードでvimマッピングを使用する

:terminal私はvimを使用しており、bashとviモードを設定しました。これを行うには、.inputrc次の構成があります。https://vim.fandom.com/wiki/Use_vi_shortcuts_in_terminal。私のキーバインディングが端末のバインディングと一致しないことがわかりました。例えば。私はスイッチバッファを使用しています<TAB>。このキーバインディングは、bashが:terminal挿入モードか通常モードかを区別できないため、続行<C-w>wするには入力する必要があります。内で次のマッピングを使用する場合.vimrc:

tmap <TAB> <C-w>w

:terminalその後、bashが挿入モードになっている場合、タブは使用できなくなります。 Vimはtmapviモードinsertとモードの両方にnormalマッピングを使用します。

<TAB>bash inが通常モードの場合にのみバッファを切り替え、bash inが挿入モードのときにオートコンプリートを実行できますか?:terminal<TAB>:terminal

答え1

Vim は、端末の bash シェルが vi-insert モードで実行されているか、vi-normal モードで実行されているかを実際には知りません。私は実際にviまたはemacsモードを使用しているかどうかはわかりません。あるいは、ある時点でbashでコマンドを実行するときにbashが挿入モードか通常モードかを議論することさえ意味がありません。技術的には両方のモードにないからです。

したがって、この統合を達成するためにbashがVimにどのモードであるかを知らせるようにしてください。または同様に、bashはキーバインディングを解釈します特殊キーが実行されると、bashでVimコマンドを呼び出す

個人的には、後者がbashでキーバインディングを実行する最も簡単な方法だと思います。なぜなら、前回はbashでモード変更をリンクする実際に信頼できる方法がないことがわかったからです。何かが放出されようとすると、安定して検出することもできません。新しいコマンドが実行されます。 。 (この意味では、zshはbashよりもはるかに良く見え、フックが多く、一般的に使いやすいです。)

ここで欠けているもう1つの部分は、Vim端末内で実行されているシェルからVimコマンドを呼び出すことです。あなたはそれを使用することができますTerminal APIこれにより、bashのエスケープシーケンスを使用してVimから関数を呼び出すことができます。

Bashバインディングについては、bindコマンドを参照してください。これを渡して、-m特定のモード(vi-normalなど)のバインディングを生成し、-x特定のキーの組み合わせがEnterを押したときにそれを使用していくつかのコード(または機能)を実行できると思います。

たとえば、readline の「標準」 vi モードと一致するモードで<Tab>(Ctrl+I と同じ) を押すと、関数が呼び出されます。wincmd_next()vi

bind -m vi -x '"\C-i": wincmd_next'

Vim Terminal APIの場合、Tapi_wincmdシェルから呼び出すことができる関数をエクスポートできます。これにより、bashで次のものを使用できます。

echo -ne '\e]51;["call","Tapi_wincmd",["w"]]\a'

wincmd_nextしたがって、関数に変換するだけです。

wincmd_next () {
    echo -ne '\e]51;["call","Tapi_wincmd",["w"]]\a'
}

その後、対応するVim関数を作成できます。

function! Tapi_wincmd(bufnum, arglist)
    execute 'wincmd' a:arglist[0]
endfunction

このようにして上記のbashコマンドを実行すると、Vimは次のウィンドウに循環します。

Terminal APIはJSONでエンコードされたパラメータを使用します。デフォルトでは、Tapi_プレフィックス名の付いた関数のみがターミナルAPIから呼び出すことができます。これにより、Vimが端末アプリケーションに公開する特定の機能とパラメータの量と種類を決定できます。

Tabキーを押したときにVimウィンドウを切り替えることに関連する特定のシナリオを設定するために必要なものをすべてまとめるのに十分です。ただシェルがvi-normalモードにあるとき。


このアプローチの代替案は、:tnoremap通常モードのvi-bashかvi-insertモードであれ、他のキー入力に関係なく、端末で実行されているアプリケーションにキー入力が送信されるたびに接続することです。

質問で述べたように、次のように設定できます。

tnoremap <Tab> <C-w>w

しかし、それはあなたに使用する方法を提供しません実際端末のタブは、vi-insert(またはemacs)モードで実行するときに便利です。

たとえば、次のいずれかのように、実際のタブをターミナルアプリケーションに送信するために別のキー押しをマップすることでこの問題を解決できます。

tnoremap <S-Tab> <Tab>      " Shift-Tab
tnoremap <C-v><Tab> <Tab>   " Ctrl-V, Tab
tnoremap <C-P> <Tab>        " Ctrl-P

関連情報