AutoHotkeyを使えば()や「」を一発で簡単に入力できるのは皆さんご存知の通り。例えば、
vk1C & 8::
Send, ()
Send, {Left}
Return
一番簡単なのはこんな感じ。変換+8をトリガーとして、“()”を出力した後、カーソルが()内に移動します。でもこれじゃ動作の安定性に欠け、全く実用的ではありません。ならこれは?
vk1C & 8::
backup := ClipboardAll
ClipWait, 2
Clipboard := "()"
ClipWait, 2
Send, ^v
Sleep,60
Clipboard := backup
Send, {Left}
Return
なるほど。クリップボードや変数を使えば、出力する文字やIMEの状態に関わらず、毎回同じ文字を出力できます (Clipboardなどのコマンドについては以下で解説しています)。
じゃあカギ括弧“「」”を出力したいときは? 別のホットキーを作る?
それもアリですが、例えばIMEがONのときに“「」”を出力し、IMEがOFFのときは“()”を出力する。こんな動作ができればどうでしょう。
今回はAutoHotkeyの原点に立ち返って、文字出力スクリプト。特に「IME.ahk」というライブラリによって、IMEのON/OFFを動作のスイッチとして使ってみたいと思います。
IME.ahkの使用方法
ダウンロードと配置
AutoHotkeyでIMEの状態を取得するのに便利なライブラリがIME.ahkです。ライブラリとは簡単に言えば、「誰かが作ってくれた、誰もが使える関数など」のこと。ありがたく使わせてもらいましょう。
上のページからダウンロードできます。「Code」をクリックして、プルダウンメニューから「Download ZIP」を選択します。
ダウンロードしたファイルを解凍。今回使うのは「ime.ahk」のみ。
このIME.ahkファイルを移動します。AutoHotkeyのフォルダの中に「Lib」という名前のフォルダがあればそこに、無ければ新しく作って、その中に入れてください。
Libフォルダが常駐プログラムと同じディレクトリに置かれている状態にします。
AutoHotkeyフォルダ
├── Libフォルダ
│ ├── IME.ahk
└── main.ahk (常駐プログラム)
こうすることによって、include文無しでもこのライブラリを利用することができます。
IME.ahkの関数
IME.ahkにはIMEに関する関数が全部で7種類定義されています。
関数名 | 働き |
---|---|
IME_GET() | IMEのON/OFFを取得する |
IME_SET(SetSts) | IMEのON/OFFを設定する |
IME_GetConvMode() | かな/ローマ字/半英数などの入力モードを取得する |
IME_SetConvMode(ConvMode) | 入力モードを設定する |
IME_GetSentenceMode() | 一般/話し言葉などの変換モードを取得する |
IME_SetSentenceMode(SentenceMode) | 変換モードを設定する |
IME_GetConverting() | 変換候補が出ている/変換中など、文字入力の状態を取得する |
今回使うのは、この中でも最も基本的なIME_GET()
とIME_SET()
です。
IME_GET(WinTitle="A")
;引数は省略可能
;戻り値はIMEがONなら1、OFFなら0
IME_SET(SetSts, WinTitle="A")
;第一引数のみ必須。ONにするなら1、OFFにするなら0を渡す
;戻り値は成功なら0、失敗なら0以外
動作確認
ファイルを移動させたら、一度簡単なコードで動作確認してみましょう。このコードはmain.ahkに記述してください。
vk1C & 8::
ans := IME_GET()
MsgBox,,, %ans%
Return
正常に動作していれば、IMEがONのときに変数ans
は1となり、OFFのときは0になるはずです。
こんな風にIMEのON/OFFでダイアログの数値が変わればOK。
コードに組み込む
これらの関数を使ってIfで分岐させれば、今回の目的は達成できそうです。冒頭のコードを改良してみましょう。main.ahkを更新します。
vk1C & 8::
If (IME_GET() == 0){ ;IME_GETの結果が0のとき (IMEがOFFのとき)
backup := ClipboardAll
ClipWait, 2
Clipboard := "()" ;()をクリップボードに入れる
ClipWait, 2
Send, ^v ;ペーストして出力
Sleep,60
Clipboard := backup
Send, {Left} ;カーソルを1つ左に移動
IME_SET(1) ;IME_SETでIMEをONにする
}else{ ;IME_GETの結果が0でなければ、
backup := ClipboardAll
ClipWait, 2
Clipboard := "「」" ;「」をクリップボードに入れる
ClipWait, 2
Send, ^v
Sleep,60
Clipboard := backup
Send, {Left}
}
Return
11行目のIME_SET
は不要なら削除してOKですが、大体こんな感じ。
これで処理的には問題無いはずですが、しかしこのコード、なんだか無駄に長くありませんか?
処理の関数化
上のコードで行数が膨らんでしまうのは、似たような処理が2回繰り返されているためです。
この処理の部分を「関数」として別ファイルに切り出し、後は呼び出すだけという状態にしておけば、常駐ファイルのコードをスッキリ整理することができます。
関数ファイルの作成と配置
ということで関数用のファイルを新たに作成しましょう。
ファイル名はある程度自由ですが、名前だけで何をする関数か分かるようにしておくのが鉄則です。ここでは「SendBrackets.ahk」という名前で新規ファイルを作ります。
この関数ファイルもいちいちinclude文を書きたくないので、先ほど使用したIME.ahkと同じ「Lib」フォルダに配置してください。
AutoHotkeyフォルダ
├── Libフォルダ
│ ├── IME.ahk
│ └── SendBrackets.ahk (関数ファイル)
└── main.ahk
関数宣言のコード
そしてこれが関数ファイルの中身。コピペでOKですが、関数の名前はファイル名と同じにしましょう。
;1つの引数を取り、その引数を出力して、カーソルを左に1つ移動する関数
SendBrackets(arg){
backup := ClipboardAll
ClipWait, 2
Clipboard := arg
ClipWait, 2
Send, ^v
Sleep,60
Clipboard := backup
Send, {Left}
}
またVisual Studio Codeなどのテキストエディタを使う場合、ファイルの文字エンコードには注意です。今回のコードに限らずですが、「With BOM」で保存しないと文字化けしてしまいます。
関数を呼び出すコード
最後の手順。作成した関数をmain.ahkから呼び出します。
vk1C & 8::
If (IME_GET() == 0){
SendBrackets("()")
IME_SET(1)
}else{
SendBrackets("「」")
}
Return
動作自体は関数を使わなくても同じことです。しかし処理部分を関数として別ファイルに移動することによって、main.ahkの行数が大幅に削減できています。
関数呼び出しの()
内が実際に出力する文字列。この部分を変更するだけで『』や<>など、様々な文字に応用しやすくなるのも関数の良いところです。
リロードして実行しましょう。IMEがONのときは「」を出力し、IMEがOFFのときは()が出力され、IMEがONになります。