rcmdnk's blog
Last update

20130723_AutoHotKey_200_200

AutoHotkey v2 に対応した vim_ahk のリリースを行いました。

vim_ahk

vim_ahkはAutoHotkeyを使ってVim風のキーバインドをWindows上のいたるところで使えるようにするスクリプトです。

AutoHotkey v2

2年ほど前にAutoHotkey v2が正式リリースされ、2023年初頭にはv2の方がプライマリーバージョンとして推奨されるようになりました。

変更点が結構ある上にv1がすぐに使えなくなるわけでもないので、自分の別のスクリプトも含めてv2に移行するのが面倒でしたが、 だいぶ前に自分で作るだけ作ってたIssueに「いつ出来るの?」と待ってくれてる方がいたので久々にAutoHotkeyを勉強しながらやってみることに。

v2への移行

AutoHotkeyは2003年頃にリリースされた古いソフトウェアですが、当初ドキュメントもあまりなく、特に日本語などは有志によるものなどが色々ありました。

10年位前でも良くまとまってるものが少なかったこともあり自分でもまとめたりしていました。

現在はかなり整備されていて、v1からv2への移行についても詳しく書かれています。

Changes from v1.1 to v2.0 AutoHotkey v2

かなり大きく変わっているので、これをパット見てすぐに移行するのは難しいですが、 実際にv2として動かしてエラーを見て、エラー箇所について上のドキュメントで探して、という感じでやっていけばほとんどなんとかなるかと思います。

ざっくりでもいいからとりあえず簡単に移行したい、という場合には 移行用のツールを作ってくれてる方もいるので、それを使うのもいいかもしれません

追記: 2024/10/02

このツール最初に使おうとしたら、自分の環境に入っているAutoHotokeyがv2.0.0のv2の古いバージョンでエラーが出て使えないじゃないか、と思ってましたが最新のv2.0.18を入れ直したら動きました。

v2.0.11あたりで結構大きな変更が入った(?)

追記ここまで

mmikeww/AHK-v2-script-converter: AHK v1 -> v2 script converter

特に細かいことを気にしたくなければ一旦これで変換して、その後にエラー箇所を修正していく、というのがてっとり早いかと。

v1/v2の切り替え

現状、AutoHotkey v2をインストールするとv1も同時にインストールされるようになっています。

適当なスクリプトを実行すると、v1/v2のどちらかでしか実行できないものだけが含まれる場合は自動判別で実行できるバージョンで実行されます。

例えば

1
2
3
4
#If
a::
    MsgBox, a
    return

とかならv1,

1
2
3
4
5
#HotIf
a::
{
    MsgBox("a")
}

ならv2で自動的に実行されます。

一方、どちらでも実行できる、もしくは混ざってしまってどちらでも失敗するようなスクリプトで判別不能な場合は 最初にどちらを使うか、の選択ウィンドウが出てくるようになっています。

また、スクリプトの先頭に

1
#Requires AutoHotkey v2.0

のようにバージョンを指定すると必ずそのバージョンで実行されるようになります1

v2でテストするためにとりあえずこのv2.0指定をして実行してエラーが出た箇所を直していく、という作業が基本です。

主な大きな変更点

たくさん変更があるので詳しくは Changes from v1.1 to v2.0 を参照ですが、 とくに気になった変更点をいくつか。

Hotkeyがラベルではなく関数に

AutoHotkeyでまず行うのが

1
a::b

といったHotkeyの設定ですが、複数行で

1
2
3
4
a::
    MsgBox a
    Send b
    Return

みたいに書くことがv1では出来ました。

この書き方をラベル表記と呼んでいるみたいです。

一方、v2ではこのラベル表記が廃止され、関数表記に変わりました。 (MsgBox, Sendもコマンドから関数に変わって書き方が変わっています。)

1
2
3
4
5
a::
  func(hk){
    MsgBox(hk)
    Send("b")
  }

引数のhkは入力のHotkey(この場合はa)が入ります。

関数名を省略して

1
2
3
4
5
a::
  {
    MsgBox(hk)
    Send("b")
  }

