AHK 八倒記 (4)
前回の続き。
AutoHotkey で Space キーをワンショットモディファイヤとして使う定義がとりあえず実用レベルに達した。
昨日のやり方だとキー1個につき modify() と unmodify() の2行を書かなきゃいけないのが気に入らないので、キー1個につき1行で済むやり方をいろいろ考えた。
- モディファイヤキーの状態に応じて入力すべきキー名を動的に生成し、その名前のホットキーラベルがあれば gosub で飛ばす。なければその名前のキーを send する。…ラベルは字面で比較されるので、 ^+End と +^End は別物扱い。 Shift, Ctrl, Alt, Win の全パターンに対応しようとすると組合せ爆発が起きる。
$*sc027:: if (getkeystate("Space")) { next := "End" ; ← Shift は? Ctrl は? } else { next := "sc027" } if (islabel(next)) { gosub %next% } else { send {%next%} } return
- ラッパー関数を用意し、その中で Hotkey コマンドを使って2つのホットキー(modify() と unmodify())を動的に定義する。… Hotkey コマンドでは関数を呼ぶホットキーが作れない。
AddModifiedKey(keyname, key0, key1) { Hotkey %keyname%, OM_Modify(key0, key1) ; ← 関数は呼べない Hotkey %keyname% up, OM_Unmodify() }
てな感じで両方とも実現不可能という結論に。仕方ないので昨日のやつをちょっと改良して実際に使う定義ファイルを書いた。ここでまた罠が… $+sc027:: と $*sc027:: が同時に存在するとき Shift+セミコロン を押すと $+sc027:: の方しか発動しない。となると 104on109.ahk を温存したまま共存させることはできなくて、両者の内容をマージしなきゃいけない。めんどくせー。 AutoHotkey はキー定義を全部ひとつのレイヤに押し込む設計だから、本質的にモディファイヤを作るのには向いてないし、モジュール化もできないんだなぁ。にんともかんとも。
というわけで、一部未完成だけどとりあえず実用レベルに達したものを貼っときます。識者の意見を求む。
; ikki_phase14.ahk (2008/06/05) ; by IKKI http://mobitan.org/ #NoEnv ; #NoTrayIcon #SingleInstance force SetWorkingDir %A_ScriptDir% SendMode input gosub OM_Init return #Include %A_ScriptDir% #Include OneshotModifier_Space.ahk ;========== ウィンドウ操作 ========== sc029:: send !{F4} ; 半角/全角 Pause:: send !{F4} ;========== IME 切替 ========== Alt:: send {sc029} ; 半角/全角 = IME ON/OFF Shift:: send {sc070} ; ひらがな = 和文モード/英文モード ;========== リマップ ========== ; 単純なリマップはレジストリで行う ; sc073:: Delete ; \ → Delete ; sc07B:: BS ; 無変換 → Backspace ; sc079:: NumpadEnter ; 変換 → NumEnter ; NumLock:: NumpadSub ; NumLock → NumMinus ; NumpadSub:: BS ; NumMinus → Backspace ; NumpadAdd:: Tab ; NumPlus → Tab *Numpad0:: send {blind}{Numpad0} Numpad0 & NumLock:: send {Blind}{NumpadAdd} ; Num0+NumLock → Num+ Numpad0 & NumpadAdd:: send {Blind}+{Tab} ; Num0+NumPlus → Shift+Tab ^Numpad0:: SetNumLockState off ; Ctrl+Num0 → NumLock ^NumpadIns:: SetNumLockState on ; ;========== モディファイヤ ========== $*sc002:: OM_Modify("{blind}{sc002}", "{blind}{F1}") ; 1 $+sc003:: OM_Modify("{sc01A}", "{blind}{F2}") ; Shift+2 = @ $*sc003:: OM_Modify("{blind}{sc003}", "{blind}{F2}") ; Other+2 $*sc004:: OM_Modify("{blind}{sc004}", "{blind}{F3}") ; 3 $*sc005:: OM_Modify("{blind}{sc005}", "{blind}{F4}") ; 4 $*sc006:: OM_Modify("{blind}{sc006}", "{blind}{F5}") ; 5 $+sc007:: OM_Modify("{sc00D}", "{blind}{F6}") ; Shift+6 = ^ $*sc007:: OM_Modify("{blind}{sc007}", "{blind}{F6}") ; Other+6 $+sc008:: OM_Modify("+{sc007}", "{blind}{F7}") ; Shift+7 = & $*sc008:: OM_Modify("{blind}{sc008}", "{blind}{F7}") ; Other+7 $+sc009:: OM_Modify("+{sc028}", "{blind}{F8}") ; Shift+8 = * $*sc009:: OM_Modify("{blind}{sc009}", "{blind}{F8}") ; Other+8 $+sc00A:: OM_Modify("+{sc009}", "{blind}{F9}") ; Shift+9 = ( $*sc00A:: OM_Modify("{blind}{sc00A}", "{blind}{F9}") ; Other+9 $+sc00B:: OM_Modify("+{sc00A}", "{blind}{F10}") ; Shift+0 = ) $*sc00B:: OM_Modify("{blind}{sc00B}", "{blind}{F10}") ; Other+0 $+sc00C:: OM_Modify("+{sc073}", (A_ComputerName = "Reinforce") ? "{blind}{PgDn}" : "{blind}{F11}") ; Shift+− = _ $*sc00C:: OM_Modify("{blind}{sc00C}", (A_ComputerName = "Reinforce") ? "{blind}{PgDn}" : "{blind}{F11}") ; Other+− $sc00D:: OM_Modify("+{sc01A}", (A_ComputerName = "Reinforce") ? "{blind}{F11}" : "{blind}{F12}") ; Alone ^ = ` $+sc00D:: OM_Modify("+{sc00D}", (A_ComputerName = "Reinforce") ? "{blind}{F11}" : "{blind}{F12}") ; Shift+^ = 〜 $*sc00D:: OM_Modify("{blind}{sc00D}", (A_ComputerName = "Reinforce") ? "{blind}{F11}" : "{blind}{F12}") ; Other+^ $*sc07D:: OM_Modify("{blind}{sc07D}", (A_ComputerName = "Reinforce") ? "{blind}{F12}" : "{blind}{}") ; ¥ $*q:: OM_Modify("{blind}{q}", "{blind}{AppsKey}") $*w:: OM_Modify("{blind}{w}", "WebSearch") ; Web 検索 $*e:: OM_Modify("{blind}{e}", "{blind}^{sc079}") ; IME 確定履歴 $*r:: OM_Modify("{blind}{r}", "{blind}+{sc079}") ; IME 再変換 $*t:: OM_Modify("{blind}{t}", "IMEDic") ; IME 辞書引き $*y:: OM_Modify("{blind}{y}", "{blind}^{Home}") ; $*u:: OM_Modify("{blind}{u}", "{blind}^{Left}") ; $*i:: OM_Modify("{blind}{i}", "{blind}{Up}") ; $*o:: OM_Modify("{blind}{o}", "{blind}^{Right}") ; $*p:: OM_Modify("{blind}{p}", "{blind}{PgUp}") ; $sc01A:: OM_Modify("+{sc00C}", "{blind}{Esc}") ; Alone @ = = $+sc01A:: OM_Modify("+{sc027}", "{blind}{Esc}") ; Shift+@ = + $*sc01A:: OM_Modify("{blind}{sc01A}", "{blind}{Esc}") ; Other+@ $*sc01B:: OM_Modify("{blind}{sc01B}", "{blind}{}") ; [ $*a:: OM_Modify("{blind}{a}", "ShiftAltTab") ; $*s:: OM_Modify("{blind}{s}", "{blind}^+{Tab}") ; $*d:: OM_Modify("{blind}{d}", "{blind}^{F4}") ; $*f:: OM_Modify("{blind}{f}", "{blind}^{Tab}") ; $*g:: OM_Modify("{blind}{g}", "AltTab") ; $*h:: OM_Modify("{blind}{h}", "{blind}{Home}") ; $*j:: OM_Modify("{blind}{j}", "{blind}{Left}") ; $*k:: OM_Modify("{blind}{k}", "{blind}{Down}") ; $*l:: OM_Modify("{blind}{l}", "{blind}{Right}") ; $+sc027:: OM_Modify("{sc028}", "{blind}{End}") ; Shift+; = : $*sc027:: OM_Modify("{blind}{sc027}", "{blind}{End}") ; Other+; $sc028:: OM_Modify("+{sc008}", "{blind}{}") ; Alone : = ’ $+sc028:: OM_Modify("+{sc003}", "{blind}{}") ; Shift+: = ” $*sc028:: OM_Modify("{blind}{sc028}", "{blind}{}") ; Other+: $*sc02B:: OM_Modify("{blind}{sc02B}", "{blind}{}") ; ] $*z:: OM_Modify("{blind}{z}", "{blind}^{z}") ; $*x:: OM_Modify("{blind}{x}", "{blind}^{x}") ; $*c:: OM_Modify("{blind}{c}", "{blind}^{c}") ; $*v:: OM_Modify("{blind}{v}", "{blind}^{v}") ; $*b:: OM_Modify("{blind}{b}", "{blind}{Space}") ; $*n:: OM_Modify("{blind}{n}", "{blind}+{Tab}") ; $*m:: OM_Modify("{blind}{m}", "{blind}{Tab}") ; $+sc033:: OM_Modify("{blind}{sc033}", "{blind}^{x}") ; Shift+, $*sc033:: OM_Modify("{blind}{sc033}", "{blind}^{c}") ; Other+, $*sc034:: OM_Modify("{blind}{sc034}", "{blind}^{v}") ; . $*sc035:: OM_Modify("{blind}{sc035}", "{blind}^{End}") ; / AltTab: ; Alt+Tab ; 未対応 return ShiftAltTab: ; Alt+Shift+Tab ; 未対応 return IMEDic: ; IME 辞書引き send +{sc079} ; 再変換 sleep 100 send {F1} return WebSearch: ; Web 検索 ; 未対応 return ClipHist: ; クリップボード履歴 ; 未対応 return ~$*sc002 up:: OM_Unmodify() ~$*sc003 up:: OM_Unmodify() ~$*sc004 up:: OM_Unmodify() ~$*sc005 up:: OM_Unmodify() ~$*sc006 up:: OM_Unmodify() ~$*sc007 up:: OM_Unmodify() ~$*sc008 up:: OM_Unmodify() ~$*sc009 up:: OM_Unmodify() ~$*sc00A up:: OM_Unmodify() ~$*sc00B up:: OM_Unmodify() ~$*sc00C up:: OM_Unmodify() ~$*sc00D up:: OM_Unmodify() ~$*sc07D up:: OM_Unmodify() ~$*q up:: OM_Unmodify() ~$*w up:: OM_Unmodify() ~$*e up:: OM_Unmodify() ~$*r up:: OM_Unmodify() ~$*t up:: OM_Unmodify() ~$*y up:: OM_Unmodify() ~$*u up:: OM_Unmodify() ~$*i up:: OM_Unmodify() ~$*o up:: OM_Unmodify() ~$*p up:: OM_Unmodify() ~$*sc01A up:: OM_Unmodify() ~$*sc01B up:: OM_Unmodify() ~$*a up:: OM_Unmodify() ~$*s up:: OM_Unmodify() ~$*d up:: OM_Unmodify() ~$*f up:: OM_Unmodify() ~$*g up:: OM_Unmodify() ~$*h up:: OM_Unmodify() ~$*j up:: OM_Unmodify() ~$*k up:: OM_Unmodify() ~$*l up:: OM_Unmodify() ~$*sc027 up:: OM_Unmodify() ~$*sc028 up:: OM_Unmodify() ~$*sc02B up:: OM_Unmodify() ~$*z up:: OM_Unmodify() ~$*x up:: OM_Unmodify() ~$*c up:: OM_Unmodify() ~$*v up:: OM_Unmodify() ~$*b up:: OM_Unmodify() ~$*n up:: OM_Unmodify() ~$*m up:: OM_Unmodify() ~$*sc033 up:: OM_Unmodify() ~$*sc034 up:: OM_Unmodify() ~$*sc035 up:: OM_Unmodify()
; OneshotModifier_Space.ahk v1.0 (2008/06/05) ; by IKKI http://mobitan.org/ ; スペースキーをワンショットモディファイヤにする。半ロールオーバー対応。 #NoEnv #SingleInstance force OM_Init: OM_mod1 = 0 return *Space:: OM_mod1 |= 2 ; tooltip % "mod1 = " . OM_mod1 return *Space up:: if (OM_mod1 & 1 == 0) { send {blind}{Space} } OM_mod1 &= 5 if (OM_mod1 & 4 == 0) { OM_mod1 := 0 } ; tooltip % "mod1 = " . OM_mod1 return OM_Modify(key0, key1) { global OM_mod1 if (OM_mod1 & 2) { OM_mod1 |= 5 if (islabel(key1)) { gosub % key1 } else { send % key1 } } else if (OM_mod1 == 0) { if (islabel(key0)) { gosub % key0 } else { send % key0 } } ; tooltip % "mod1 = " . OM_mod1 . "`n" . A_ThisHotkey . " is modified" } OM_Unmodify() { global OM_mod1 OM_mod1 &= 3 if (OM_mod1 & 2 == 0) { OM_mod1 := 0 } ; tooltip % "mod1 = " . OM_mod1 . "`n" . A_ThisHotkey . " is unmodified" } ; ~Esc:: tooltip ; ツールチップを消す(デバッグ用)