テンキーNを押すと直前に入力したキーをN回連打する AutoHotkey スクリプト
スペースとか Backspace とかカーソルキーとか、連打する機会はちらほらあるけど、だるい時があるので楽できないかなと考えて、「直前に押したキーを N 回連打する」 というアイデアはどうか、とひらめいた。んで、形になったのがこんなの。
以下、細かい解説とかだらだらと。
これは何?
たとえばスペースを押した後にテンキー8を押すと、スペースが8回連打される。「→」を押した後にテンキー4を押すと、「→」が4回連打される。
そんな感じのブツ。
成果物
GitHub にアップしたのでそちらを。
英語圏にも訴求したいので(下手だが)英語にした。あと名前は Stroke(キー入力) を Clone(複製する)、というところから名付けた。
スクリプトはどんな感じ?
こんな感じ。
priorkey := A_PriorKey Numpad1:: push_priorkey(1) Return ; ...中略... Numpad9:: push_priorkey(9) Return push_priorkey(count){ global priorkey old_priorkey := priorkey priorkey := A_PriorKey is_numpad_found := InStr(priorkey, "Numpad") if(is_numpad_found){ priorkey := old_priorkey } Loop %count% { SendEvent {%priorkey%} } }
スクリプト解説
(1) 繰り返し入力の実現
どうやって実現したのかというアイデアを解説する。
まず必要となるパーツは以下三つ。
Numpad1:: ; テンキー1を押した時に実行する処理をココに書く Return
; 直前に押されたキー内容が入っているシステム変数 A_PriorKey
; Spaceを入力する SendEvent {Space}
これらを組み合わせれば表題を実現できそうだが、一点厄介なのが 一度テンキーを入力すると A_PriorKey の中身がテンキーになってしまう こと。これのせいで、たとえば space → テンキー8 → テンキー8 と押しても space が16回入力されない(1回目のテンキー8を押した時点で A_PriorKey がテンキー8 になってしまう)。
どころか、内部的には「テンキー8を押したら A_PriorKey(この中身がテンキー8) を Send する」という 無限再帰呼び出し になってしまい、そのうちスクリプトがエラーを出してしまう。
これを回避するために、以下のようにした。
- A_PriorKey の値を別のグローバル変数にもたせておく(例: priorkey)
- 二つ前に入力されたキーも保持しておく(例: old_priorkey)
- SendEvent を行う前に priorkey の中身を見て、 もしテンキー系が入っていたら場合は priorkey の中身を old_priorkey にする
つまり「テンキーを A_PriorKey の対象から外す」処理を強引に実現した。
(2) その他必要な設定について
スクリ序盤で定義してるやつら。
#SingleInstance force
これは多重起動を防止するオプション。厳密に言うと「後から起動された場合、前に起動してた分を 強制的に(Forcely) 終了させる」という挙動になる。
#Persistent
これは「(スクリプト最後まで実行したら終了するのではなく)常駐してね」というオプション。
#KeyHistory 20
これは「入力されたキー情報をどこまで記録するか」という値。A_PriorKey 変数は、この key history 機能が有効じゃないと使えなかったりする。
この key history は keydown(キーを押し込む) と keyup(キーを離す) をそれぞれ 1 件として記録するので、「一つ前のキー」情報がほしければ最低でも 2 が必要となる……と思ったんだけど、 2 だと動作しなかったのでテキトーに 20 くらいにしといた。
#InstallKeybdHook
これは「キーボードフック」とかいう機能を有効にするオプション。詳しいことはよーわからんが、AutoHotkey ではキーボード絡みで色々複雑なことをしており、そのために「キーボードフック」なる専門的な処理が必要みたいで、このオプションはその「専門的な処理を使ってもいいですよ」ってのを指定している。おなじないみたいなもん。