AutoHotKeyの解説と自分の設定について

前置き

自作キーボードキットのErgoDashを組み立てて日々使っているが、以下のページで紹介されている方法を使って、Raise/Lowerキーを「単独で押せば変換/無変換 or かな/英数、他のキーと組み合わせて押せばRaise/Lower」となるように設定して使っている。

MacOSは「かな/英数キー」でIMEのオン/オフが切り替えられ、Windowsも、enthumbleというアプリを使えば「変換/無変換キー」で同じことができるので、こうした設定を行なっている。

MacOSではこの設定で問題なくIMEを切り替えられたのだが、Windowsで同じことを実現しようとした時に思いっきりつまづいてしまった。

試行錯誤の末に、WindowsでもIMEをMacOSと同様に切り替えられるようになったのだが、そのときの知見を備忘録代わりにまとめておこうと思う。

enthumbleとは?

前置きでも少し触れているが、Windowsで出番がほとんどない無変換キーをFnキーの代わりとして使うことで、「無変換-HJKL」でカーソル移動、「無変換-スペース」でEnterキーを入力、「無変換-S」でCtrl-Sを入力、といった機能に加えて、変換/無変換キーをIMEのオン/オフのキーとして使えるようにするアプリである。

自作キーボードを使う前から重宝していたアプリなのだが、自作キーボード導入後はしばらくWindowsPCを操作していなかったので、自作キーボード導入後の最初のWindowsPC操作の時点で、変換/無変換キーをIMEの切り替えに使えないという問題に遭遇してしまったのである。

最初の悪戦苦闘

enthumbleを入れても変換/無変換キーをIMEのオン/オフキーとして使えなかったので、まずは、本当に変換/無変換がWindowsに送信されているのか調べることにした。

調査では、まず、Change Keyというキーボードカスタマイズソフトのキーコード調査機能を使ったのだが、以下のスクリーンショットのとおり、ちゃんと変換/無変換キーが送信されているという結果が出てきた。

スクショ1

変換/無変換キーが送信されているのは確認できたので、Raise/Lowerキーを「単独で押せば変換/無変換、他のキーと組み合わせたらRaise/Lower」という設定がきちんとできていることは確認できたのだが、それでもenthumbleが動作しない理由が分からなかった。とりあえず、enthumbleを再インストールしたりWindowsを再起動したりといった定番の作業は行ったが、一向に問題が解決しない。

ここで、enthumbleを使うことは諦めて、キーボードカスタマイズソフトのAutoHotkeyを使うことにした。

AutoHotKeyとは?

AutoHotKeyは、元々はキーボードカスタマイズソフトとして開発されていたが、ユーザーの要望を取り入れながら開発しているうちに、Windowsの動作制御までできるようになったソフトである。

本当に多機能なソフトで、

  • アプリ毎に自分用のショートカットキーを作る
  • 変換/無変換キーをIMEの制御キーする
  • アプリ操作を自動化
  • GUIフォームを備えたアプリを作成する

といった具合に、とにかく色んなことができるようになるソフトである。

また、書いたスクリプトを.exeファイルにコンパイルすることもできるので、自作の設定を他人に使ってもらうことも可能である。ちなみに、enthumbleもAutoHotKeyで作成されている。

ただし、様々なことができるとはいえ、自分でスクリプトを書かないといけないので、マウスでぽちぽちクリックすればOKと言う訳ではない。とはいえ、自分用のショートカットキーを作ったり、IMEの制御を「全角/半角」キー以外で行うと言うレベルであれば、そこまで難しいものではない。

というわけで、AutoHotKeyの使い方を簡単に紹介するとともに、私が行っている設定も紹介したいと思う。

AutoHotKeyの使い方

詳しい使い方については、ネットを検索すれば優れた先人の解説がいくつも見つかるので、本記事では基本的な部分に絞って解説する。

基本的な構文

AutoHotKeyでMyショートカットキー(AutoHotKeyではホットキーと呼ぶ)を作成する場合、*.ahkという拡張子の設定ファイルにホットキーを割り当てるキー::という形でコードを書く。こう書くことで、AutoHotKeyではサブルーチンのラベルとして認識され、指定のキーを押すと、ラベルの次の行以降に処理が移り、ReturnExitが実行されるまで処理が続けられる。

