Vimpulse / viper-modeと日本語
Emacsで日本語を使うのもわりに面倒だったりするようで、さらに Vimpulse/viper-modeなどというとちょっと面倒かもしれません。
それでも Vimpulse/viper-modeで少しは日本語編集をがんばってみようという個人的な試みについて書いてみます。
日本語のカーソル移動
h l を行末を超えるように設定したり、 j k を表示行単位で移動するようなカスタマイズはこちらです→「カスタマイズ」
Vimpulse/viper-modeで日本語を扱う時の w b コマンドによるカーソル移動は理解しがたい不可思議な動作を行います。
Emacsの日本語に対するカーソル移動もどうかと思いますが Vimpulse/viper-modeはマルチバイト文字を考慮せずカーソル移動を独自処理しているのでかなりアレです。
とりあえず Vimpulse/viper-modeをロードした後に、移動コマンドを Emacsの移動コマンドに変更してやると Emacs互換のカーソル移動になります。
;; Vimpulseなら vimpulse-mapでもかまいません
(define-key viper-vi-basic-map "w" 'forward-word)
(define-key viper-vi-basic-map "b" 'backward-word)
日本語だけなら非常用としてそれなりにはなりますが viコマンドとの相性はというと色々とアレです。
.txt のように日本語を扱うバッファのみ、バッファローカルな viper-vi-local-user-map を使用してマップするという手もあります。
気合いの入った人は自分で好みのコマンドを作りましょう :-P
そうでない人には Vimpulse/viper-modeを vim互換の日本語に対応した移動を行うようにしてくれるプラグインがあります。
vimpulse-cjk
vimpulse-cjk.el 「Emacs (Viper/Vimpulse)で日本語の文節を扱う」
http://d.hatena.ne.jp/tarao/20100803/1280813432
Vimpulse/viper-modeで日本語を扱う場合は必携かと思います。
vimpulse-cjk.elを load-pathの通った場所にコピーして読込設定を追加します。
(require 'vimpulse-cjk)
(注意)
ただし toggle-viper-modeを繰り返して Emacsモードと切り替えて使う場合は、toggle-viper-modeで初期化されるため vimpulse-cjkが無効になることがあります。
以下のように defadviceしてやると viper-mode読込の度に再ロードするようです。
(defadvice viper-mode (after my-viper-mode-cjk activate)
(load "vimpulse-cjk" t))
単語単位の検索とビジュアルモードの検索
Vimpulseの * コマンドは symbol を検索するので、日本語の場合は空白がないと一行丸ごとの検索になってしまい使い物になりません。
(thing-at-point 'word)でも日本語の単語は認識しないので同じ事になるようです。
そこで日本語でもカーソル位置の単語単位で取得して検索可能なコマンドを作成してみました。
前述の vimpulse-cjk.el を使用している場合は文字種ごとに、そうでない場合でも Emacsの文節扱いで単語を拾うので、少なくとも妙な区切りではなくなります。
Vimpulse/viper-modeの両方で動作します。
またビジュアルモードで選択中に * で「選択中の文字列」を検索文字列として登録するコマンドも作成しました。
Vimpulse
;; * 検索コマンド(symbol)
(vimpulse-map "*" 'my-viper-search-for-symbol-at-point)
;; カーソル位置の単語を検索文字列として取得
(vimpulse-map "g*" 'my-viper-search-star)
;; ビジュアルモードで選択中の文字列を検索文字列として設定
(vimpulse-vmap "*" 'my-vimpulse-visual-search-star)
viper-mode
viper-modeにはビジュアルモードがないので * コマンドだけです。
;; * 検索コマンド(symbol)
(define-key viper-vi-global-user-map "*" 'my-viper-search-for-symbol-at-point)
;; カーソル位置の単語を検索文字列として取得
(define-key viper-vi-global-user-map "g*" 'my-viper-search-star)
検索スクリプトは別ページにあります。
「Vimpulse/viper-mode用スクリプト」 (Vimpulse/viper-mode)
個人的な好みから、コマンド実行しても検索文字列を取得するだけで検索はしないようにしています。
コマンド実行後に n か Nで方向を決めて検索します。
「検索レジスタに文字列設定」 (vimの場合)
気に入らない場合はハイライト処理(my-viper-flash-pattern)を行っている部分を、コメントアウトしてある次行の検索コマンド(viper-search)と置き換えてください。
my-viper-search-for-symbol-at-pointは Vimpulseの * にデフォルトで設定されている vimpulse-search-forward-for-symbol-at-point と同等の関数です(たぶん)
基本的に viper-modeしか使えない時のために作成したコマンドなので、 Vimpulseを使用するなら vimpulse-search-forward-for-symbol-at-point (デフォルトのまま)の方がよいかしれません。
(vimpulse-map "*" 'vimpulse-search-forward-for-symbol-at-point)
インクリメンタルサーチ
Vimpulse/viper-modeの検索 / コマンドは Emacsのインクリメンタルサーチ(isearch)を呼び出します。
しかし Emacsのインクリメンタルサーチは日本語に対応していません。
したがってエディットモードに切り替えてから日本語入力するか、あれば Migemo等を使うことになります。
以下のようにすると / コマンドの後 <C-k>でエディットモードに切替、そして IMをオンにすることで日本語検索可能になります。
この場合インクリメンタルサーチではなく通常の検索になります。
(define-key isearch-mode-map "\C-k" 'isearch-edit-string)
(setq viper-suppress-input-method-change-message t)
ここで IMの切替メッセージを抑制しているのは <C-k>の後の切替でうっとうしいからです。
当然 IMの状態は表示されなくなるので、Emacsに IMの状態でカーソルの色を変更するなどの設定をしておいた方がよいでしょう。
この切替キーは isearch-modeのキーマップなので Emacsの環境を汚すことになります。
わりと定番的な設定のようですが使用するキーは環境に合わせて設定してください。
vi協調 / 日本語入力固定モード
IM/IMEの制御が出来るように設定された Emacsenなら大抵 Vimpulse/viper-modeでの vi協調モードが有効です。
ただ個人的には日本語入力補助の方法として、あまり良い仕様だとは考えていません。
また Windowsでは NTEmacsのように viper-modeには対応していても Vimpulseには対応していない場合もあります。
そのような場合は挿入モードで日本語入力していると Vimpulseのビジュアルモードでは IMEがオンになったりします。
対処として NTEmacsでも vi協調モードを有効にするためと、個人的に好みでない Vimpulse/viper-modeの vi協調モードの動作改変のため「日本語入力固定モード」を作成して使用しています。
「日本語入力固定モード」について(リンク先はvim版についての説明です)
http://sites.google.com/site/fudist/Home/vim-nihongo-ban/vim-japanese/ime-control
日本語入力固定モード
jpfixmode.el (vi協調モード/日本語入力固定モード)
http://sites.google.com/site/fudist/files/jpfixmode.el
Vimpulse/viper-modeどちらでも有効です。
.emacsの設定例
NTEmacs (Windows IMEpatch)
;; NTEmacs (setq default-input-method "W32-IME")
;; (setq viper-ime-control "DISABLE")
(setq viper-ime-control-key "\C-j")
ibus.elでは Vimpulseでも vi協調モードが動作するので「日本語入力固定モード」を使用したい時だけ設定します。
;; iBus.el
(setq viper-ime-control "iBus.el")
(setq viper-ime-control-key "\C-j")
ibus.el
www11.atwiki.jp/s-irie/pages/21.html
詳細は jpfixmode.elを参照してください。
(Windowsの動作確認は gnupackの IMEpatch適用済み NTEmacsで行いました)
http://sourceforge.jp/projects/gnupack/releases/?package_id=10839
最後に
お約束の免責事項
Emacsや lispを理解していないので、このサイトにある設定や私が作成したスクリプトの動作は保証しません。
詳しいことは Emacsを使用している人に聞いたほうが良いかもしれません :-P