XEmacsのXIM
以降の説明はXEmacs 21.1系のものですが、21.4系でも同じことが当てはまります。21.4系では、このパッチを適用してください(FreeBSDのXEmacs 21.4.20で動作確認済み)。
XEmacs 21.1.xのXIMを改良する
2. ミニバッファ入力中のXIMオフ
概要
複数ストロークのコマンド入力が面倒。
詳細
xemacs-21.1.14でXIMを利用し、日本語入力オンの状態でM-w
やM->
などをエスケープキーに続けて複数ストロークで入力すると、エスケープだけがXEmacsに渡り、続く文字は前編集文字列になってしまう。そのほか、C-x b
などの複数ストローク入力も同様である。
原因
複数ストロークのコマンドを入力するときにXIMの日本語入力をオフにできない(してない)ため。内部的には入力しているコマンドが未完であることは判定されているが、XIMの制御には活用されていない。
修正の例
以下のパッチを適用する。FreeBSDで動作確認した。
diff -c -r -d src.orig/event-Xt.c src/event-Xt.c
*** src.orig/event-Xt.c Thu Jan 2 21:18:00 2003
--- src/event-Xt.c Thu Jan 2 21:24:27 2003
***************
*** 3003,3005 ****
--- 3003,3037 ----
shellClassRec.core_class.initialize = ShellVisualPatch;
}
+
+ #if defined(HAVE_XIM)
+ #include <dlfcn.h>
+ #include "window.h"
+
+ Bool
+ XFilterEvent(XEvent *event, Window w)
+ {
+ static Bool (*realXFilterEvent)(XEvent *, Window) = NULL;
+ static int self = 0;
+
+ if (realXFilterEvent == NULL)
+ realXFilterEvent = dlsym(RTLD_NEXT, "XFilterEvent");
+
+ if (event->type != KeyPress || EQ(minibuf_window, Fselected_window(Qnil))
+ || event_chain_count(Vthis_command_keys) < 1
+ || cursor_in_echo_area) {
+ self = 0;
+ return realXFilterEvent(event, w);
+ }
+ if (EQ(Vthis_command, Qself_insert_command)) {
+ self = 1;
+ return realXFilterEvent(event, w);
+ }
+ if (self) {
+ self = 0;
+ return realXFilterEvent(event, w);
+ }
+ self = 0;
+ return False;
+ }
+ #endif
1. 空白のコミット
概要
空白をコミットできない。
詳細
xemacs-21.1.14でXIMを利用し、空白文字列を含む文字列をコミット(確定)した場合、空白文字の直前まで入力されて、ベル音が鳴り、空白文字以降の文字列が入力されない。
原因
コミットされる文字列に、空白、改行などの文字コードが含まれていることを考慮してないため。スペースキーを変換キーに割り当てることが多く、気付きにくい。
修正の例
以下のパッチを適用する。ただし、このパッチでは空白文字に関する問題しか考慮されていない。
diff -c -r -d src.orig/event-Xt.c src/event-Xt.c
*** src.orig/event-Xt.c Sun Dec 17 11:08:49 2000
--- src/event-Xt.c Mon Feb 26 04:32:54 2001
***************
*** 880,885 ****
--- 880,887 ----
ev->timestamp = event->time;
ev->event.key.modifiers = 0;
ev->event.key.keysym = make_char (ch);
+ if (ch == ' ')
+ ev->event.key.keysym = QKspace;
enqueue_Xt_dispatch_event (emacs_event);
}
Lstream_close (istr);