Windows 8 環境下で NTEmacs を使うと、場合によっては日本語入力がうまくいかない。その対処策として判明したのは、 Emacs のウィンドウを移動したりサイズを変更することである。そこでAutoHotkey_L のスクリプトを用いて対処策を実現し、その AutoHotkey_L スクリプトを Emacs lisp 経由で実行することにした。こうすれば問題の症状に対処することができる。
これまで私は、Windows 8 と Windows 7 の環境下で、 gnupack (cygwn + emacs package) 所収の Emacs (NTEmacs) を利用してきた。この gnupack は、 Windows ユーザーから関心を集めているツール集であり、今年出版された『Emacs実践入門』(([asin:4774150029:detail]))では、Windows ユーザーにとって導入しやすい、 Emacs (NTEmacs) が収録されているパッケージだと位置づけられている((p.12))。たしかに、Emacs を即座に使ってみたい Windows ユーザーにとって、gnupack は手軽かつ便利なパッケージなのだ。
先日、ime-enable-document-feed有効時のフリーズ問題解消? - gnupackの開発メモで配布されている Emacs version 24.3 を入手し、 gnupack に収録されている Emacs を最新版へと更新したら、Windows 8 で日本語入力がうまくいかなくなった(Windows 7 においては同様の症状は生じない)。日本語で入力するために Emacs 上で変換キーを押しても IME が有効にならないのである。eamat @Cabinet - IME制御(IME.ahk) を使ってIME の状態を監視している最中に変換キーを押したら、MEの状態には変化が見あたらないという、以下の画像のとおりの結果が出た。本来であれば、変換キーを押せば IME_GET の値は 0 と 1 を交互に切り替えるはずである。しかし、そうはならずに、"<auto> is undefiend" や "<enlw> is undefined" とのエラーメッセージが表示されるだけなのだった。
[f:id:blechmusik2:20130708023821p:plain] [f:id:blechmusik2:20130708023830p:plain]
参考資料として、Meryで同様の動作をしたその結果を画像形式で示そう。IME_GET の値が正しく変化していることに気づくだろう。
[f:id:blechmusik2:20130708023849p:plain] [f:id:blechmusik2:20130708023858p:plain]
では、どうすればこの問題を解消できるのか。私の場合、Windows キー + space で複数の IME を切り替えることで対処してきた。普段利用している ATOK から Microsoft IME へと IME を切り替え、その状態で何かしら入力し、続けて Microsoft IME から ATOK へと IME を再度切り替えていた。こうすれば日本語入力に支障は無くなるのだが、問題を対処するための手順としては煩雑なものと評価せざるを得まい。
結論を先取りすると、私が頼った対処策は AutoHotkey と emacs を連動させ、emacs の位置を調整するというものである。
私が現在採用している対処策に関しては、 twitter 上のつぶやきから着想を得た。
この指摘のとおり、「NTEmacsのウインドウを移動させる・サイズ変更す」れば、「半角/全角キーが機能」するようになる。ただし、ここでいうサイズ変更やウィンドウ移動というのは、マウス操作を経由するものであって、AutoHotkey の WinMove - AutoHotkeyJpを使うものではない。後者の場合は、確かにウィンドウを移動させることはできるが、半角/全角キーを機能させることにはつながらないのだ。
こうして、対処策は次の手順としてまとめられる。
後者の elisp を Emacs 起動時に自動的に読み込むか、手動で評価することによって、件の日本語入力のつまづきが解消される。
ここでは、AutoHotkey_L の現行スクリプト名は shaking-the-window-of-ntemacs-to-enable-ime.ahk で、exe バイナリ化したファイルの名前は shaking-the-window-of-ntemacs-to-enable-ime.exe とする。
#NoEnv SendMode Input SetWorkingDir %A_ScriptDir% #SingleInstance force DetectHiddenWindows, On whnd := WinExist("ahk_class Emacs") if (( whnd ) and ("WIN_8" == A_OSVersion)){ WinActivate, ahk_id %whnd% MouseGetPos, mouseX, mouseY ;; mouseButton := "left" mouseButton := "right" if (get_script_parameters()[1]) { mouseButton := get_script_parameters()[1] } BlockInput, MouseMove MouseClick, %mouseButton%, 50, 15, , 0, D sleep,50 MouseClick, %mouseButton%, 15, 0, , 0, D, R sleep,50 MouseClick, %mouseButton%, -15, 0, , 0, U, R sleep,50 MouseMove, %mouseX%, %mouseY%, 0 BlockInput, MouseMoveOff ;; WinGetPos, winX, winY ;; WinMove, ahk_id %whnd%, , winX+1, winY ;; WinMove, ahk_id %whnd%, , winX, winY } ExitApp get_script_parameters(){ global static Script_Parameters := Object() if ("" == Script_Parameters.MaxIndex()) { Loop, %0% { Script_Parameters.insert(%A_Index%) } } return Script_Parameters }
(defvar exec-path-shaking-the-window-of-ntemacs "~/shaking-the-window-of-ntemacs-to-enable-ime.exe") (defun shaking-the-window-of-ntemacs (path &optional mouse-button) (with-temp-buffer (start-process "my-process" nil path (if mouse-button mouse-button "left") ))) (if (and (eq window-system 'w32) (file-exists-p exec-path-shaking-the-window-of-ntemacs) ) ;; (move-window-with-ahk path-move-window-with-ahk) (shaking-the-window-of-ntemacs exec-path-shaking-the-window-of-ntemacs "right") (message (concat "error: " exec-path-shaking-the-window-of-ntemacs " is not found.")))