Emacs NS build + Google IME でストレスなくIMEを切り替える


==本記事は暫定版です==

Emacs NS build と Google IME を併用すると,IMEが正しく切り替わらないことがある.以下はこの問題に対処するための一つの手法である.

Google IMEによる切替系統を,Emacs.app だけ分離する
- Emacs.app は内部のAPIを直接呼び出し Google IME を切り替える
- 他のアプリは通常通りに使う

以下は,Cmd-SpaceもしくはShift-SpaceをIME切替のキーとして使う事例である.

想定する環境

  • macOS (Catalina)
  • Emacs 27.0.91 (with ns-inline-patch)

必要なアプリケーション

macOSの IME切替を Ctrl-` に割り当てる

macOSの環境設定で変える.

Ctrl-` に Cmd-Space と Shift-Spaceを割り当てる

Karabiner-Elements で設定する.

~/.config/karabiner/assets/complex_modifications/toggle-ime-except-emacs.json として配置後,Karabiner-Elements.app を起動して確認.

これにより,Ctrl-`,Cmd-Space, Shift-Space の3つの方法で IME を切り替えられるようになる.ただし,Emacs.appの使用中は,Emacs.app内部の機能でIMEを切り替えるために,Cmd-Space と Shift-Space の押下を OSに渡さない.

toggle-ime-except-emacs.json
{
    "title": "Toggle IME (except Emacs.app)",
    "rules": [
        {
            "description": "Toggle IME by Shift-Space (left side)",
            "manipulators": [
                {
                    "type": "basic",
                    "from": {
                        "key_code": "spacebar",
                        "modifiers": {
                            "mandatory": [
                                "left_shift"
                            ]
                        }
                    },
                    "to": [
                        {
                            "key_code": "grave_accent_and_tilde",
                            "modifiers": [
                                "left_control"
                            ]
                        }
                    ],
                    "conditions": [
                        {
                            "type": "frontmost_application_unless",
                            "bundle_identifiers": [
                                "Emacs"
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "Toggle IME by Shift-Space (right side)",
            "manipulators": [
                {
                    "type": "basic",
                    "from": {
                        "key_code": "spacebar",
                        "modifiers": {
                            "mandatory": [
                                "right_shift"
                            ]
                        }
                    },
                    "to": [
                        {
                            "key_code": "grave_accent_and_tilde",
                            "modifiers": [
                                "left_control"
                            ]
                        }
                    ],
                    "conditions": [
                        {
                            "type": "frontmost_application_unless",
                            "bundle_identifiers": [
                                "Emacs"
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "Toggle IME by Cmd-Space (left side)",
            "manipulators": [
                {
                    "type": "basic",
                    "from": {
                        "key_code": "spacebar",
                        "modifiers": {
                            "mandatory": [
                                "left_command"
                            ]
                        }
                    },
                    "to": [
                        {
                            "key_code": "grave_accent_and_tilde",
                            "modifiers": [
                                "left_control"
                            ]
                        }
                    ],
                    "conditions": [
                        {
                            "type": "frontmost_application_unless",
                            "bundle_identifiers": [
                                "Emacs"
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "description": "Toggle IME by Cmd-Space (right side)",
            "manipulators": [
                {
                    "type": "basic",
                    "from": {
                        "key_code": "spacebar",
                        "modifiers": {
                            "mandatory": [
                                "right_command"
                            ]
                        }
                    },
                    "to": [
                        {
                            "key_code": "grave_accent_and_tilde",
                            "modifiers": [
                                "left_control"
                            ]
                        }
                    ],
                    "conditions": [
                        {
                            "type": "frontmost_application_unless",
                            "bundle_identifiers": [
                                "Emacs"
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

ns-inline-patch で Google IME を有効化

init.el
;; Google IME を指定(locale=en や自動検出がコケる場合には必須)
(custom-set-variables
     '(mac-default-input-source "com.google.inputmethod.Japanese.base"))

;; インラインパッチの有効化
(mac-input-method-mode 1)

Emacs.app で Google IME 切替を Cmd-Space と Shift-Space に割り当てる

init.el
(global-set-key (kbd "M-SPC") 'mac-ime-toggle)
(global-set-key (kbd "S-SPC") 'mac-ime-toggle)
(define-key isearch-mode-map (kbd "M-SPC") 'mac-ime-toggle)
(define-key isearch-mode-map (kbd "S-SPC") 'mac-ime-toggle)

Google IME の設定で Shift-Space を透過させる

Shift-Space が Emacs.app に透過しないケースがある.

Googke IME Keymap Style > Google IME input keymap editor から,「Shift Space」が Keyになっているコマンドを削除(Porcomposition, Composition, Conversion)すれば希望の操作(Shift-Spaceがダイレクトに Emacsに通る)

なおこの設定はエクスポートしてテキストで保存できる.新しい環境では,それをインポートすれば良い.

補助関数

  • mac-ime-toggle (IMEのON/OFF切替関数, interactive)
  • mac-ime-active-p(IMEのON判定関数)
  • mac-ime-activate(IMEのON関数, interactive)
  • mac-ime-deactivate(IMEのOFF関数, interactive)
  • mac-ime-input-source-list(使えるIMEのコードをメッセージバッファに書き出す, interactive)

Hooks

カーソルの色を変えるなどのカスタム関数を hook にぶら下げると便利です.

  • input-method-activate-hook(mac-ime-activate内で呼ばれる)
  • input-method-deactivate-hook(mac-ime-deactivate内で呼ばれる)