⌨️

Ghostty上でmacSKKを使えるようにする

2024/12/27に公開

2024-12-27にGhostty v1.0がリリースされました🎉 。Zig製なんですね。
v1.0時点では対象プラットフォームはmacOSとLinuxですが、いずれWindows版もリリース予定だそうです[1]

私はmacSKKというmacOS向け日本語入力システムを開発しています。さっそくGhosttyでのmacSKKの動作を確認してみたところ、次の2つの問題がありそうでした。

  • Ctrl-Jでひらがなモードに変更してほしいのに改行されてしまう
  • qキーによるひらがなカタカナモードの切り替え、lキーによるASCII入力モードへの変更と一緒にqやlがそのまま入力されてしまう

これまでKittyなどにあったような「変換確定前の文字列が表示されない」といった問題はないようなのでmacOSの標準の日本語IMEやATOKなどでは問題がないかもしれません。困るのはmacSKKやAquaSKKのようなちょっと変わったキーバインドを持つIMEに限られそうです。

2024-11-09時点でDiscussionにすでにこの2つの問題は報告されていたのですが、まだ修正はされていないようです。
https://github.com/ghostty-org/ghostty/discussions/2628

この記事ではGhostty上でmacSKKとAquaSKKを使うためのワークアラウンドを紹介します。

問題その1: Ctrl-Jで改行されてしまう

macSKKやAquaSKKではCtrl-Jをひらがなモードへの変更として標準でバインドしていますが、Ghosttyでは改行もされてしまいます。

これはGhosttyのキーバインド設定で潰すことができます。
Trigger=Action のようなフォーマットで記述するのですが、Triggerに ctrl+j、Actionに ignore (何もしない) を設定すればひらがなモードへの変換だけが発生するようになりました。

keybind = ctrl+j=ignore

https://ghostty.org/docs/config/keybind

問題その2: qやlが入力されてしまう

macSKKやAquaSKKではモードの切り替えにq (ひらがなカタカナモードの切り替え) や l (ASCIIモード) を使用します。このときにモード切り替えと一緒にqやlが入力されてしまうようです。

Ctrl-Jと違い英字入力モードではqやlはそのまま入力したいわけですが現在のGhosttyのキーバインド設定では今のIMEのモードによってignoreするかどうかは選べないようです。ここはKarabiner-Elementsを使って今のIMEモードによってqやlをモード変換に割り当てする設定をしてしまいましょう。

例えばmacSKKなら次のような設定をComplex Modificationsに書くことで「ひらがな・カタカナ・半角カナモード時はqキーをカタカナひらがなモードのトグル変換、lキーをASCIIモードへの変換として扱う」ことができるようになります。

(2024-12-27 23:00追記) qキーでひらがなモードとカタカナモードをトグルできてなかったので修正しました🙇

{
    "description": "macSKK for Ghostty",
    "manipulators": [
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^net\\.mtgto\\.inputmethod\\.macSKK\\.(hiragana|katakana|hankaku)$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "l" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "net.mtgto.inputmethod.macSKK.ascii",
                        "input_source_id": "net.mtgto.inputmethod.macSKK.ascii",
                        "language": "en"
                    }
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^net\\.mtgto\\.inputmethod\\.macSKK\\.(katakana|hankaku)$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "q" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "net.mtgto.inputmethod.macSKK.hiragana",
                        "input_source_id": "net.mtgto.inputmethod.macSKK.hiragana",
                        "language": "ja"
                    }
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^net\\.mtgto\\.inputmethod\\.macSKK\\.hiragana$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "q" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "net.mtgto.inputmethod.macSKK.katakana",
                        "input_source_id": "net.mtgto.inputmethod.macSKK.katakana",
                        "language": "ja"
                    }
                }
            ],
            "type": "basic"
        }
    ]
}

同じようにAquaSKKでもKarabiner-ElementsのComplex Modificationsで回避できます。

{
    "description": "AquaSKK for Ghostty",
    "manipulators": [
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^jp\\.sourceforge\\.inputmethod\\.aquaskk\\.(Katakana|HalfWidthKana)$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "l" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "com.apple.inputmethod.Roman",
                        "input_source_id": "jp.sourceforge.inputmethod.aquaskk.Ascii",
                        "language": "en"
                    }
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^jp\\.sourceforge\\.inputmethod\\.aquaskk\\.(Katakana|HalfWidthKana)$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "q" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "com.apple.inputmethod.Japanese.Hiragana",
                        "input_source_id": "jp.sourceforge.inputmethod.aquaskk.Hiragana",
                        "language": "ja"
                    }
                }
            ],
            "type": "basic"
        },
        {
            "conditions": [
                {
                    "bundle_identifiers": [
                        "^com\\.mitchellh\\.ghostty$"
                    ],
                    "type": "frontmost_application_if"
                },
                {
                    "input_sources": [{ "input_source_id": "^jp\\.sourceforge\\.inputmethod\\.aquaskk\\.Hiragana$" }],
                    "type": "input_source_if"
                }
            ],
            "from": { "key_code": "q" },
            "to": [
                {
                    "select_input_source": {
                        "input_mode_id": "com.apple.inputmethod.Japanese.Katakana",
                        "input_source_id": "jp.sourceforge.inputmethod.aquaskk.Katakana",
                        "language": "ja"
                    }
                }
            ],
            "type": "basic"
        }
    ]
}

注意ですが、Karabiner-Elementsで現在のモードを使って判定しているためシステム設定の「キーボード」→「入力ソース」でmacSKKなら「ABC」と「カタカナ」、AquaSKKなら「ASCII」と「カタカナ」を追加しておいてください。

入力ソースからカタカナ入力とASCII入力を追加しておく

脚注
  1. Windows support is planned after the 1.0 release. https://mitchellh.com/writing/ghostty-is-coming ↩︎

Discussion