最終更新日: 2019-01-04 金 14:42
ホーム | 文書トップ | 目次

自作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
ホーム | 文書トップ | 目次
Created by Emacs 27.1 (Org mode 9.3)