Vim Advent Calendar 2013の105日目(2014-03-15)の記事です。
日本語入力IMをオンにしてInsert modeを開始するコマンドをmapする
Vimプラグインimactivatemap.vimを作りました
(i,a,c,o等に対して、日本語入力オンで開始するgi,ga,gc,go等をmap)。
Insert modeに入る際には、日本語を編集したいことは意識しているので、
その意図を直接表現するコマンドを用意すると気持ち良く操作ができるかと思って作ってみました。
c,s,rコマンドで、書き換え前の文字列に応じてIMオン/オフを切り替えるVimプラグインを作ったのですが、
日本語入力オン/オフ制御が意図から外れる場合がたまにあってストレスになるので、
逆方向のアプローチとして、日本語で編集することを指定するコマンドを割り当てる方法のプラグインです。
vi的には、日本語入力IMオンにしてInsert modeを開始するコマンドを用意する方が自然な気がしたので。
さらに、Insert modeのままでのIMオン/オフ切り替えは使わずに、
オンに切り替えたい場合は一度Insert modeを抜ける形にするのがvi的かもしれません。
つまり、以下の2種類のコマンドとみなす形。
-
iで始まり、ASCII文字列を入力して、Escで終わるコマンド。 -
giで始まり、日本語文字列を入力して、Escで終わるコマンド。
この場合は、以下のようにInsert modeを抜けるとIMオフになるように設定しておいてください。
inoremap <silent> <unique> <Esc> <Esc>:set imsearch=0 iminsert=0<CR>
特徴
- 新たなモードの追加無しに、vi操作中に日本語編集を融合
(日本語入力固定モード
のように、IMEオン固定モードとIMEオフ固定モードを追加して切り替えるのではなく) -
がまでの文字列をIMオフで編集するcgtがや、
hまでの文字列をIMオンで編集するgcth等の組み合わせも可。 - 現在の日本語入力モードがオンかオフかを意識しなくて良い。
gaでInsert modeを始めれば常に日本語入力オンで入力できますし、
aで始めれば常に日本語入力オフで入力できます。 - Insert mode中に日本語入力オンオフ切り替え操作をしなくて良い。
かわりにEscで抜けてInsert modeに入り直す操作が多くなりますが。
欠点
iのかわりにgiを入力する必要があるので、操作が少し長くなります。
日本語入力メインで行う場合は、iのかわりにgiを打つのは面倒なので、
Insert modeを抜けてもオフにしない方がいいかもしれません。
(その場合は、日本語入力オフでInsert modeを開始するコマンドを、
qi等に割り当てておくのがいいかも。)
このあたりは、viを使い始めた時にiを打つのを面倒に感じたのと同様に、
慣れの問題かもしれないので、しばらく使ってみる予定です。
少し使ってみての感想
- Insert modeに入ってからIMを切り替えるよりも、
ga等のコマンドを使う方が楽な印象。
たとえ、Escで抜けてgaを押してIMをオンにし直さないといけない場合でも。
IM切り替えはコントロールキーを使うからかも。 -
g/で直接日本語入力を開始できるのは便利。
CTRL-^を押して切り替えるのは面倒だったので。 - 日本語編集をするつもりなのに
gcでなくcを押してしまう場合がよくある。
同様にaやiでも。この場合、一度Escで抜けてgcを押し直す形。
慣れると意識せずにできるようになるか? - 一番良く使うのは
ga。逆に、日本語入力をするつもりが無いのに押してしまって、
一度Escで抜けてaを押し直すことも。
その他便利なのはgs。gcは少し考えないとまだ使えない。 - Vim以外のアプリではIMオン/オフ操作が必要なので、操作の統一性が無くなるため、
意識のスイッチが必要。
(Vimを使う時点である程度スイッチしているので慣れればほぼ無意識にできるはず?)
mapするキー
デフォルトでは、日本語入力IMオンにして編集を開始する以下のキーをmapします。
-
gi,gI,ga,gA,go,gO,gs,gS,gc,gC,gr,gR -
gf,gF,gt,gT -
g/,g?
デフォルトでは、打ちやすさを考慮してgに割り当てていますが、
gi, gI, ga, go, gs, gr, gR, gf, gt, g?を上書きしてしまいます。
他のキーに割り当てるには、g:imactivatemap_prefixkeyを設定してください。
let g:imactivatemap_prefixkey = 'q'
候補となるprefixキー:
-
q: 少し打ちにくい。 -
m:ma等はよく使うので、指が意識せずに動いてしまっていまいち。 -
s:clで代替可能なので。ただ個人的にsはよく使うのでつぶしたくない。
IMのオン/オフの切り替え制御
IMのオン/オフの切り替え制御は、デフォルトでは
&iminsertや&imsearch(/,?向け)の値を2や0に設定することで行います。
(Windowsのgvimの場合など。)
その他のIM切り替え方法に関しては、以下を参考にしてください。
- 日本語入力固定モード
-
'imactivatekey'関係 - https://github.com/koron/imcsc-vim/
- Ubuntu上のVimでIME(ibus制御)
- CUIでもimaf/imsfを使いたい - Issue #444 - vim-jp/issues - GitHub
IM切り替え方法のカスタマイズをしたい場合は、
IM切り替えを行う関数を定義して、
その関数名をimactivatemap_imifuncやimactivatemap_imsfuncに設定してください
(以下の設定例も参考)。
関数の引数は'imactivatefunc'と同じです。
これらのカスタマイズした関数をIMオフ目的で呼ぶ<Plug>として、
<Plug>(imactivatemap-reset)をnnoremapしてあります。
Insert modeをEscで抜けるとIMオフになるように設定するには、
inoremap <silent> <unique> <Esc> <Esc>:set imsearch=0 iminsert=0<CR>
のかわりに
imap <silent> <unique> <Esc> <Esc><Plug>(imactivatemap-reset)
と設定してください。
設定例: tcvime(1.5.0)の場合
tcvimeはkeymapを使うので、
tcvime#Activate()では、&iminsertの値を1や0に設定しています。
" g/, g?, /, ?の検索でIMのオン/オフを切り替えるため、imsearchをセットする関数
function! ImActivateMapImsFunc(active)
if !a:active
set imsearch=0
return
endif
if &keymap != ''
set imsearch=1
return
endif
" keymap未設定時はロードが必要
call tcvime#Activate(1)
set imsearch=1
" tcvime#Activate(1)で&imi=1になるが、g/直後のa等ではオフにしておきたいので
call tcvime#Activate(0)
endfunction
let imactivatemap_imsfunc = 'ImActivateMapImsFunc'
let imactivatemap_imifunc = 'tcvime#Activate'
imap <silent> <unique> <Esc> <Esc><Plug>(imactivatemap-reset)
関連
-
contextimi.vim:
c,s,rコマンドで、書き換え前の文字列に応じてIMオン/オフを切り替えるVimプラグイン。
imactivatemap.vimとの共存は未対応。