: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はtmap
viモード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