NTEmacs IMEパッチについて(23.4)
Table of Contents
はじめに
emacs-23.4-ime-2012-02-05.patch の解析。
追加 or 変更されているファイルリスト
- lib-src/makefile.w32-in
- lisp/international/w32-ime.el
- lisp/loadup.el
- lisp/startup.el
- nt/configure.bat
- src/buffer.c
- src/frame.c
- src/frame.h
- src/keyboard.c
- src/w32.c
- src/w32fns.c
- src/w32font.c
- src/w32menu.c
- src/w32proc.c
- src/w32term.c
- src/w32term.h
- src/window.c
各ファイル内容
lib-src/makefile.w32-in
追加
$(lispsource)international/w32-ime.elc が追加されている
WINNT_SUPPORT = ¥ $(lispsource)ls-lisp.elc ¥ $(lispsource)disp-table.elc ¥ $(lispsource)w32-fns.elc ¥ $(lispsource)dos-w32.elc ¥ $(lispsource)w32-vars.elc ¥ $(lispsource)international/w32-ime.elc ¥ ★ココ★ $(lispsource)term/common-win.elc ¥ $(lispsource)term/w32-win.elc
lisp/international/w32-ime.el
これは元々のEmacsのソースには存在しないファイル
ちなみに、Meadow のソースだと、lisp/international/meadow.el に元らしきコードがある。
Meadowだと mw32-なんちゃらとなっていた部分が w32-なんちゃら に変更されている。mw32のままでもよかったと思うのだが。
;;;;; w32-ime.el ---- Meadow features for NTEmacs.
;;
;; Author H.Miyashita
;;
;;;;;
(defgroup W32-IME nil
"w32-ime"
:group 'emacs)
(defvar w32-last-selection nil
"It is stored the last data from Emacs.")
;----------
(defvar w32-ime-on-hook nil
"Functions to eval when IME is turned on at least.
Even if IME state is not changed, these functiona are maybe called.")
(defvar w32-ime-off-hook nil
"Functions to eval when IME is turned off at least.
Even if IME state is not changed, these functiona are maybe called.")
(defvar w32-ime-buffer-switch-p t
"If this variable is nil, IME control when buffer is switched is disabled.")
(defvar w32-ime-show-mode-line t
"When t, mode line indicates IME state.")
(defvar w32-ime-mode-line-state-indicator "[O]"
"This is shown at the mode line. It is regarded as state of ime.")
(make-variable-buffer-local 'w32-ime-mode-line-state-indicator)
(put 'w32-ime-mode-line-state-indicator 'permanent-local t)
(defvar w32-ime-mode-line-state-indicator-list '("-" "[|]" "[O]")
"List of IME state indicator string.")
(defvar w32-ime-mode-line-format-original nil
"Original mode line format.")
;;
;; Section: IME
;;
;; ;; This is temporal solution. In the future, we will prepare
;; ;; dynamic configuration.
;; (defvar w32-ime-coding-system-language-environment-alist
;; '(("Japanese" . japanese-shift-jis)
;; ("Chinese-GB" . chinese-iso-8bit)
;; ("Chinese-BIG5" . chinese-big5)
;; ("Korean" . korean-iso-8bit)))
;;
;; IME state indicator
;;
(global-set-key [kanji] 'ignore)
(global-set-key [compend] 'ignore)
(defun wrap-function-to-control-ime
(function interactive-p interactive-arg &optional suffix)
"Wrap FUNCTION, and IME control is enabled when FUNCTION is called.
An original function is saved to FUNCTION-SUFFIX when suffix is string.
If SUFFIX is nil, ¥"-original¥" is added. "
(let ((original-function
(intern (concat (symbol-name function)
(if suffix suffix "-original")))))
(cond
((not (fboundp original-function))
(fset original-function
(symbol-function function))
(fset function
(list
'lambda '(&rest arguments)
(when interactive-p
(list 'interactive interactive-arg))
`(cond
((and (ime-get-mode)
(equal current-input-method "W32-IME"))
(ime-force-off)
(unwind-protect
(apply ',original-function arguments)
(when (and (not (ime-get-mode))
(equal current-input-method "W32-IME"))
(ime-force-on))))
(t
(apply ',original-function arguments)))))))))
(defvar w32-ime-toroku-region-yomigana nil
"* if this variable is string, toroku-region regard this value as yomigana.")
(defun w32-ime-toroku-region (begin end)
(interactive "r")
(let ((string (buffer-substring begin end))
(w32-ime-buffer-switch-p nil)
(reading w32-ime-toroku-region-yomigana))
(unless (stringp reading)
(w32-set-ime-mode 'hiragana)
(setq reading
(read-multilingual-string
(format "Input reading of ¥"%s¥": " string) nil "W32-IME")))
(w32-ime-register-word-dialog reading string)))
;; for IME management system.
(defun w32-ime-sync-state (window)
(when w32-ime-buffer-switch-p
(with-current-buffer (window-buffer window)
(let* ((frame (window-frame window))
(ime-state (ime-get-mode)))
(cond
((and (not ime-state)
(equal current-input-method "W32-IME"))
(ime-force-on nil)
(run-hooks 'w32-ime-on-hook))
((and ime-state
(not (equal current-input-method "W32-IME")))
;;; (when (= (w32-ime-undetermined-string-length) 0)
(ime-force-off nil)
(run-hooks 'w32-ime-off-hook)))))))
(defun w32-ime-set-selected-window-buffer-hook (oldbuf newwin newbuf)
(w32-ime-sync-state newwin))
(defun w32-ime-select-window-hook (old new)
(w32-ime-sync-state new))
(defun w32-ime-mode-line-update ()
(cond
(w32-ime-show-mode-line
(unless (window-minibuffer-p (selected-window))
(setq w32-ime-mode-line-state-indicator
(nth (if (ime-get-mode) 1 2)
w32-ime-mode-line-state-indicator-list))))
(t
(setq w32-ime-mode-line-state-indicator
(nth 0 w32-ime-mode-line-state-indicator-list))))
(force-mode-line-update))
(defun w32-ime-init-mode-line-display ()
(unless (member 'w32-ime-mode-line-state-indicator mode-line-format)
(setq w32-ime-mode-line-format-original
(default-value 'mode-line-format))
(if (and (stringp (car mode-line-format))
(string= (car mode-line-format) "-"))
(setq-default mode-line-format
(cons ""
(cons 'w32-ime-mode-line-state-indicator
(cdr mode-line-format))))
(setq-default mode-line-format
(cons ""
(cons 'w32-ime-mode-line-state-indicator
mode-line-format))))
(force-mode-line-update t)))
(defun w32-ime-initialize ()
(when (and (eq system-type 'windows-nt)
(eq window-system 'w32)
(featurep 'w32-ime))
(w32-ime-init-mode-line-display)
(w32-ime-mode-line-update)
(add-hook 'select-window-functions
'w32-ime-select-window-hook)
(add-hook 'set-selected-window-buffer-functions
'w32-ime-set-selected-window-buffer-hook)
(define-key global-map [kanji] 'toggle-input-method)))
;; (set-keyboard-coding-system 'utf-8)))
(defun w32-ime-uninitialize ()
(when (and (eq system-type 'windows-nt)
(eq window-system 'w32)
(featurep 'w32-ime))
(setq-default mode-line-format
w32-ime-mode-line-format-original)
(force-mode-line-update t)
(remove-hook 'select-window-functions
'w32-ime-select-window-hook)
(remove-hook 'set-selected-window-buffer-functions
'w32-ime-set-selected-window-buffer-hook)
(define-key global-map [kanji] 'ignore)))
(defun w32-ime-exit-from-minibuffer ()
(inactivate-input-method)
(when (<= (minibuffer-depth) 1)
(remove-hook 'minibuffer-exit-hook 'w32-ime-exit-from-minibuffer)))
(defun w32-ime-state-switch (&optional arg)
(if arg
(progn
(setq inactivate-current-input-method-function
'w32-ime-state-switch)
(run-hooks 'input-method-activate-hook)
(run-hooks 'w32-ime-on-hook)
(setq describe-current-input-method-function nil)
(when (eq (selected-window) (minibuffer-window))
(add-hook 'minibuffer-exit-hook 'w32-ime-exit-from-minibuffer))
(ime-force-on))
(setq current-input-method nil)
(run-hooks 'input-method-inactivate-hook)
(run-hooks 'w32-ime-off-hook)
(setq describe-current-input-method-function nil)
(ime-force-off))
(w32-ime-mode-line-update))
(register-input-method "W32-IME" "Japanese" 'w32-ime-state-switch ""
"W32 System IME")
(provide 'w32-ime)
lisp/loadup.el
international/w32-ime が追加されている
(if (eq system-type 'windows-nt)
(progn
(load "w32-vars")
(load "term/common-win")
(load "term/w32-win")
(load "ls-lisp")
(load "disp-table")
(load "international/w32-ime") ★ココ★
(load "dos-w32")
(load "w32-fns")))
lisp/startup.el
1行追加されている。ここで設定しておく必要はあるのだろうか。(ユーザ設定ではダメなのだろうか)
(set-language-environment "japanese") ★ココ★ (let ((pwd (getenv "PWD"))) (and (stringp pwd) ;; Use FOO/., so that if FOO is a symlink, file-attributes ;; describes the directory linked to, not FOO itself. (or (equal (file-attributes (concat (file-name-as-directory pwd) ".")) (file-attributes (concat (file-name-as-directory default-directory) "."))) (setq process-environment (delete (concat "PWD=" pwd) process-environment)))))
nt/configure.bat
- copyright に 2012 が追加されている。細かい。。
- usew32ime という設定が追加されている。
:start :start rem ---------------------------------------------------------------------- rem Default settings. set prefix= set nodebug=N set noopt=N set profile=N set nocygwin=N set COMPILER= set usercflags= set docflags= set userldflags= set doldflags= set sep1= set sep2= set usew32ime= ★ココ★
- configure.bat で –enable-w32-ime が指定された場合、withime にジャンプする。
- 親切に configure.bat のオプション説明のメッセージにも追加されている
rem ---------------------------------------------------------------------- rem Handle arguments. :again if "%1" == "-h" goto usage if "%1" == "--help" goto usage if "%1" == "--prefix" goto setprefix if "%1" == "--with-gcc" goto withgcc if "%1" == "--with-msvc" goto withmsvc if "%1" == "--no-debug" goto nodebug if "%1" == "--no-opt" goto noopt if "%1" == "--profile" goto profile if "%1" == "--no-cygwin" goto nocygwin if "%1" == "--cflags" goto usercflags if "%1" == "--ldflags" goto userldflags if "%1" == "--without-png" goto withoutpng if "%1" == "--without-jpeg" goto withoutjpeg if "%1" == "--without-gif" goto withoutgif if "%1" == "--without-tiff" goto withouttiff if "%1" == "--without-xpm" goto withoutxpm if "%1" == "--with-svg" goto withsvg if "%1" == "--enable-w32-ime" goto withime ★ココ★ if "%1" == "" goto checkutils :usage echo Usage: configure [options] echo Options: echo. --prefix PREFIX install Emacs in directory PREFIX echo. --with-gcc use GCC to compile Emacs echo. --with-msvc use MSVC to compile Emacs echo. --no-debug exclude debug info from executables echo. --no-opt disable optimization echo. --profile enable profiling echo. --no-cygwin use -mno-cygwin option with GCC echo. --cflags FLAG pass FLAG to compiler echo. --ldflags FLAG pass FLAG to compiler when linking echo. --without-png do not use PNG library even if it is installed echo. --without-jpeg do not use JPEG library even if it is installed echo. --without-gif do not use GIF library even if it is installed echo. --without-tiff do not use TIFF library even if it is installed echo. --without-xpm do not use XPM library even if it is installed echo. --with-svg use the RSVG library (experimental) echo. --enable-w32-ime build with w32 input method editor ★ココ★ goto end
- ここへ来ると usew32ime がY USE_W32_IMEがYとなる
rem ---------------------------------------------------------------------- :withime set usew32ime=Y set USE_W32_IME=Y shift goto again
- RECONVERTSTRING の処理
rem ----------------------------------------------------------------------
rem check for RECONVERTSTRING
rem
echo checking for RECONVERTSTRING...
echo #include "windows.h" >junk.c
echo #include "imm.h" >>junk.c
echo main(){RECONVERTSTRING x;} >>junk.c
%COMPILER% %usercflags% %mingwflag% -c junk.c -o junk.obj >>config.log 2>&1
if exist junk.obj goto haveReconvertstring
echo ...RECONVERTSTRING isn't defined.
echo The failed program was: >>config.log
type junk.c >>config.log
set HAVE_RECONVERTSTRING=
goto recoverstringDone
:haveReconvertstring
echo ...RECONVERTSTRING is defined.
set HAVE_RECONVERTSTRING=1
:recoverstringDone
rm -f junk.c junk.obj
- config.settings への追記
- usew32ime=Y の時、USE_W32_IME=1
- config.tmp への追記
- USE_W32_IME が空白でない時、#define USE_W32_IME 1
- HAVE_RECONVERTSTRING が空白でない時、#define HAVE_RECONVERTSTRING 1
- config.tmp へ #define PROFILING 1 が追記されないようにしている。
rem ---------------------------------------------------------------------- :genmakefiles echo Generating makefiles if %COMPILER% == gcc set MAKECMD=gmake if %COMPILER% == cl set MAKECMD=nmake rem Pass on chosen settings to makefiles. rem NB. Be very careful to not have a space before redirection symbols rem except when there is a preceding digit, when a space is required. rem echo # Start of settings from configure.bat >config.settings echo COMPILER=%COMPILER%>>config.settings if not "(%mf%)" == "()" echo MCPU_FLAG=%mf%>>config.settings if not "(%dbginfo%)" == "()" echo DEBUG_INFO=%dbginfo%>>config.settings if (%nodebug%) == (Y) echo NODEBUG=1 >>config.settings if (%noopt%) == (Y) echo NOOPT=1 >>config.settings if (%profile%) == (Y) echo PROFILE=1 >>config.settings if (%nocygwin%) == (Y) echo NOCYGWIN=1 >>config.settings if not "(%prefix%)" == "()" echo INSTALL_DIR=%prefix%>>config.settings rem We go thru docflags because usercflags could be "-DFOO=bar" -something rem and the if command cannot cope with this for %%v in (%usercflags%) do if not (%%v)==() set docflags=Y if (%docflags%)==(Y) echo USER_CFLAGS=%usercflags%>>config.settings for %%v in (%userldflags%) do if not (%%v)==() set doldflags=Y if (%doldflags%)==(Y) echo USER_LDFLAGS=%userldflags%>>config.settings if (%usew32ime%) == (Y) echo USE_W32_IME=1 >>config.settings ★ココは追加 echo # End of settings from configure.bat>>config.settings echo. >>config.settings copy config.nt config.tmp echo. >>config.tmp echo /* Start of settings from configure.bat. */ >>config.tmp if (%docflags%) == (Y) echo #define USER_CFLAGS " %usercflags%">>config.tmp if (%doldflags%) == (Y) echo #define USER_LDFLAGS " %userldflags%">>config.tmp if (%profile%) == (Y) echo #define PROFILING 1 >>config.tmp ★ココは削除 if not "(%HAVE_PNG%)" == "()" echo #define HAVE_PNG 1 >>config.tmp if not "(%HAVE_JPEG%)" == "()" echo #define HAVE_JPEG 1 >>config.tmp if not "(%HAVE_GIF%)" == "()" echo #define HAVE_GIF 1 >>config.tmp if not "(%HAVE_TIFF%)" == "()" echo #define HAVE_TIFF 1 >>config.tmp if not "(%HAVE_XPM%)" == "()" echo #define HAVE_XPM 1 >>config.tmp if "(%HAVE_RSVG%)" == "(1)" echo #define HAVE_RSVG 1 >>config.tmp if not "(%USE_W32_IME%)" == "()" echo #define USE_W32_IME 1 >>config.tmp ★ココは追加 if not "(%HAVE_RECONVERTSTRING%)" == "()" echo #define HAVE_RECONVERTSTRING 1 >>config.tmp ★ココは追加 echo /* End of settings from configure.bat. */ >>config.tmp
src/buffer.c
- マクロの追加
/* patch20101016 */ #ifdef WINDOWSNT #include <mbstring.h> #define LAST_CHAR(buf,len) ((len) < 1 ? '¥0' : *_mbsdec((buf), (buf) + (len))) #define STRINC(p) _mbsinc(p) #define STRDEC(start, p) _mbsdec(start, p) #+BEGIN_HTML <a name="else" id="else"> #+END_HTML #define LAST_CHAR(buf,len) ((len) < 1 ? '¥0' : *((buf) + (len) - 1)) #define STRINC(p) p + 1 #define STRDEC(start, p) p - 1 #+BEGIN_HTML <a name="endif" id="endif"> #+END_HTML
- 最後の文字列の判断が、マルチバイトだと問題になっている部分を修正しているようだ
/* patch20101016 if (!(IS_DIRECTORY_SEP (pwd[len - 1]))) */ if (!(IS_DIRECTORY_SEP (LAST_CHAR(pwd, len))))
src/frame.c
static struct frame_parm_table frame_parms[] =
{
{"auto-raise", &Qauto_raise},
{"auto-lower", &Qauto_lower},
{"background-color", 0},
{"border-color", &Qborder_color},
{"border-width", &Qborder_width},
{"cursor-color", &Qcursor_color},
{"cursor-type", &Qcursor_type},
{"font", 0},
{"foreground-color", 0},
{"icon-name", &Qicon_name},
{"icon-type", &Qicon_type},
{"internal-border-width", &Qinternal_border_width},
{"menu-bar-lines", &Qmenu_bar_lines},
{"mouse-color", &Qmouse_color},
{"name", &Qname},
{"scroll-bar-width", &Qscroll_bar_width},
{"title", &Qtitle},
{"unsplittable", &Qunsplittable},
{"vertical-scroll-bars", &Qvertical_scroll_bars},
{"visibility", &Qvisibility},
{"tool-bar-lines", &Qtool_bar_lines},
{"scroll-bar-foreground", &Qscroll_bar_foreground},
{"scroll-bar-background", &Qscroll_bar_background},
{"screen-gamma", &Qscreen_gamma},
{"line-spacing", &Qline_spacing},
{"left-fringe", &Qleft_fringe},
{"right-fringe", &Qright_fringe},
{"wait-for-wm", &Qwait_for_wm},
{"fullscreen", &Qfullscreen},
{"font-backend", &Qfont_backend},
{"alpha", &Qalpha},
#ifdef USE_W32_IME ★ココ追加
{"ime-font", &Qime_font}, ★ココ追加
#endif /* USE_W32_IME */ ★ココ追加
{"sticky", &Qsticky},
};
src/frame.h
extern Lisp_Object Qauto_raise, Qauto_lower; extern Lisp_Object Qborder_color, Qborder_width; extern Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list; extern Lisp_Object Qcursor_color, Qcursor_type; #ifdef USE_W32_IME ★ココ追加 extern Lisp_Object Qime_font; ★ココ追加 #endif /* USE_W32_IME */ ★ココ追加 extern Lisp_Object Qfont; extern Lisp_Object Qbackground_color, Qforeground_color; extern Lisp_Object Qicon, Qicon_name, Qicon_type, Qicon_left, Qicon_top; extern Lisp_Object Qinternal_border_width; extern Lisp_Object Qmenu_bar_lines, Qtool_bar_lines; extern Lisp_Object Qmouse_color; extern Lisp_Object Qname, Qtitle; extern Lisp_Object Qparent_id; extern Lisp_Object Qunsplittable, Qvisibility; extern Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars; extern Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background; extern Lisp_Object Qscreen_gamma; extern Lisp_Object Qline_spacing; extern Lisp_Object Qwait_for_wm; extern Lisp_Object Qfullscreen; extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth, Qmaximized; extern Lisp_Object Qsticky; extern Lisp_Object Qfont_backend; extern Lisp_Object Qalpha;