長いタイトルの通りです。
AutoHotKeyを使い、EscまたはCtrl-[でノーマルモードに戻る際に、日本語入力がONであればOFFになるよう設定します。
AutoHotKeyのインストール
以下からダウンロードしてインストールする。
http://www.autohotkey.com/
ahkスクリプト
以下のスクリプトを*.ahkとして保存し、実行します。
ここでは、Sublime Text(とついでにAtom)のWindowがアクティブのときにのみAutoHotKeyが有効になるようにしています。
なお、IMEの操作には、eamat@Cabinetさんが公開されているIME.ahkを使わせていただいています。
vim_esc.ahk
; For Sublime Text/Atom
SetTitleMatchMode, 2
GroupAdd Editor, ahk_class PX_WINDOW_CLASS ; Sublime Text
GroupAdd Editor, - Atom ; Atom
return
; Paste IME.ahk functions
IME_GET(WinTitle="A") {
ControlGet,hwnd,HWND,,,%WinTitle%
if (WinActive(WinTitle)) {
ptrSize := !A_PtrSize ? 4 : A_PtrSize
VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
NumPut(cbSize, stGTI, 0, "UInt") ; DWORD cbSize;
hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
}
return DllCall("SendMessage"
, UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
, UInt, 0x0283 ;Message : WM_IME_CONTROL
, Int, 0x0005 ;wParam : IMC_GETOPENSTATUS
, Int, 0) ;lParam : 0
}
IME_SET(SetSts, WinTitle="A") {
ControlGet,hwnd,HWND,,,%WinTitle%
if (WinActive(WinTitle)) {
ptrSize := !A_PtrSize ? 4 : A_PtrSize
VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
NumPut(cbSize, stGTI, 0, "UInt") ; DWORD cbSize;
hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
}
return DllCall("SendMessage"
, UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
, UInt, 0x0283 ;Message : WM_IME_CONTROL
, Int, 0x006 ;wParam : IMC_SETOPENSTATUS
, Int, SetSts) ;lParam : 0 or 1
}
IME_GetConverting(WinTitle="A",ConvCls="",CandCls="") {
;IME毎の 入力窓/候補窓Class一覧 ("|" 区切りで適当に足してけばOK)
ConvCls .= (ConvCls ? "|" : "") ;--- 入力窓 ---
. "ATOK\d+CompStr" ; ATOK系
. "|imejpstcnv\d+" ; MS-IME系
. "|WXGIMEConv" ; WXG
. "|SKKIME\d+\.*\d+UCompStr" ; SKKIME Unicode
. "|MSCTFIME Composition" ; Google日本語入力
CandCls .= (CandCls ? "|" : "") ;--- 候補窓 ---
. "ATOK\d+Cand" ; ATOK系
. "|imejpstCandList\d+|imejpstcand\d+" ; MS-IME 2002(8.1)XP付属
. "|mscandui\d+\.candidate" ; MS Office IME-2007
. "|WXGIMECand" ; WXG
. "|SKKIME\d+\.*\d+UCand" ; SKKIME Unicode
CandGCls := "GoogleJapaneseInputCandidateWindow" ;Google日本語入力
ControlGet,hwnd,HWND,,,%WinTitle%
if (WinActive(WinTitle)) {
ptrSize := !A_PtrSize ? 4 : A_PtrSize
VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
NumPut(cbSize, stGTI, 0, "UInt") ; DWORD cbSize;
hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
}
WinGet, pid, PID,% "ahk_id " hwnd
tmm:=A_TitleMatchMode
SetTitleMatchMode, RegEx
ret := WinExist("ahk_class " . CandCls . " ahk_pid " pid) ? 2
: WinExist("ahk_class " . CandGCls ) ? 2
: WinExist("ahk_class " . ConvCls . " ahk_pid " pid) ? 1
: 0
SetTitleMatchMode, %tmm%
return ret
}
#IfWInActive, ahk_group Editor
; When Press Esc
Esc::
if (IME_GET(A)) {
if (IME_GetConverting(A)) {
Send,{Esc}
} else {
Send,{Esc}
Sleep 1 ; wait 1 ms (Need to stop converting)
IME_SET(0)
}
} else {
Send,{Esc}
}
Return
^[::
; When Press Ctrl-[
if (IME_GET(A)) {
Send,{Esc}
Sleep 1 ; wait 1 ms (Need to stop converting)
IME_SET(0)
Send,{Esc}
} else {
Send,{Esc}
}
Return
#IfWInActive