なお、/* ~ */という構文はコメントである。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
example2: Alt-Qの2連打でアプリを閉じる
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
~!q::
  Input, inputText, I L1 T0.5, !q
  IfInString, ErrorLevel, EndKey:
  {
    Send, !{F4}
  }
Return

なお、割り当てる処理が1行で足りる場合、以下のコードのようにReturnを省略できる。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
example1: Ctrl-Alt-Rでこのスクリプトを再読み込みする
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
^!r::Reload

ホットキーの指定方法

ホットキーを指定するには、こちらに掲載されているキーリストに沿って指定するが、基本的に、アルファベットキーは印字通り(大文字小文字は不問)指定すればOKである。BackSpaceやReturnなどのキーも、基本的にキーの印字通りでOKである。

一方、変換/無変換のような一部のキーは、vkXX(仮想キーコード)scYYY(スキャンコード)というキーコードで指定する必要がある。キー毎の具体的なコードは、上記のリンク先を参考にするか、AutoHotKeyのキースキャン機能で確認できる。

なお、注意事項として、ネットではvkXXscYYYという指定方法が散見されるが、この方式は、2017年12月25日にリリースされたバージョン1.1.27.00で*.ahkスクリプトのバリデーションが変更されたことにより、現在ではエラーとなる。そのため、現在はvkXXscYYYと指定する。

CtrlやAltキーなどのモディファイヤキーと組み合わせるホットキーを指定する際は、以下の表に示したコードと組み合わせて指定する(例: ^j)。上の設定例の^!rは”Ctrl-Alt-R”という組み合わせを指定している。

キー名説明
+shift
^control
!alt
#windows

なお、上の設定例の~!q::の行頭にある~は、押したキーをそのままシステムに通すという設定である。この例で言えば、”Alt-Q”というキーをAutoHotKeyで受け取った後システムにも渡すという設定である。

変数と条件分岐

変数

変数は、事前の宣言不要でMyVar = 123abcの形で値を代入できる。また、変数の値の展開はMsgBox, MyVar is %MyVar%のように%で囲めばOKである。

なお、関数の返り値を変数に代入する際は、MyVar := function()のように、=ではなく:=とする必要がある。

参考

条件分岐

If文による条件分岐が可能であり、ElseIfの条件に当てはまらない場合の処理が指定できる。その場合、Elseの後にIfを追加して細かい条件分岐を行うことも可能である。

If MyVar > 10000
    MsgBox,"たくさん"
Else If MyVar > 1000
    MsgBox,"多い"
Else
    MsgBox,"そこそこ"

If文による条件分岐は、「等しい、以上・以下、超・未満」のような判定に加えて、指定した文字列が含まれているか、変数のデータ型が特定の型に等しいか、という判定も可能である。

参考

設定ファイルの分割

AutoHotKeyの設定は*.ahkファイルに書いていくが、全ての設定を1つのファイルに書く必要はなく、複数の*.ahkファイルに書くことが可能である。設定が増えた際の管理の手間を考えると、アプリ毎の設定ファイル、Windows全体で適用する設定ファイルのように、目的別で分けた方が良いと思う。

私の場合、IME関係(IME-setting.ahk)、アプリ毎の設定(settings-for-each-app.ahk)、その他の設定(misc-setting.ahk)の3つに分けて管理しており、その3つのファイルをmy_keybind.ahkで以下のとおり読み込んでいる。なお、1行目では各設定で使うIME.ahkを読み込んでいる。ここで読み込むと、それぞれの設定ファイルでは改めて読み込む必要がなくなる。

#Include %A_ScriptDir%/IME.ahk
#Include %A_ScriptDir%/IME-setting.ahk
#Include %A_ScriptDir%/settings-for-each-app.ahk
#Include %A_ScriptDir%/misc-setting.ahk
Return

実際のファイルを確認したい人は、私のGitHubのリポジトリを確認して欲しい。

参考

具体的な設定