のように書くことも出来、この場合入力キーはA_ThisHotkeyで取得できます。(これはv1のラベル表記でも使える。)

この書き方はv1.1.20から使える様になってv2以前では括弧だけ使うか、関数の引数無しで

1
2
3
4
5
a::
  func(){
    MsgBox, % A_ThisHotkey
    Send b
  }

のように定義して入力キーはA_ThisHotkeyで取得する、という形でした。

1行で書く場合にはv2でも

1
a::b

のように括弧なしでも書けます。

また、

1
2
3
4
5
6
a::
b::
  {
    MsgBox(A_ThisHotkey)
    Send("c")
  }

のように、複数のキーに同じ処理を割り当てることが出来ます。

同じようなことはv1でも出来ますが、v1だとラベル表記として

1
2
3
4
5
6
7
8
a::
b::
  MsgBox, % A_ThisHotkey
  Send d
c::
  MsgBox c
  Send e
  Return

のように書くとa, bを押すとそのHotkeyの表示とdが送られ、さらにcの表示とeが送られます。

これは複数行で書く場合にはReturnが来るまで途中にキーラベルがあっても継続して処理が行われるためです。

v2だとこういった重ねがけはできないので、A_ThisHotkeyを使って処理を分けたりする必要があります。

ただ、このReturnを忘れて処理がおかしくなったりすることもあったので より明確に処理を分けることが出来るようになった、という感じはします。

#If -> #HotIf

特定の条件下でHotkeyを有効にするためにv1では#Ifを使っていましたが、v2では#HotIfに変わりました。

#IfWinActiveなどはなくなり、 #HotIf WinActive(...)のように条件部分を分けてかくようになりました。

HotIfWinActiveなどもはありますが、これらは上のような::を使ったHotkeyではなくHotkey関数をつかった定義のための条件分岐として使われます。 それらは特に動的にHotkeyを変更するときに使われるものです。

HotIf / HotIfWin… - Syntax & Usage AutoHotkey v2

単純なHotkey設定だけであれば上のHotkeyの関数化とこの#HotIfへの変更を行えば大概動くはずです。

変数代入

v1では=および:=で変数に代入できましたが、v2では:=のみになりました。

v1だと

1
2
3
4
5
a := "abc"   ;1
a := abc     ;2
a = "abc"    ;3
a = abc      ;4
a = %abc%    ;5

とするとそれぞれ

  1. abc
  2. 変数abcに入っていた値
  3. “abc” (“も含む)
  4. abc
  5. 変数abcに入っていた値

といった代入になっていました。

/blog/2013/07/29/computer-windows-autohotkey/#%E5%A4%89%E6%95%B0/

v2では3, 4 ,5はできなくなります。 一般的なプログラミング言語の代入を:=で行うようになった形です。

v2では全体的に曖昧な書き方が削除されてわかりやすくなっています。

また、v1だと

1
abc :=

のようにすると空文字列が代入されていましたが、v2ではエラーになります。

1
abc := ""

のように明示的に空文字列を代入する必要があります。

文字列の扱い

v1では

1
2
3
4
5
6
7
abc := "123"
a ::
{
    MsgBox abc xyz
    MsgBox %abc% xyz
    MsgBox % abc "xyz"
}

とするとそれぞれ

  • “abcxyz”
  • “123xyz”
  • “123xyz”

といった結果になりました。何もつけないと文字列として理解され、%囲むと変数として理解されました。 さらに% で始めるとなにもないものは変数として扱われ"で囲むと文字列として扱われました。

この辺もあまり他では見ないものでややこしくなる一員でしたが、v2では% という表記は削除され、基本全てが% で始まった状態として扱われるようになっています。

1
2
3
4
5
abc := "123"
a ::
{
    MsgBox abc "xyz"
}

123xyzと表示されます。

これに関連して

1
a::Send {Enter}

のように書きましたが、v2では

1
a::Send "{Enter}"

のように"で囲む必要があります。

SendはHotkeyの設定で比較的よく使うと思うのでこの変更が必要となる部分は多いかもしれません。

