AutoHotKey Syntax Problems

Perm url with updates:

AutoHotKey Syntax Problems

Xah Lee, 2010-05-16

The AutoHotKey language syntax are bad, from a pure design point of view. This page gives some examples.

If you add a blank line in the wrong place, it is a compiler error. For a example, the following compiles fine:

;;; make the numpad star “*” key to do next tab
WinGet, myProcName, ProcessName, A
If ( WinActive("ahk_class Chrome_WindowImpl_0")
Or WinActive("ahk_class MozillaUIWindowClass")
Or WinActive("ahk_class gdkWindowToplevel") )
  Send ^{PgDn}
Else If (WinActive("ahk_class IEFrame")
  Or WinActive("ahk_class OpWindow")
or (myProcName = "safari.exe") )
  Send ^{Tab}
Else {
  Send {NumpadMult}

But if the line:

If ( WinActive("ahk_class Chrome_WindowImpl_0")

has a newline after the paren like this:

If (
 WinActive("ahk_class Chrome_WindowImpl_0")

The compiler generates a error.

Following is another example on the newline problem. This is ok:

Else If (WinActive("ahk_class Emacs") 
  Or WinActive("ahk_class Chrome_WidgetWin_0") 
Or WinActive("ahk_class MozillaUIWindowClass") 
Or WinActive("ahk_class gdkWindowToplevel") )

But putting the closing paren in a separate line creates compiler error:

Else If (WinActive("ahk_class Emacs") 
  Or WinActive("ahk_class Chrome_WidgetWin_0") 
Or WinActive("ahk_class MozillaUIWindowClass") 
Or WinActive("ahk_class gdkWindowToplevel")

Syntax Soup

Also, the syntax is quite a syntax soup. e.g.

IfWinActive ahk_class Notepad
IfWinActive, ahk_class Notepad
if WinActive("ahk_class Notepad")
if WinActive("ahk_class" . "Notepad")

are pretty much the same. I still don't quite understand if they are exactly equivalent at the syntax level, or if they are just semantically equivalent, or if they are semantically similar but not equivalent.

Its syntax for keys is also badly designed, with huge amount of special cases. See: AutoHotKey Example Scripts.

For example, to define a combination of key presses, such as “Ctrl+N”, it is like this:

^n::Run Notepad ; this means Ctrl+n

The general form is one of:


However, you can have special meaning characters in front of the key syntax, like this:

$NumpadDiv::Send !{Left}

That dollar sign means if a NumpadDiv press is generated by ahk, don't interpret it in this definition. (useful to prevent infinite recursion)

So, the meaning of the form “‹char›‹key name›” depends on whether if the “char” is a special char for modifiers.

Also, for some commands, you can add a “#” char in front and it became a directive. e.g.

#IfWinActive ahk_class Notepad
#Space::MsgBox You pressed Win+Spacebar in Notepad.

In the above, the “#IfWinActive” is a directive, changing the meaning all lines below. In a C-like syntax, it would be something like this:

If ( WinActive( ahk_class("Notepad") ) ) {
 #Space::MsgBox("You pressed Win+Spacebar in Notepad.")

However, not all commands can become a directive by adding a “#”. Also, some directives, starts with “#” but does not become command without “#”. e.g. “#NoTrayIcon”.

Also note, the prefix of “#” char has multiple meanings depending on what follows. In the above example, the “#Space” is a key syntax, meaning holding the Win Logo key and pressing the Space bar key.

Why It's Lousy

The reason the syntax is lousy is due to the language's history, of course. AHK is a language that evolved out of practical needs. It is a branch off of the AutoIt scripting language. AutoIt is scripting language for task automation for Windows. At the time, the language does not feature defining hotkeys. The AHK author Chris Mallett was a fan of AutoIt, suggested the hotkey feature, but got turned down or got no reaction, so he branched off and started AHK. So, the a key binding syntax is added onto the language. Further, it is safe to presume the keybinding features just got added gradually from practical experimentation, so even the key syntax is quite inconsistent.

I've been learning and using AHK since 2009-08. On average perhaps spending 1 hour per week for the past 10 months. That's a total of 40+ hours. However, i can't see any general principle of the syntax. It seems just a soup of commands, much like unix shells, but worse.

Popular posts from this blog

11 Years of Writing About Emacs

does md5 creates more randomness?

Google Code shutting down, future of ErgoEmacs