vim/gvimで日本語を使いやすくする
vim/gvimは日本語が苦手とされていて、それ自体は否定できるものではないのですが好みに合わせて設定すると扱いやすくなります。
(個人的には他のエディタより楽になりました)
vim/gvimで日本語を扱うために追加した設定や問題点と対処法は以下の通りです。
日本語入力の切替
挿入モードへ移行した時の日本語入力切替
vim/gvimで日本語入力・編集を行う場合は日本語入力と直接入力の切替が一番大きな問題で、IMEの自動制御が行える Windowsでも IMEのモード切替が非常に鬱陶しく感じる事があります。
これは挿入モードで日本語入力してからノーマルモードへ戻り、再び挿入モードへと移行した場合に、日本語入力が有効になって欲しい場合と、無効にして欲しい場合の二種類が有るのに vimの動作を選べないという事が原因かと思います。
つまり、ソースコードに日本語で一言だけコメントを書くような時には、
- 挿入モードに入ってIME ON
- コメントを書く
- <ESC>で挿入モードを抜ける
- 再び挿入モードへ
- この時 IMEはOFFのまま
となっていて欲しいのですが、日本語の文章をメインに入力したい場合は、逆に
- 挿入モードに入ってIME ON
- 日本語の文章を書く
- <ESC>で挿入モードを抜ける
- 再び挿入モードへ
- この時 IMEは自動的にONになる
というようにIMEは自動制御でオンになって欲しいわけです。
WindowsではIMEの制御が行えますが仕様的な問題で入力内容によっては余計なモード切替が頻繁に起こる事がありますし、Linuxに至っては IM制御の挙動はまちまちで、同じ OS上の Vim(非GUI)と GVimですら挙動が異なるため非常に混乱しやすくなっています。
更にLinuxの場合はIMによってはモード切替自体が出来ない事があって、ノーマルモードへ戻っても手動でIMをOFFにしないといけない環境もあります。
これらの問題はスクリプトを書いて「日本語入力固定モード」を導入する事で解決しました。
「日本語入力固定モード」を使用すると IME(IM)の自動制御を Vim(非GUI)と GVimだけでなく Windowsと Linuxのように OS自体が違う場合でも同じ挙動にして扱う事ができるので非常にわかりやすくなります。
「日本語入力固定モード」は Windows、Linux(iBus、SCIM、uim)と <C-^>の使える一部のMacなどで使用可能です。
IMEの状態でカーソルの色を変更する
gvimなら IMEのモードでカーソルカラーを変更すると便利です。
IMEの「確定取り消し」を使用する
WindowsのIME(ATOK、MS-IME、Google日本語入力)では候補確定した直後に限り、CTRL+BackSpace で未確定状態へ戻す「確定取り消し(確定アンドゥ)」が使えます。
連文節変換で長い文章を確定した瞬間に間違いに気づくのは良くあることだと思いますが、そのような場合非常に有効で「確定取り消し」を使用しない場合はノーマルモードへ戻ってカーソル移動して……と結構面倒なことになります。
「確定取り消し」はvimに限った話ではないのですが非常に便利なので書いておきます。
日本語編集の挿入モード
vimの挿入モードはその性質上あまり高機能ではありません。
しかし日本語の場合 vimの編集コマンドはさほど有効でないこともあり、ある程度は挿入モードでの編集が行えると便利です。
標準では<C-w>で前単語削除などができますが、独自に挿入モードでのコマンドを定義しても良いかもしれません。
個人的には挿入モードの行連結やカーソル以降の単語削除などはよく使います。
vimで日本語を扱う設定
表示行で移動する
日本語の場合は一行が長くなりやすくて画面上で折り返し表示されている事が多いのでカーソルの上下移動は表示行で移動した方が便利です。
ソースなどでもカーソル上下移動を表示行単位に変更しても特に問題になることはないようです。
ただしキーボードマクロでは物理行移動でないと困る場合が多いので、キーボードマクロには<C-p>,<C-n>を使うように気をつけた方がよいかと思います。
以下を.vimrcに追加すると表示行での移動になります。
"カーソルを表示行で移動する。物理行移動は<C-n>,<C-p>
nnoremap j gj
nnoremap k gk
nnoremap <Down> gj
nnoremap <Up> gk
カーソルを表示行の真ん中に移動する gm コマンド(やg0 g$)も日本語の場合は結構使えます。
連結と文字幅、長い行
その他に J コマンドの行連結の空白の扱いと、□や○などの一部の文字幅が半角と見なされて表示がずれるのを防ぐ設定を .vimrc に追加しました。
また、一行が長くなりがちな日本語では display=lastline は必須かと思います。
"日本語(マルチバイト文字)行の連結時には空白を入力しない。
set formatoptions+=mM
"□や○の文字があってもカーソル位置がずれないようにする。
set ambiwidth=double
"画面最後の行をできる限り表示する。
set display+=lastline
vim 7.4以降ではformatoptions
にjオプション(コメント行処理)を追加すると良いかもしれません。
set formatoptions+=mMj
全角スペースを強調表示する
全角スペースと半角スペースが混在すると問題になる事があるので、全角スペースを強調表示するように設定しました。
ファイルエンコーディングや文字コードをステータス行に表示する
ステータスラインにファイルエンコーディングやファイルフォーマット(改行コード)を表示しておくと、異なるファイルエンコーディングのファイルが混在している場合に簡単に確認できます。
set laststatus=2
set statusline=%<%f\ %m\ %r%h%w%{'['.(&fenc!=''?&fenc:&enc).']['.&ff.']'}%=\ (%v,%l)/%L%8P\
カーソル位置の文字コードも表示したい場合は以下を参照してください。
「ステータスラインに文字コードやファイルエンコーディングを表示」
ステータスラインのオプション B は内部エンコーディングに変換した文字コードを表示しますが、上記のリンクの場合はファイルエンコーディングに応じた文字コードが表示されます。
日本語のカーソル移動
カーソル移動
日本語は一文が長く、スペースが存在しないまま複数の文が一行に連結されているため、スペース区切りのW,B,Eはほとんど意味がありません。
日本語では英文のスペースのかわりに"、
"や"。
"のような句読点で区切られているので、そこへ移動できれば少しは楽になります。
このためW,B,Eのセパレータとして '。、
' などを指定して、長い日本語の同一行内カーソル移動を楽にする事を目的とするプラグインを書いて対処しました。
たとえばcWで現在位置から次の "。
"や "、
" まで変更したりすることが可能になります。
matchpairs
また"、
"や"。
"とは異なる区切りとして"「」
" や "()
" が使われますが、これらはmatchpairs
を設定することにより%
コマンドで対応する位置へ移動可能です。
set matchpairs+=「:」,(:)
小説のように「」を多用している場合は有用です。
もっと細かく設定したい場合は、標準添付されているmatchit.vimを利用しても便利かもしれません。
なお前述のプラグインにはmatchpairsで移動する範囲を削除/コピー/置換するテキストオブジェクトも含まれているので、ci%
で会話文の中を変更したりすることが出来ます。
タイプライタースクロール
エディタによっては「タイプライタースクロール」という、常にカーソルがディスプレイ中央に固定される機能があります。
「タイプライタースクロール」を使用すると目線を動かさずに文章が書けるため、日本語文書作成時のように現在行が重要な場合に集中しやすくなります。
Vimでもこの「タイプライタースクロール」を使用することが可能です。
set scrolloff=9999
scrolloff
は
scrolloff
は画面の上端または下端のカーソル表示マージンを設定するもので、値が画面表示行数の半分より大きければ、カーソルは画面中央に固定されます。
Vimの場合カーソル位置は中央固定ではなくscrolloff=3
のように、最下行から3行上でスクロールが行われるような設定も可能です。
「タイプライタースクロール」を終了したい場合はscrolloff=0
に設定します。
日本語の折り返しと文字数
折り返し
標準のままのvim/gvimでは一行あたりの文字数を指定してソフトラップ(改行を埋め込まずに折り返し)を行う事は出来ませんし、ウィンドウサイズに合わせてのソフトラップでは日本語の禁則処理は行われません。
通常は商業原稿や小説書きぐらいでしか問題にはならないと思いますが、自動で疑似ソフトラップと禁則処理を行うプラグインを書いて対処しました。
たとえばメールの下書きや、青空文庫の小説などの長文を vimで読むような場合は整形してやると読みやすさが結構違ってきます。
何度整形しても、元の状態に簡単に戻せるので未完成原稿にも安心して整形を掛ける事が出来ます。
文字数
現在編集中バッファの文字数はg<C-g>
で確認可能ですが、改行自体も一文字としてカウントされたり、Windowsの改行コード(CR+LF)は2文字としてカウントされるので改行を含まない純粋な文字数を知りたい場合は気をつける必要があります。
このため改行を含まない純粋な文字数を表示するg<C-g>
互換コマンドや、ステータスラインに表示可能なスクリプトを書いて対処しました。
文字コードの異なる日本語文書でも grepする
ソースファイルのように英数字しか使わないものは問題有りませんが、日本語はvimの内部エンコーディングとファイルの文字エンコーディングが異なるとgrep出来ません。
若干の制限はありますが外部grepを日本語対応にする事も出来ます。
幸いなことに vim/gvimの場合は内部grep(vimgrep)を使用すれば異なる文字エンコーディングのファイルが混在していても grep可能です。
vimgrepは速度面で問題がありますが、ソースファイルと違って日本語文書の場合は対象ファイル数が少ないと思いますので問題になりにくいかと思います。
他のエディタでは異なる文字コードのファイルが混在していると grepできなかったりする事も多いのでこの辺はアドバンテージになるかもしれません。