かんな/emacs の input method 化

まず使い方。話はそれからだ!

事情を説明すると前置きが長くなりすぎるので、まずは使い方から。

  1. このサイトのEmacs ページにあるように、 Canna for GNU Emacs 29 のパッチと 私の独自パッチを当 てる。
  2. isearch-ext.el, canna.el を消去する。
  3. loadup.el, subr.el に対する変更を、元に戻す (.orig ファイルを元のファイル名に復帰する) ※ emacs.c に対する変更も、もはや syms_of_canna の追加だけで十分ですが、そこはお好みで。
  4. Emacs をコンパイル、インストールする。
  5. canna-im.el.bz2(ver 2.4; 11722 bytes)の圧縮を解き、Emacs の load path 内のどこかに置く。
  6. .emacs などで、(load "canna")(require 'canna) となっていた所を、(load "canna-im")(require 'canna-im) と直す。(※ 「(canna)」の所はそのままにする)

以上でいいはずです。新たに Emacs を起動すれば、これまでと同様に日本語 入力ができるでしょう。問題があればお知らせください。

isearch 中の日本語入力は、C-o ではなく C-\ でで きるようになっています。

変更履歴

  1. [2020, 11/10] lexical binding を有効 にしてみた。

  2. [2020, 8/25] emacs 27 になって、 set-minibuffer-message の働きで、ミニバッファで入力中 に一覧を表示するとき、一覧が未確定部の前に割り込んでくるようになっ た。かんなの入力中は従来通りの動作になるように、一時的に set-message-functionnil にした。

  3. [2018, 7/4] isearch で input method を使うと(input method がオンの状態で isearch を呼び出した場 合も含む)、その後は minibuffer での入力中ではモード文字列が minibuffer の先頭に出なくなっていたのを修正。isearch の動作をちゃんと理解していま せんでした。

  4. [2018, 7/4] marker の扱いを多少修正。

  5. [2015, 6/3] かんな終了時にかんな側から出る warning を、これまで は完全に無視してしまっていた(coding miss で、拾うつもりの処理が書かれ ていながら実際には拾い損ねていた)のを修正。なお、 独自パッチcanna-finalize が返す値の形式を修正したの に合わせてあるので、そちらと合わせて更新しないと正しく動作しません。

  6. [2015, 5/19] ウインドウの右下で入力していて、未確定文字列がウイ ンドウをはみ出したときに表示位置が調整されなくなってしまっていたのを修 正しました。

  7. [2015, 5/16] 未確定文字列の表示は、バッファへ実際に文字列を挿入 するのではなく「見かけ上表示されるだけ」(overlay の before-string プロ パティを使用)にしました。なので、変換結果を確定するまではバッファの modified status は変更されません。また、未確定文字列の色等の装飾表示が、そのバッファの font lock の影響を受けずに済むようになりました。

    一方この結果、canna-with-fences を nil にして使ってい る場合、文字端末上でバッファの末尾で入力している場合に限り、カー ソル位置が本来未確定文字列の最後に来るはずの場面で、未確定文字列の 先頭に来てしまいます。恐らく emacs のバグによるものです。なる べく canna-with-fences は t のままで使ってください(どう しても気になる、という方がいらした場合は、お知らせ頂けたら emacs 開 発サイドに修正リクエストのバグレポートを書くかもしれません…)。

    ミニバッファへの候補一覧表示の仕方も text property を使うやり方 に合わせたので、見た目が従来と若干変わります。これまでは一覧表示の 文字反転装飾部にほんとのカーソルを置いていたので表示が濃かったので すが、変更後はカーソルが置かれなくなったのでグラフィック端末上では ちょっと色が薄くなったように見えます。

  8. [2015, 5/16] 日本語モードで C-h c などの入力待ちに日 本語を入力しようとする際にちょくちょくエラーが起きていたのを修正しました。

  9. [2015, 5/16] 変換結果確定を続けて何 回か行った後で通常の undo を行うと、直前の確定結果だけでなくそれ以 前の確定結果まで巻き込まれてしまっていたのを修正しました。

  10. [2015, 5/16] emacs 24.4 での overriding-terminal-local-map の仕様変更のため、フェンスモー ドで、マウスによってメニューバー・ツールバーの項目を選択した時に動作が おかしくなることがあったのを修正しました。

    なお、フェンスモード中にかんなの日本語入力以外の操作を行うことは 元々想定していません。マウスで別のフレームを選択したりするとやはり 動作がおかしくなることが十分考えられます。この辺りはあんまりきちん と例外処理を拾うようには作っていないので、そのつもりでお使いくださ い(やはり、「何とかしてくれ」というリクエストがあれば直そうとする かもしれません…)。

  11. [2015, 5/16] coding style をちょびっとだけ修正。 user-error を使うのがふさわしそうな場面では使い、また論理 的否定の意味で null を使っていた所は not に置 き換え、等。

  12. input method 関数の本来の動作により合わせて、確定文字列は関数の返り 値として返して、バッファ内への挿入は emacs の側に任せました。これに より、overwrite mode ではちゃんと上書きが行われるようになります (auto fill も、emacs の側に任せられるようになりました)。

    また、あらかじめ日本語モードにしておけば、C-h cC-h k に対して、漢字(やひらがななど)を入力することも可 能です。(文字が確定するまでの間は、minibuffer でカーソルが入力待ちしてるのに、未確定文字列が元のバッファ上に表示 されてしまってかなり珍妙な具合にはなりますが。また、表示され るメッセージには「translated from <return> …」みたいな余分な 部分がついてしまいますが、気にしないことにします)

    確定文字列の挿入は全部 emacs の側に任せた結果、 self-insert-after-hookinput-method-after-insert-chunk-hook もサポートしなくな りました(そういう特別扱いは不要になりました)。

  13. カラー関連の設定を canna.el 独自のものから、emacs 標準 のものにしました。

    emacs 23 から、multi terminal 機能が導入されて、 1つの emacs session が X window 上と tty 上の両方で同時に動作でき るようになりました。このため、これまでの canna(-im).el では、先に X window の frame を開いてから tty の frame も開くような 場合、tty 用に調整した色が使われません(その逆も真)。また、「カラー が使えるかどうか」を始めとした端末(画面)の機能を emacs 起動時 に判定することは不可能になり、特に「起動は emacs --deamon で行い、以下の利用は常に emacsclient を通 じて行う」という使い方をする場合、起動時には一律「 カラーが使えない文字端末上」と判定されてしまうため、そのまま ではかんなでカラーグラフィック frame 用の色 が使えなくなっていました。

    canna-im.el バージョン 2 では、そういった問題点に対 処しました。カラー利用をデフォルトとし、使っている端末に応じてその 場で適切なカラーが選ばれるようにしてあります。

    なお、この変更によって、以下のような影響が出ていますので、該当す る方は注意してください。

