[Autohotkey]一つのキーに対して、単独で押した時と他のキーと組み合わせて押した時の挙動を変える

Keyboard

こんにちは。
泡アハです。

私は別の記事でも書いた通り、キー配列をがちがちにカスタマイズしています。
windows,mac,linuxでキー配列を変更していますが、
唯一Autohotkeyだけは少し癖があります。

karabiner(mac用), xremap(linux用)では、設定ファイルに単体押しとキーコンビネーション時に押し続けた場合の役割を定義することができます。

例:xremapの場合(Space単体押し=Space, 押し続けたとき=CapsLock)

modmap:
  - name: Global
    remap:
      Space:
        held: CapsLock
        alone: Space

※xremapは、設定ファイルを簡潔に書くことができ、なおかつ後から見返した場合にわかりやすくて個人的に好きです。

そんな中でAutohotkeyでも、一つのキーに対して、単独で押した時と他のキーと組み合わせて長押しした時で、それぞれ異なる機能を割り当てたかったのですが、解決策をみつけたので、共有します。

同じようにAutohotkeyで単体押しとキーコンビネーション時の場合分けをしたい方がいれば、ご参考いただければと思います。

なお、本スクリプトは、Autohotkey ver2で実装しています。
おそらくver1.0でも書き方を工夫すれば同じことはできると思いますが、この点ご注意ください。

結論

例:

Spaceキー単体押し = Space
Space + i = up

としたい場合、以下のようなスクリプトで実現できます。

SinglePress(lastkey, sendkey) {
    KeyWait lastkey
    If (A_PriorKey = lastkey)
    {
        Send sendkey
    }
    return
}

Space:: SinglePress("Space", "{Space}")
~Space & i::up

解説

SinglePress

概要

SinglePress(lastkey, sendkey) {
    KeyWait lastkey
    If (A_PriorKey = lastkey)
    {
        Send sendkey
    }
    return
}

Space:: SinglePress("Space", "{Space}")

このスクリプトでは、スペースキーが押されてすぐには何も実行せず、スペースキーが離されるまで待つ動作を行います。
その後、最後に押されたキーがスペースキーだった場合(つまり、他のキーとのコンビネーションではない場合)、スペースキーが押されたことをシミュレート(再送)します。

引数

SinglePressには、lastkeyとsendkeyを引数に受け取りますが、それぞれ以下のような意味となっています。

引数名 意味
lastkey 最後に押されたキー
sendkey 単押しだった場合に送信するキー

なぜlastkeyとsendkeyをわけているかというと、Alt+Spaceのようにキーコンビネーションを制限したいケースを考慮したからです。
Alt + Spaceは、コマンドランチャーを起動したいけど、Alt + Space + iの場合、Alt + upとして動いてほしいというときに有効です。

!Space:: SinglePress("Space", "!{Space}")

私の場合、VSCodeでAlt + Space + iでAlt + up(行の移動)を実現したかったのですが、

~Space & i::up

とだけ設定しても先にAlt + Spaceが先に動いてしまうため、SinglePressを使うとやりたかったことができるようになります。

要点

このスクリプトの肝は、

    KeyWait lastkey
    If (A_PriorKey = lastkey)

の部分です。
単押しかどうかを判断するために

KeyWait "Space"

で、スペースキーが離されたかどうかを検知し、

If (A_PriorKey = "Space")

最後に押されたキーがスペースキーだった場合(つまり、スペースキーが単体で押された場合)に条件を満たして、Send sendkeyするという仕組みになっています。

まとめ

いかがでしたでしょうか?

Autohotkeyは、ほかのキーバインドツールにくらべ、スクリプトで記述する分、自由度は高いですが、その分難易度も高いと思っています。

とはいえ、マスターすれば、強力なツールになることは間違いないと思いますので、
ぜひこの記事を参考に素晴らしいキーボードライフを楽しんでください。

コメント

  1. kcode より:

    Spaceキー単体押し = Space
    Space + i = up
    ということであれば

    *Space Up::{
    if A_PriorKey = “Space”
    Send “{Blind}{Space}”
    }

    Space & i::Up

    のように書くこともできますね。
    Spaceの押し上げで発火するイベントを記述し、押し上げる前のキーがスペースならSendで送るというロジックです。
    *は同時押し(Shift Spaceなど)でも発火させる設定。{Blind}は同時押しをそのまま({Space}だけを書いていたらShiftなどは解除されてしまう)送る設定です。

    AHKは押し下げ・押し上げでイベントを無制限に設定できる分、色々なやり方があるなーと思いながら拝見させていただきました^^

タイトルとURLをコピーしました