mozc-mode有効時にmultiple-cursorsが使えないので

ふと気がついた。
multiple-cursorsを使おうとしてもなぜか1つ目のカーソルにしか編集が有効にならない。

例えば以下のようにmultiple-cursorsで1から4行目の行頭にカーソルを作っておいて

f:id:nishikawasasaki:20190122220626p:plain

この状態で例えば 1 と入力すれば、全ての行頭に 1 が入力されるはず。
それなのになぜかたまに(必ずではなく)

f:id:nishikawasasaki:20190122220838p:plain

のようになることに気がついた。
なぜだろう?

いろいろ設定を有効・無効切り替えて試していると、
日本語入力のためにmozc-modeが有効になっていると発生することがわかった。
かといって日本語入力しないわけにもいかないし
いまさら数年ぶりにskkに戻るのもなぁと。

本質的には何が原因なのかまで突き止められていないけれど、
ひとまずはmultiple-cursorsを使いたいときにmozc-modeを無効にすればワークアラウンド

ただ、ATOKを普段は使っていて

  • 変換 → 日本語入力オン
  • 無変換 → 直接入力

としているので、
Emacsでも同じような挙動にしようと
どのバッファでもmozc-modeをオンにしておいて

  • 変換 → 日本語入力有効
  • 無変換 → 日本語入力無効

としていたのだけれど、
これだと常にmozc-modeがオンなのでmultiple-cursorsが使えない……。

ということはEmacsでのキーの挙動が

  • 変換 → mozc-mode有効にしてさらに日本語入力有効
  • 無変換 → mozc-mode無効

となれば良い。

少し悩んだのがmozc-mode有効時に直接mozc-modeを無効にする方法。
というのも、mozc-modeを有効にしていると
キーがmozc(WSLなのでGoogle日本語入力)に取られてしまうので
無変換キーを押すと日本語がオフになるだけでmozc-modeは有効のまま。
無変換キーを2回連打すればmozc-modeもオフになるけどなんだか微妙。
無変換キーを1回押すだけでmozc-modeがオフになってほしい。

けっきょく下のようにmozc-handle-event に無変換キー入力の場合の挙動をdefadviceして
無変換キー入力時はそのままmozc-modeをオフにするようにしてみた。

  ;; mozcオンでも無変換キーはEmacsにわたすようにキーイベントを横取りする
  (defadvice mozc-handle-event (around intercept-keys (event))
    (if (member event (list 'zenkaku-hankaku 'muhenkan))
        (progn
          (mozc-clean-up-session)
          ;; (toggle-input-method)
          (mozc-mode nil)
          (deactivate-input-method))
      (progn ;(message "%s" event) ;debug
        ad-do-it)))
  (ad-activate 'mozc-handle-event)

ついでに変換キーを押すとmozc-modeをオンにした上で
日本語入力モードもオンにするように以下の設定も追加。

  ;; 変換キーでon
  (global-set-key [henkan]
                  (lambda () (interactive)
                    (mozc-mode 1)
                    (when (null current-input-method) (toggle-input-method))))
  ;; 無変換キーでoff
  (global-set-key [muhenkan]
                  (lambda () (interactive)
                    (deactivate-input-method)))

あわせると以下のような感じになりました。

  ;; 変換キーでon
  (global-set-key [henkan]
                  (lambda () (interactive)
                    (mozc-mode 1)
                    (when (null current-input-method) (toggle-input-method))))
  ;; 無変換キーでoff
  (global-set-key [muhenkan]
                  (lambda () (interactive)
                    (deactivate-input-method)))

  ;; mozcオンでも無変換キーはEmacsにわたすようにキーイベントを横取りする
  (defadvice mozc-handle-event (around intercept-keys (event))
    (if (member event (list 'zenkaku-hankaku 'muhenkan))
        (progn
          (mozc-clean-up-session)
          ;; (toggle-input-method)
          (mozc-mode nil)
          (deactivate-input-method))
      (progn ;(message "%s" event) ;debug
        ad-do-it)))
  (ad-activate 'mozc-handle-event)

いまのところ変換・無変換キーで違和感無く日本語入力の切り替えができていて満足。

そもそもの日本語入力中にmultiple-cursorsを使いたいときは
multiple-cursorsの前に無変換キーを1回押す必要があるけれど

f:id:nishikawasasaki:20190122222305p:plain

まあ許容範囲かな……。

これを書いてて気がついたけど、
multiple-cursorsがはじまるのをフック(multiple-cursors-mode-hook)して
mozc-modeをオフにしても良い気もする。
こんな感じ。

  (add-hook 'multiple-cursors-mode-hook
            (lambda ()
              (mozc-mode nil)
              (deactivate-input-method)))

それにしても調べても見かけなかったから
mozc-modeとmultiple-cursorsの併用はニッチなのだろう……。