後者のカラー化に関する変更の結果、以前と動作が変わった点として、 「白黒の文字端末上でデフォルトの設定で使う場合、文節区切りのスペースが入 らないようになってしまったため、複数の文節を含む部分を変換している最中 は、着目文節がどこまで続いているのかわからなくなってしまっている」という 点があります。このような場合は、 canna-underlinet にして下線や反転で区別がつ くようになることを期待するか、関数 canna-set-bunsetsu-kugiricanna-set-fence-mode-format によって文節区切りをオンにする 設定を入れるようにしてください。

バージョン 2 では主要な機能部分を完全に書き換えたので、動作に不具合が 発生するかもしれません。なので、旧バージョ ンもしばらくは残しておきます。

以下、バージョン 1 時代に書いた文章ですが、だいたいそのまま当てはまる ので残しておきます。

[2013, 3/24] 今回の変更点は以下の通りです。

  1. C-SPC などで mark を打ったとき、日本語モードなら再変換 領域の設定も行っていました (canna-use-space-key-as-henkan-regionnil でないとき)が、C-u C-SPC などで pop-buffer 系のコマンドが実行されていた場合はその動作は適切ではない と思われるため、その場合は再変換領域を設定しないようにしました。
  2. emacs 23 の時に入れていた、「minibuffer なしの frame で入力してい て、候補一覧が他の minibuffer のみの frame に表示された状態で C-g を入力するとエラーになってしまう」という問題への対策 は削除しました。emacs 24 になっていよいよその場当たり的な対処ではエ ラーになるようになってしまった上に、そのような環境ではかんなとは無 関係にそもそも emacs がまともに使えない(minibuffer への普通の入力 待ちの時に、minibuffer のみのframe のタイトルバーをクリックしてから C-g をタイプすると、quit がかかった後にポイントが minibuffer のみの frame に取り残されてしまい、以下まともな操作が困 難になる)ので、ここでだけ対処を入れても無意味だからです。

[2013, 3/16] isearch で日本語を検索したい 場合、従来の isearch-ext.el を使ったやり方と違って、isearch 中に C-\ をタイプすることで普通に日本語入力が可能です (C-o ではダメ)。このこともあって、 日本語モードの切り替えキーは、 .cannaC-\ に変更しておくのがお勧めです。