コマンドは全て関数に

上のMsgBoxSendのようなものはv1ではコマンド扱いでしたが 関数となり、書き方が変わっています。

Changes from v1.1 to v2.0 AutoHotkey v2

v1では

1
2
3
4
5
a::
{
    MsgBox abc
    MsgBox, abc
}

のようにコマンド直後に,をつけても付けなくてもよかったのですが、v2では 関数ではあるが関数の引数の両側の括弧を省略して書くことができる、という形なので、 関数名直後に,をつけるとエラーになります。

1
2
3
4
5
6
a::
{
    MsgBox "abc"
    MsgBox("abc")
    MsgBox, "abc" ; これはエラー
}

これもSendでも同様で直す部分は結構あるかもしれません。

また、関数化に伴い、引数の順序が変わったりもしています。

MsgBoxだと

1
2
MsgBox , Text
MsgBox , Options, Title, Text, Timeout

という書き方だったものがv2では

1
2
MsgBox Text, Title, Options
Result := MsgBox(Text, Title, Options)

のように。

MsgBox - Syntax & Usage AutoHotkey v1

MsgBox - Syntax & Usage AutoHotkey v2

もう一つ大きな変更は関数化により返り値が出るようにあんったので、 これまで取得したい値を引数に渡して取り出すような形だったものの多くが返り値として取得できるようになりました。

また、KeyWaitなど一部の関数では実行後にErrorLevelという値を見ることで 処理の成否を判断するようになっていましたが、これも関数化により返り値として取得できるようになりました。

MsgBoxTimeoutも返り値として取得できるようになっています。 また、MsgBoxではv1ではIfMsgBoxというコマンドを使って押されたボタンを判断していましたが、 これも返り値に入ります。 タイム・アウトすればtimeout、それ以外ならOKなど押されたボタンの情報が入ります。

設定項目の変更

  • #NoEnvは削除(NoEnvな状態がデフォルトに)
  • #UseHook On #UseHook True (On/OffからTrue/Falseに変更)
  • #InstallKeybdHook InstallKeybdHook (#コマンドから関数に変更)
  • #HotkeyInterval 2000 A_HotkeyInterval := 2000 (#コマンドから変数に変更)

など、設定項目も変わっています。

Gui周り

かなり変わってます。

ボタンを押したときの動作などをg-labelという形でgCancelのようにオプションに追加すると Cancelというラベルが呼ばれるようになっていましたが、 v2では作られたオブジェクトに対してOnEventという関数を使ってイベントを設定するようになりました。

また、似たようにvをつけるオプションでvMyVarをオプションに加えるとMyVarというglobal変数に そのコントロールの値が入るようになっていましたが、 v2ではvMyVarのようにvをつけるオプションは残っていますがこれは単にそのコントロールの名前を指定するだけのものになっています。

コントロールでの値の取得はそのコントロールユニットのValueプロパティを使うようになっています。

その他いろいろな変更がありますが、 この辺り、もともとあったものを書き換えようと思うとかなりややこしいのですが、 v2からの学び始めるのであればv1の書き方を覚えるよりも素直に理解できるようになってると思います。

Gui Object - Methods & Properties AutoHotkey v2

vim_ahkのv2対応

以下のPRにまとめてあります。

Ahk v2 by rcmdnk · Pull Request #101 · rcmdnk/vim_ahk

なるべく細かく一つ一つの変更に対応してcommitは分けてあります。

v2の(もしくはv1のときにすでにアップデートで入っていた)書き方によってより良く出来そうな部分はまだあると思うので また改善していきたいと思います。

現状、v1だったときに出来たことは全て出来るようになっていると思っていますが、 もし何か不具合があればIssueなどで報告していただけると助かります。

自分のv1スクリプトの中で使いたい場合は v0.13.2などのv0.13.X以前のものかahk_v1 branchのものを使ってください。

Sponsored Links
Sponsored Links

« Win/Macそれぞれで特定のウィンドウを最前面に固定する shell-logger: シェルスクリプトのロガーツールにファイル出力機能を追加 »

}