Skip to content

Conditional breakpoint

zero-plusplus edited this page Dec 25, 2021 · 28 revisions

This is a variant of a breakpoint that stops the script only if a condition is matched. To learn the basics, look here.

Since this feature does not exist in the AutoHotkey debugger, it is handled by the debugger adapter. Therefore, please note the following limitations.

  • The way to specify conditions is not the pure AutoHotkey language, but a proprietary language
  • It takes a little time to interpret the conditions, so it is not suitable for loops that exceed several thousand. In this case, it is recommended to set the condition in the AutoHotkey script and set a normal breakpoint

Syntax

This syntax is a experimental version and its use is subject to change.

This language is defined by BNF as follows (Same for v2). However, since this is difficult to understand this, so please refer to the rules explained in the following sections for details.

expressions ::= <expression> { <logical_operator> <expression> }
expression ::= <operand> {<comparison_operator> <operand>}
operand ::= [<prefix_operator>] (<value> | <variable>)
variable ::= (<variable_name> { "[" <operand> "]" | "." <variable_name> }) | <meta_variable>
variable_name ::= [\w_#$@]+
value ::= <string> | <number>
regex ::= "/" ("\/" | [^/])+ "/" [<regex_flags>]
regex_flags ::= "g" | "i" | "m" | "s" | "u" | "y"
prefix_operator ::= "countof"
comparison_operator ::= "=" | "!=" | "==" | "!==" | "~=" | "!~" | "<" | "<=" | ">" | ">=" | " is " | " is not " | " in " | " not in " | " contains " | " not contains "
logical_operator ::= "&&" | "||"

Rules

string

The syntax is the same as in AutoHotkey, except that v2 allows strings with single quotation marks.

"string"
'string'

number

The syntax is the same as in AutoHotkey.

123
123.456
0x123
123e+4

variable

The syntax is almost identical to that of AutoHotkey.

variable
object.key
object["key"]
array[1]

object.key["key"][1] ; The above can also be combined to specify deep child elements

Simple dynamic keying can be done using variable.

object[variable]

Expressions are not supported, so the following are invalid.

arr[1 + 2]

regex

Two types of regular expressions are available: AutoHotkey-like regular expressions and JavaScript regular expressions.

The reason it is called AutoHotkey-like is because it is converted to a JavaScript regular expression and executed. Although they have many features in common, they are not fully compatible.

AutoHotkey-like regular expressions. Currently it is only supported on the right side of the ~= operator.

"abc" ~= "i)^A"

JavaScript regular expressions. Currently it is supported on the right side of the ~=, has and contains operator.

"abc" ~= /^A/i

meta_variable

See Meta variable.

prefix_operator

countof

Returns the number of values specified to the right.

The number to be returned depends on the value and is as follows.

  • string, number - Returns the length of a string. This is the same as the StrLen function
  • object, array - Returns the number of elements. This is the same as the count method.
countof "abc"
countof object
countof array

comparison_operator

A number of comparison operators are provided to compare two values. Most are similar to AutoHotkey. There are additional useful operators that it does not have.

The following are the basic comparison operators

a = b                 ; equals (case in-sensitive)
a != b                ; not equals (case in-sensitive)
a == b                ; equals (case sensitive)
a !== b               ; not equals (case sensitive)
a ~= b                ; regex match
a !~ b                ; not regex match
a < b                 ; less than
a <= b                ; less than equals
a > b                 ; greater than
a >= b                ; greater than equals

is operator

The is operator determines whether or not the left-hand side is related to the right-hand side.

Basic type check

The following is a basic type check.

a is "undefined" ; Determines whether a variable is uninitialized or not
a is "string"    ; e.g. "abc"
a is "number"    ; e.g. 123, 123.456, 0x123 or 123e+4
a is "integer"   ; or "int". e.g. 123
a is "float"     ; e.g. 123.456
a is "primitive" ; Determine whether it is a string or a number
a is "object"    ; e.g. {}, [] or any other object

Additional type check

To apply more detailed determination, follow : with a word, as follows.

a is "string:alpha" ; same as `a ~= "^[a-zA-Z]+$"`. e.g. "abc"
a is "string:alnum" ; same as `a ~= "^[a-zA-Z0-9]+$"`. e.g. "abc123"
a is "string:hex"   ; same as `a ~= "^0x[0-9a-fA-F]+". e.g. "0x123"
a is "string:upper" ; same as `a ~= "^[A-Z]+$". e.g. "ABC"
a is "string:lower" ; same as `a ~= "^[a-z]+$". e.g. "abc"
a is "string:space" ; same as `a ~= "^\s+$"`. e.g. " "
a is "string:time"  ; e.g. "01 Jan 1970 00:00:00 GMT"

a is "number:like"   ; e.g. "123", "123.456", "0x123", "123e+4"
a is "integer:like"  ; or "int:like". e.g. 123, "123"
a is "float:like"    ; e.g. 123.456, "123.456"

a is "object:CLASSNAME" ; This is explained as follows

The above a is "string:time" is realized by Data.parse, so please check there.

The CLASSNAME in a is "object:CLASSNAME" can be checked by looking at the value of the Data inspection. Note that this is internal data of the AutoHotkey debugger and does not necessarily match the __class property that the instance has.

To invert the above result, use after is with not.

a is not "string"

in operator

Determines whether the right-hand side has the key specified in the left-hand side. This includes inherited keys.

"key" in object

To invert the above result, before in with not.

"key" not in object

has operator

The behavior is the same as haskey.

Specify an object on the left side, and a primitive value (or a variable holding it) or a JavaScript regular expression on the right side.

object has key
object has "key"
object has /key/i

To invert the above result, use after has with not.

object has not "key"

contains operator

Searches for the value of a variable. The inherited values will not be searched.

Specify an object on the left side, and a primitive value (or a variable holding it) or a JavaScript regular expression on the right side.

object contains value
object contains "value"
object contains /value/i

To invert the above result, before contains with not.

object not contains "value"

logical_operator

This operators is same AutoHotkey. Note, however, that parentheses are not supported, so they are always interpreted from left to right.

a == b && countof c == 3
a == b || c == d