AutoHotKeyの各機能を1つ1つ説明すると非常に長くなるし、そもそも「まずホットキーを指定し、そのホットキーに処理を割り当てる」というスタイルで設定していくアプリなので、これ以降は具体的な設定を逐一解説することで、AutoHotKeyの使い方を説明するという流れにする。

IMEのオン/オフの切り替え

最初は、上記のとおり悪戦苦闘したIMEのオン/オフの切り替えから。

キーコードの指定でつまずいたが、以下のコードで望み通りの動作を実現することができた。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Title: 変換/無変換でIMEをオン/オフする
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
SC079::IME_SET(1)
SC07B::
  if IME_GetConverting() >= 1 {
    Return
  }
  else {
    IME_SET(0)
  }
  Return

この設定で使用しているIME_SET()関数とIME_GetConverting関数は、前述の「設定ファイルの分割」の1行目(#Include %A_ScriptDir%/IME.ahk)で読み込んだIME.ahkで定義されている。IME周りの制御では必須の関数が定義されているスクリプトファイルなので、IME制御を行うなら必ずダウンロードすることになる。

スクリプトを解説すると、6行目で”変換”キーをホットキーに、7行目で”無変換”キーをそれぞれホットキーに指定している。

変換/無変換キーをホットキーに指定する場合、キーコードで指定する必要があるので、上記の設定を行う前に、キーコードをAutoHotKeyで調べた。調査画面は次のとおりである。

スクショ3

ここで、変換キーのスキャンコード(SC)が079、無変換キーのスキャンコードが07Bだと分かるので、SC079SC07Bと指定した。そのうえで、変換キーにIMEオンの機能を割り当てるため、IME.ahkに定義されているIME_SET関数を使用した。IME_SET(1)でIMEをオンに、IME_SET(0)でオフにできる。

次に、無変換キーにIMEオフの機能を割り当てるが、私のErgoDashでは、無変換キーがスペースキーの隣の親指担当の場所にあるため、スペースキーと間違えて無変換キーを押すことがしばしばあった。そのため、IMEオンで入力しているときは、無変換キーを押してもIMEをオフにしない設定にした。

そのため、IME_GetConverting関数でIMEの状態を確認し、返り値が1以上(IMEオンで入力中 or 変換中)なら、何もしない(Returnで処理終了)設定にし、それ以外の場合(IMEオンだが入力していない)にIME_SET(0)関数を実行してIMEをオフにする設定にした。

なお、IME_GetConverting関数でIMEの状態が取得できるのは、インラインで入力が行われないアプリだけである。そのため、WordやNotepadのようにインラインで入力が行われるアプリでは、IMEの状態が取得できないので、入力中はIMEをオフにしないという細かい調節はできない。

参考

補足

ちなみに、上記で調査した変換/無変換キーのスキャンコードは、市販のJISキーボードでも同じである。しかし、仮想コードはErgoDashと市販のキーボードで異なっている。

キーの指定は、スキャンコードか仮想コードで行うので、enthumbleは、スキャンコードではなく仮想コードで指定しているか、それともvkXXscYYYという組み合わせで指定しているのではないかと思う。そのため、ErgoDashでは動作しなかったのではないかと思う。

仮想キーコード変換無変換
ErgoDashFFEB
市販品1C1D

IME関連の他の設定

これで最大の懸念であったIMEの切り替えが実現できたが、変換キーにIMEオンの機能を割り当てたので、本来の変換キーが無くなっている。誤入力した箇所にカーソルを置いて変換キーを押すと再変換できる機能は便利なので、Ctrl-BackSpaceに変換キーの機能を割り当てることにする。

BS::Send, {vk1C}

BSはBackSpaceの指定(BackspaceでもOK)で、Sendは、引数に指定したキーをシステムに送信するコマンドである。vk1Cは変換キーの仮想キーコードなので、”Ctrl-BackSpace”を押すと変換キーが送信されるという動作になる。

参考

アプリ毎の設定

AutoHotKeyでは、アプリ毎に設定を行うことも可能である。

次の例は、Excelで行(列)選択のショートカットキーのShift(Ctrl)-SpaceをIMEオンでも動作させるというものである(このショートカットキーはIMEオンだと動かない)。キーボードでExcelを操作するときに必須のショートカットキーなので、IMEオンでも動作するようにする。

#ifWinActive ahk_exe EXCEL.EXE
  $^Space::
    if (IME_GET())
    {
      IME_SET(0)
      Sleep 30
      Send,^{Space}
      Sleep 30
      IME_SET(1)
    }
    else
    {
      Send,^{Space}
    }
    Return

  $+Space::
    if (IME_GET())
    {
      IME_SET(0)
      Sleep 30
      Send,+{Space}
      Sleep 30
      IME_SET(1)
    }
    else
    {
      Send,+{Space}
    }
    Return
#ifWinActive

IME_GET関数やIME_SET関数は、上記のIME関連の設定で説明したとおりIME.ahkで定義されているものである。

1行目の#ifWinActiveは、特定のウィンドウがアクティブの時だけ実行するというコマンドである。ウィンドウの指定はウィンドウタイトルやウィンドウクラスで行うが、ウィンドウタイトルで行うのが簡単だと思う。

ウィンドウタイトルの確認は、AutoHotKeyに備わっている「Window Spy」という機能を使うのがベストである。Window Spyは、右下のタスクトレイにあるAutoHotKeyのアイコンを右クリックしたメニューにあるので、そこから起動する。起動した後の操作方法は以下のスクリーンショットのとおり。

スクショ4

2行目の$^Space::は、”Ctrl-Space”というホットキーを指定するものであるが、行頭に$をつけているのは、”Ctrl-Space”をAutoHotKeyで強制的にフックするためである。システムが使うショートカットキーを上書きする場合に必要となる。

3行目のif (IME_GET())は、IME_GET()の返り値が1、つまりIMEがオンになっているという条件式である。AutoHotKeyは、数値が0ならfalse、それ以外の数値はtrueと処理するので、こういうコードでOKとなる。

5〜9行目はIMEがオンの場合の処理であるが、まず、5行目のIME_SET(0)でIMEをオフにし、続いて6行目のSleep 30で30ミリ秒処理を中断する。この中断処理を除くとIMEオンの状態で”Ctrl-Space”を入力したのと同じ動作になるので、中断処理を行っている。なお、30ミリ秒より短いと上手くいかない。

それから7行目のSend,^{Space}で”Ctrl-Space”を送信し、8行目のSleep 30で再び処理を中断している(この中断処理を省略しても上手く動作しない)。

そして、9行目のIME_SET(1)でIMEをオンに戻している。

11行目のelseは、IMEがオフの場合の分岐で、この場合は、単純に13行目のSend,^{Space}で”Ctrl-Space”を送信している。

17行目の$+Space::は、”Shift-Space”というホットキーを指定するものである。以降の設定はこれまでと同じなので、省略する。

なお、Excelについては、次のような設定も行なっている。説明の都合上2つに分けているが、実際の設定ファイルでは、#ifWinActiveを除いた部分を上記のコードの続きに書いている。

#ifWinActive ahk_exe EXCEL.EXE
  $F1::Return
    $+F1::SendInput, {F1}
#ifWinActive

2行目の$F1::Returnは、”F1″キーを無効化する設定である。以前使っていたキーボードで、F1キーがEscキーの隣にあるためにEscとF1をの押し間違いが頻発していたので、思い切ってF1を無効化したのである。特定のキーを無効化する場合、無効化したいキー::Returnとすることで、そのキーを無効化できる。

なお、F1キーを無効化したが、ヘルプを見たい時があるかもしれないので、$+F1::SendInput, {F1}で”Shift-F1″に元々のF1を割り当てている。

参考

キー2連打への割り当て

キー2連打への割り当て方法は2通りあるので、それぞれ紹介する。

方法1(モディファイヤキーが無い場合)

CtrlやAltなどのモディファイヤキーと組み合わせないキーの2連打の場合、AutoHotKeyの組み込み変数を使うことで簡単に2連打の設定ができる。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Title: テンキーのピリオド2連打でカンマ入力
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
~NumpadDot::
  If (A_PriorHotKey == A_ThisHotKey and A_TimeSincePriorHotkey < 200)
  {
    SendInput, {BackSpace 2}
    Send,{U+002c}
  }
Return

上記のコードを解説すると、まず、~NumpadDot::でテンキーの”.”をホットキーに指定している。行頭に~を追加しているので、”.”の入力はシステムにも渡されて”.”が入力される。

そして、7行目のIf (A_PriorHotKey == A_ThisHotKey and A_TimeSincePriorHotkey < 200)は、組み込み変数を使って、「前回入力されたホットキーと今回のホットキーが同じ」かつ「前回のホットキー入力から今回のホットキー入力までの時間が200ミリ秒未満」という条件文を組み立てている。

A_PriorHotKey変数には前回押されたホットキー、A_ThisHotKey変数には今回押されたホットキーが格納されているので、2つの変数が等しければ同じホットキーを2回連続で入力したと判断できる。そして、A_TimeSincePriorHotkey変数には、前回のホットキー入力から今回のホットキー入力までの時間がミリ秒単位で格納されているので、この変数の値が200未満なら2連打したと判断している。

つまり、最初の”.”入力では、7行目のIf文の条件が必ず満たされず最後のReturnコマンドに直行し、2回目の”.”入力で7行目のIf分の条件が満たされて、次のSend~の処理に移るという訳である。

そして、この段階までに2回入力されている”.”を削除するため、SendInput, {BackSpace 2}コマンドでBackSpaceを2回入力している。それからSend,{U+002c}コマンドで”,”を入力している。なお、{U+002c}は、”,”のUnicodeの文字コードである。わざわざUnicodeの文字コードで指定している理由は、Send,{,}だとIMEがオンの場合に全角の”、”が入力されてしまうためである。

参考

方法2(モディファイヤキーがある場合)

CtrlやAltなどのモディファイヤキーと組み合わせたキーの2連打の場合、上記より面倒になる。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Title: Alt-Qの2連打でアプリを閉じる
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
~!q::
  Input, inputText, I L1 T0.5, !q
  IfInString, ErrorLevel, EndKey:
  {
    Send, !{F4}
  }
Return

最初に掲載した設定例の再掲であるが、解説すると、まず~!q::で”Alt-Q”をホットキーに指定している。

そして、Inputコマンドで最初の”Alt-Q”に続くキー入力を横取りして、inputText変数に格納している。

InputコマンドのI L1 T0.5という引数は、「AutoHotKeyが生成したキー入力は無視、入力を受け付けるキーの長さは1文字、キー入力を待つ時間は0.5秒以内」という条件を指定するもので、!qという引数は、「”Alt-Q”が入力されたらコマンドを終了して次の行に進む」という条件を指定するものである。

その次のIfInString, ErrorLevel, EndKey:は、「ErrorLevel変数にEndKey:という文字列が含まれているか」という条件文である。

Inputコマンドの待ち時間(0.5秒)以内に”Alt-Q”が押されたら、ErrorLevel変数にEndKey:!{q}という値が格納され、0.5秒以内に”Alt-Q”が押されない場合はTimeoutという値が格納されるので、EndKey:が含まれていれば「Alt-Qが2連打された」と判断できる。

そのうえで、Send,!{F4}で”Alt-F4″キーを送信してアプリを終了させている。

参考

クリップボードを活用

クリップボードを活用することで、選択した文字列を”(“や”[“や”#”で囲むということも可能になる。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Title: 選択した文字列を'('等で囲む
Usage: 文字列を選択→ctrl-,を押す→続けて入力した文字で囲む
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
^,::
  backup = ClipboardAll
  Clipboard =
  Send, ^c    
  ClipWait, 1
  imeStatus := IME_GET()
  if ErrorLevel = 0
  {
    Input, inputText, I L1 T1,{Esc}, (,[,`{,',",``,-,_,=,`%,`#,`*, ,|
    If ErrorLevel = Match
    {
      IME_SET(0)
      If inputText = [
      {
        Send,{[}
        Send,^v
        Send,{]}
        Sleep 200
      } 
      Else if inputText = (
      {
        Send,{(}
        Send,^v
        Send,{)}
        Sleep 200
      }
      Else if inputText = {
      {
        Send,{{}
        Send,^v
        Send,{}}
        Sleep 200
      }
      ;スペースは`=`による条件判定ができないため、変数の型で判定している。
      Else if inputText is space
      {
        Send,{Space}
        Send,^v
        Send,{Space}
        Sleep 200
      }
      ;`#`は個別に条件指定しないと動かない
      Else if inputText = `#
      {
        Send,{`#}
        Send,^v
        Send,{`#}
        Sleep 200
      }
      Else
      {
        Send,%inputText%
        Send,^v
        Send,%inputText%
        Sleep 200
      }
    }
  }
  Clipboard = %backup%
  IME_SET(imeStatus)
  Return

8行目のbackup = ClipboardAllは、その時点でクリップボードに格納されているデータをbackup変数に退避させる処理である。ClipboardAll変数は組み込み変数で、クリップボードのデータを読み取る際に使用する。

9行目のClipboard =は、クリップボードを空にする処理である。Clipboard変数も組み込み変数で、クリップボードの中身を書き換える際に使用する。

10行目のSend, ^cで、”Ctrl-C”をシステムに送信して選択中の文字列をコピーするが、コピー失敗に備えて、11行目にClipWait, 1という処理を挟んでいる。ClipWaitコマンドは、引数で指定した秒数の間待機し、時間内にコピーが成功すればその時点でErrorLevel変数に0を格納する。そのため、ErrorLevel変数の値でコピーが成功したか否かが確認できるようになる。

12行目はIME_GET()関数で現在のIMEの状態を変数に格納している。この処理はSendコマンドで囲み文字を入力する方法なので、囲み文字を確実に半角入力するため、一度IMEをオフにする必要がある。そのため、処理実行前のIMEの状態を取得している。なお、関数の戻り値を変数に格納する際は:=で代入する必要がある。

15行目のInput, inputText, I L1 T1,{Esc}, (,[,\`{,',",`,-,_,=,`%,`#,`*, ,|は、前述のInputコマンドを使って、”Ctrl-,”の次に入力された文字が( [ { ` - _ = % # | 半角スペースだった場合に、その文字をinputText変数に格納している。なお、{ ` # % *はAutoHotKeyで特別な意味のある文字であることから、これらの文字を指定する際は`でエスケープ処理する必要があり、また、半角スペースは条件式の途中(この例では|の前)に書かないと認識されないという2点に注意が必要である。

16行目のIf ErrorLevel = Matchは、Inputコマンドで(,[,\`{,',",`,-,_,=,`%,`#,`*, ,|が入力されていればErrorLevel変数にMatchが格納されているので、それを分岐条件にしている。

あとは、18行目のIME_SET(0)でIMEをオフにして、入力された文字に応じた分岐を18行目以降のIf inputText =で行い、

  1. 入力された文字をSendコマンドで送信
  2. Send,^vコマンドでクリップボードの文字を貼り付け
  3. 再び入力された文字をSendコマンドで送信

という処理を行うことで、選択した文字列を指定した文字で囲むという動作を実現している。

工夫が必要な点は、まず、(,[,\`{は、対になる),],\`}とセットで囲む必要があることから、この3つのカッコは個別に分岐条件を設定している。そのほかの囲み文字については、同じ文字を2回入力すればOKである。

また、半角スペースはIf inputText = " "のような条件判定がどうやってもできなかったので、指定した変数のデータ型で判断するif inputText is typeを使って、inputTextが半角スペース(タブもOK)か否かによる条件判定を行なった。

そのほか、なぜか#は個別に条件判定を行う必要があったので、やむなく個別に判定している。

それ以外の囲み文字については、まとめて最後のElse節で処理している。

最後に、IMEの状態を処理前に戻して動作完了である。

参考

設定ファイルの再読み込みを簡単に

設定ファイルを編集した場合、右下のタスクトレイにあるAutoHotKeyのアイコンを右クリックして「Reload This Script」をクリックする必要があるが、非常に面倒な作業なので、設定ファイル再読み込みのショートカットキーを作成する。

/*
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Title: Ctrl-Alt-Rでこのスクリプトを再読み込みする
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
*/
^!r::Reload

最初の方で紹介した設定例の再掲であるが、^!rで”Ctrl-Alt-R”をホットキーとして指定し、現在実行中の設定ファイルの再読み込みを行うReloadコマンドを割り当てている。

参考