※ [2012, 9/30] これま でのバージョンでは、set-mark-command で再変換用のリージョンをセットするの に after advice を使っていたのですが、C-\ による日本語モード の on/off の度に advice を enable/disable する(他の input method への影 響をなるべく小さくする目的で)というやり方をとっていたため、buffer A で 日本語モードを off にすると、日本語モードが on のままの buffer B でまで advice が無効化されてしまうという問題がありました(考えてみれば当たり前 だった…)。

あとまあ、C-\ の度に set-mark-command の advice が強制的に activate されてしまうので、何らかの理由で非活性のままで保持しておきたい、 という人がもしいた場合、その人にとっては困る動作になっていました。

なので、advice を使うのはやめて、おとなしく、広瀬さんが canna.el でな さっていた方法に倣うことにしました。canna-set-mark-command 関数で this-command を上書きし、global-map で set-mark-command を canna-set-mark-command に remap します(ですので、複 数の input method を並行して使い分ける人では、他の input method も set-mark-command を乗っ取るタイプの動作だった場合、競合が起きることが考 えられます。ご注意ください)。

お題目

現在、Emacs 29 にはかんなで入力するための パッチが 公開されており、canna.el による日本語入力が可能になって います。さて、これも含め、従来の canna.el による日本語入力 には、以下のような問題点があります。

  1. minor mode map(古いバージョンでは、local map) として実現されてい るので、他の minor mode map とキー定義が競合する可能性があります (emacs lisp では、複数の minor mode map の間の優先順位は決まってい ません)。また、keymap property がバッファ文字列や overlay に付与 されていた場合は、そちらが優先されてしまいます。 canna.el は、日本語入力途中のキー入力は全部かんなに渡 ることを前提とした作りになっているため、それが破れると動作に不具合 が出たり、最悪の場合はキーボードからの Emacs の操作がまったくでき なくなったりする可能性があります。
  2. global map で、通常の ASCII 文字のキーに対応するコマンドを、すべて self-insert-command から canna-self-insert-command に置き換えているのですが、 これが他の elisp に不具合をもたらすことがあり、それらに対して個別 に修正が必要となります。実際、 Canna for GNU Emacs 27 のパッチでは subr.el picture.el で、 canna-self-insert-command を特別扱いした処理を必要と しています。また、他の elisp library、例えば AUCTeX などにも 同様の特殊処理が盛り込まれているのが観察できます。 しかし、このような self-insert-command 系の置き換えは、 emacs lisp reference で
    In general ... the facilities for customizing `self-insert-command' are limited to special cases (designed for abbrevs and Auto Fill mode). (Do not try substituting your own definition of `self-insert-command' for the standard one. The editor command loop handles this function specially.
    と戒められています。また、他にも同様の置き換えを行う elisp が現れた場合、 いちいち個別の扱いを追加する手間がその都度増えていきます。

(2) の問題点に対しては、global map に手を加える代わりに minor mode map でやりくりする手もありそうですが、そうしたとしても (1) の問題点に制 約を受けることは変わりありません。Emacs 23 になって、いくつかの minor mode map 間での優先順位をきめ細かく分けるための emulation-mode-map-alistsminor-mode-overriding-map-alist といった変数が導入されまし たが、それらを利用したとしても、結局それらを利用する他の elisp との競合 は避けられず、keymap property に対して無力であることも変わらないのです。

この問題に対する答は最初からわかっていて、それは「かんなを input method 化する」ことです。input method というのは、非 ASCII 文字 を入力するための手段として Emacs 20(21 だったか?)から用意されたもので、 元々 minor mode map や keymap propery よりも高い優先順位で動作するように 設計されています。かんな/emacs のような枠組みは、本来 input method とし て動作するべきなのです。それで、上記のような問題は解消します。

そればかりか、input method は Emacs の標準機能なので、isearch も問題 なく動作するようになります。現状の canna.el は、そのままで は isearch 中に日本語入力ができないので、 Canna for GNU Emacs 29 では isearch-ext.el というパッケー ジを丸ごと付加して、それを Emacs に preload するということまでしていたの ですが、そういうことがまったく不要になるのです。

そこで、私は canna.el を改造して、input method として動 作するようにしてみました。それが、既に上でも登場し た canna-im.el です。試作品で すが、個人的にはもう何年も使ってきており、私の使用法では大きな問題は起こっ ていません。

input method 化に加えて、elisp coding convention に合わせた体裁の調整 も加えてあります。普通に使う分には、.emacs などへの調整はご く一部ですむはずですが、いくつか注意を述べます。

既知の問題点


コンピュータ関連のページ目次へ
トップページへ
井汲 景太 <ikumikeita@jcom.home.ne.jp.NOSPAM.>(迷惑メールお断り)
最終更新日: 2023年08月21日