Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

挿入モードを出る時にIMEをオフにする(SSH接続など端末エミュレータからVimを利用する場合)

$
0
0

端末エミュレータから Vim を利用する場合,Vim はサーバ側に,IME はクライアント側にあります.そのため,挿入モードを出る時に IME を(日本語入力を)自動的にオフにしようと思っても,MacVim や GVim のようにはいきません.一部の端末エミュレータでは,サーバからクライアントの IME をエスケープシーケンスによって制御することが可能です.ここでは,エスケープシーケンスを用いて挿入モードを出る時に IME を自動的にオフにする方法を紹介します.

使用した端末エミュレータ

RLogin (2.16.8)

※ 元ネタは Tera Term のマニュアルから拾ってきたので,おそらく Tera Term でも動くはず.

設定

Vim で .vimrc を開いて,以下のコマンドを記述します.注意事項として,^[[<r^[[<s^[ESCを表しています.入力する際には,^[ではなく,Ctrl+vESCと打ってください.以下のコマンドをコピペしても正しく動きません!

.vimrc
" 挿入モードに入る時,前回の挿入モードにおける IME の状態を復元する.sett_SI+=^[[<r" 挿入モードを出る時,現在の IME の状態を保存し,IME をオフにする.sett_EI+=^[[<s^[[<0t

" Vim 終了時,IME を無効にし,無効にした状態を保存する.sett_te+=^[[<0t^[[<s" ESC キーを押してから挿入モードを出るまでの時間を短くするsettimeoutlen=100

解説

エスケープシーケンス(ANSI escape code)とは,端末を制御するための文字の組み合わせです.端末エミュレータはエスケープシーケンスによる制御機能もエミュレートしているため,エスケープシーケンスを利用することでサーバ側の Vim からクライアント側の端末エミュレータを制御することができます.エスケープシーケンスによる端末制御の大まかな流れは以下の通りです.

  1. ユーザがキー操作を行う(例|挿入モードを出る)
  2. Vim がキー操作に対応するシーケンスを端末エミュレータに送信する
  3. 端末エミュレータがシーケンスを受信する
  4. 端末エミュレータが受信したシーケンスに基づいて処理を行う(例|IME をオフにする)

端末オプション

Vim は「ユーザのキー操作」と「操作時に端末へ送信されるシーケンス」の対応表を端末オプションという形で保持しています.現在設定されている端末オプションは :set termcapで確認できます.端末オプションに IME を制御するエスケープシーケンスを追記することで,Vim から IME を制御することが可能になります.今回の設定で用いるオプションは以下の3つです.

オプションオプションの意味
t_SI挿入モードに 入る
t_EI挿入モードを 出る
t_te端末オプションに基づくシーケンスの送信を終了する時(Vim 終了時)

Control Sequence Introducer (CSI)

エスケープシーケンスの多くは ESC[で始まります.これらのシーケンスは CSI と呼ばれ,CSI を用いることで端末の高度な制御を行うことが可能です.今回の設定に関係するエスケープシーケンスは以下の通りです.以下のエスケープシーケンスを上記の端末オプションに追記することで,IME の制御を行います.

シーケンスシーケンスの意味
ESC[<r保存された IME の状態を復元する
ESC[<s現在の IME の状態を保存する
ESC[<0tIME を オフにする
ESC[<1tIME を オンにする

タイムアウト

実は ESCを押してから挿入モードを出るまでの間に,1秒間(timeoutlen=1000)の待ち時間が設けられています.これは ESC単体とエスケープシーケンスを区別するための仕掛けです.ESCは単体で用いられる場合と,ESC[A(方向キー上)のようにエスケープシーケンスとして他の文字と組み合わせて用いられる場合の2パターンがあります.ESCを受信した直後は後に文字が続く可能性があり,どちらのパターンなのか区別することができません.そのため,Vim は timeoutlenオプションで指定した時間だけ待機し,その間に続く文字が入力されなければ「ESCは単体で用いられた」と判断します.

この判断の後にエスケープシーケンスが送信されるため,timeoutlenオプションの値が大きいと ESCを押してから IME がオフになるまでの間に無視できないレベルのタイムラグが発生します.これを防ぐために,timeoutlenオプションに小さな値を設定します.

参考資料

  1. IME を制御する|Tera Term ヘルプ
  2. Tera Term の対応制御シーケンス|Tera Term ヘルプ
  3. RLogin の対応制御シーケンス|RLogin
  4. ANSI escape code|Wikipedia
  5. 端末オプション|Vim documentation

Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>