自作IMEパッチ
Table of Contents
要件
- (Must)モードラインにIME状態表示をする
- (Better)IME有効時にコマンド入力の挙動(できないようにする or 自動無効化)
準備
ベース
Gitリポジトリからクローンしたものを使う。
- git://git.sv.gnu.org/emacs.git
- タグ emacs-26.1
これに、rzl24ozi氏の提供する imeパッチをあてて、まずはビルド
autogeh.sh
mingw32.exe にて、
$ ./autogen.sh
gitにパスが通っていないといけないらしく、.bashrcに下記の設定をした。
export PATH=$PATH:"/c/Program Files/Git/Cmd"
$ ./autogen.sh Checking whether you have the necessary tools... (Read INSTALL.REPO for more details on building Emacs) Checking for autoconf (need at least version 2.65) ... ok Your system has the required tools. Running 'autoreconf -fi -I m4' ... Configuring local git repository... '.git/config' -> '.git/config.~4~' git config transfer.fsckObjects 'true' git config diff.elisp.xfuncname '^\(def[^[:space:]]+[[:space:]]+([^()[:space:]]+)' git config diff.m4.xfuncname '^((m4_)?define|A._DEFUN(_ONCE)?)\([^),]*' git config diff.make.xfuncname '^([$.[:alnum:]_].*:|[[:alnum:]_]+[[:space:]]*([*:+]?[:?]?|!?)=|define .*)' git config diff.shell.xfuncname '^([[:space:]]*[[:alpha:]_][[:alnum:]_]*[[:space:]]*\(\)|[[:alpha:]_][[:alnum:]_]*=)' git config diff.texinfo.xfuncname '^@node[[:space:]]+([^,[:space:]][^,]+)' Installing git hooks... 'build-aux/git-hooks/commit-msg' -> '.git/hooks/commit-msg' 'build-aux/git-hooks/pre-commit' -> '.git/hooks/pre-commit' '.git/hooks/applypatch-msg.sample' -> '.git/hooks/applypatch-msg' '.git/hooks/pre-applypatch.sample' -> '.git/hooks/pre-applypatch' You can now run './configure'.
configure
PKG_CONFIG_PATH=/mingw32/lib/pkgconfig ./configure CFLAGS="-s -g3 -O2 -gdwarf-2" --prefix=/c/usr/emacs --without-imagemagick --without-dbus
make
$ make bootstrap
方針
- まずは lisp/international/w32-ime.el だけ使えるものを目指す
参考にしたIMEパッチの変更点
- configure.ac .ac 変更 54 0
- lisp/international/w32-ime.el .el 追加 201 0
- lisp/language/japan-util.el .el 変更 4 2
- lisp/loadup.el .el 変更 1 0
- lisp/startup.el .el 変更 2 0
- src/frame.c .c 変更 6 0
- src/keyboard.c .c 変更 32 0
- src/w32fns.c .c 変更 1202 0
- src/w32font.c .c 変更 6 1
- src/w32font.h .h 変更 3 0
- src/w32term.c .c 変更 81 0
- src/w32term.h .h 変更 97 0
- src/window.c .c 変更 33 0
w32-ime.el 分析
defun
53:(defun wrap-function-to-control-ime 85:(defun w32-ime-toroku-region (begin end) 99:(defun w32-ime-sync-state (window) 115:(defun w32-ime-set-selected-window-buffer-hook (oldbuf newwin newbuf) 118:(defun w32-ime-select-window-hook (old new) 121:(defun w32-ime-mode-line-update () 133:(defun w32-ime-init-mode-line-display () 149:(defun w32-ime-initialize () 162:(defun w32-ime-uninitialize () 175:(defun w32-ime-exit-from-minibuffer () 180:(defun w32-ime-state-switch (&optional arg)
defvar
11:(defvar w32-last-selection nil 16:(defvar w32-ime-on-hook nil 19:(defvar w32-ime-off-hook nil 22:(defvar w32-ime-buffer-switch-p t 24:(defvar w32-ime-show-mode-line t 26:(defvar w32-ime-mode-line-state-indicator "[O]" 30:(defvar w32-ime-mode-line-state-indicator-list '("-" "[|]" "[O]") 32:(defvar w32-ime-mode-line-format-original nil 82:(defvar w32-ime-toroku-region-yomigana nil
ソース上から上記が使用されているところを探す
とりあえず "w32-ime" でgrep
$ find . -iname *.[ch] | xargs grep "w32-ime" ./src/globals.h: "w32-ime-buffer-switch-p", ./src/w32fns.c:DEFUN ("w32-ime-register-word-dialog", ./src/w32fns.c:DEFUN ("w32-ime-perform-reconversion", ./src/w32fns.c: DEFSYM (Qw32_ime_buffer_switch_p, "w32-ime-buffer-switch-p"); ./src/w32fns.c: DEFVAR_LISP ("w32-ime-composition-window",
これが w32-ime-el にあるかというと
- w32-ime-buffer-switch-p ある
- w32-ime-register-word-dialog 無い
- w32-ime-perform-reconversion
- w32-ime-composition-window 無い
とりあえず w32-ime-buffer-switch-p だけ押さえればよさそう
- ./src/globals.h: "w32-ime-buffer-switch-p",
- ./src/w32fns.c: DEFSYM (Qw32_ime_buffer_switch_p, "w32-ime-buffer-switch-p");
globals.h
このヘッダはmake時に自動生成されるもののようだ。
static char const *const defsym_name[] = { "nil", /* 略 */ "w32-ime-buffer-switch-p", /* 略 */ };
w32fns.c
とすると押さえる必要があるのは w32fns.c だけのはず。
$ find . -iname *.[ch] | xargs grep "wrap-function"
まずは
下記ファイルを追加
- lisp/international/w32-ime.el
下記ファイルのうち必要と思われるところを変更
- lisp/loadup.el
- lisp/startup.el
- src/w32fns.c
make&make installしてみたが
下記のように言われる
Warning (initialization): An error occurred while loading ‘d:/home/wurly/.emacs’: Symbol's function definition is void: ime-get-mode To ensure normal operation, you should investigate and remove the cause of the error in your initialization file. Start Emacs with the ‘--debug-init’ option to view a complete error backtrace.
ime-get-mode 見つからずにエラーとなっている。
w32-ime.el の中で、下記関数が参照されているが実体は無いので、Cソース側に実装する必要があるようだ。
- w32-set-ime-mode
- w32-ime-register-word-dialog
- ime-force-on
- ime-force-off
- ime-get-mode
できた
emacs-26.1-windows-ime-minimum.patch
基本的には下記5関数の実装(空関数も含む)と WM_IME_NOTIFY の処理。
- w32-set-ime-mode / w32_set_ime_mode
- w32-ime-register-word-dialog / w32_ime_register_word_dialog
- ime-force-on / ime_force_on
- ime-force-off / ime_force_off
- ime-get-mode / ime_get_mode