This document has been translated by DeepL Translator.
- Overview
- Attention: Use in Games
- Notes
- Support for developer
- Installation
- Docs
- Common settings
- Advanced Docs
CustomHotkey is a library for AutoHotkey that can define complex hotkeys (or simulate remap) with extensible Action and Condition.
Before using this library, you need to learn about hotkey.
Currently, only AutoHotkey v1 is supported. I will start working on v2 when the library specification is finalized.
Since anti-cheat systems may recognize AutoHotkey as a cheat (even if you are not abusing it), I strongly recommended that you always exit it before playing games with online elements.
If you want to exit all running AutoHotkey scripts, use ExitAllAction.
This library is under development. The specifications are not yet finalized and may be subject to destructive changes in the future.
The version under development takes the form 0.x.y
, where x
represents a destructive change and y
a non-destructive change.
If you want to see the changes, please see CHANGELOG.
Some of the Actions in this library use tricky processing to implement their features.
For example, the ExtraPressCombiAction, which defines a hotkey with three or more keys, temporarily blocks user input and changes the priority of other hotkeys to the lowest.
While these tricky processes are necessary to implement the feature, they have the disadvantage that they will not be undone if the Action is not completed successfully.
Although the system is designed to prevent such problems from occurring, these problems cannot be completely solved because there are some bugs that I cannot control, such as misjudgment of key input.
Therefore, please keep in mind the following workarounds. If you remember these solutions, you will not be stuck in an inoperable state.
Basically, all you need to do is to register a hotkey for forced termination as described next.
Register a hotkey for forced termination as follows to recover from an inoperable state.
You are free to assign any key, however, be sure to specify the F
option of Trigger.
; RShift(>+), RCtrl(>^)
new CustomHotkey(">+>^Esc|F", "{Exit|R}Exit {A_ScriptName}")
; It would be useful to be able to restart the script
new CustomHotkey(">+>^F5|F", "{Reload|R}Reload {A_ScriptName}
Execute this shortcut and the Winlogon
screen will appear.
During this time, the AutoHotkey process is disabled, so you can recover from the inoperable state by restarting the PC or using the Task Manager or other means from the menu.
It also has the effect of forcibly unblocking user input by this library. If not unblocked, it may be unblicked by executing this shortcut key multiple times.
Executing this shortcut will launch the Task Manager
.
AutoHotkey is disabled when the Task Manager is active, so it may be possible to recover from the inoperable state. If you are able to recover, you can use the task manager to force AutoHotkey to terminate.
If the script is running in elevated status, it may not be possible to recover because auto-input is not disabled.
If you like this library, I would appreciate it if you would support it with donation/sponsorship.
The development is created as a personal hobby, and I do not accept pull requests. Instead, I accept feature requests and bug reports at Issues.
-
Download the installer of AutoHotkey. Even if you have already installed it, recommend reinstalling it to make sure the following option is set
-
Run the installer and a window will appear. At this time, MUST check the
Default to UTF-8
in theoptions
tab to install -
Download the this library at here
-
Then place the library in a folder of your choice and include it in your scripts using the #Include directive
CustomHotkey has features, but the first one you need to learn is the CustomHotkey Interface described next.
Next you will learn about Trigger and Action.
For Actions, enough to know how to use SendAction first. Not necessary to understand everything.
Then learn about define hotkeys for each window (application) using Condition.
After you understand the above basics, learn how to define more complex and flexible hotkeys by learning the remaining Actions, Combination Actions, Template, etc.
If you don't know how to use it, you can ask questions in Discussion (GitHub account required).
When describing function and method signatures in this document, TypeScript-like syntax is used to express argument and return types.
funcOrMethodName(arg1: type1, arg2: type2 | type3) => resultType
The non-object types that appear in this document are as follows.
- string : A string
- number : A number
- boolean : A boolean. i.e.
true
orfalse
- time : A number or string representing time
The following is the syntax for object types.
; Object
{ [key: keyType]: valueType }
; Array
[ valueType1, valueType2, valueTypeN... ]
If { [key: string]: string }
, it represents an object with a string key and a string value. And if [ string, number, boolean ]
then array[1]
represents a string, array[2]
a number, and array[3]
a boolean.
If multiple types are accepted, they are separated by |
, such as string | number
.
Trigger and some Actions can specify option string such as "T1s R"
. Options are expressed in the following syntax: R
is used by itself and T1s
is used to specify a value.
Options are expressed in the following syntax.
; <TYPE> is optional
OPTION<TYPE>
For example, if described as T<time>
, it can be specified as "T1s"
, "T1000"
, and so on.
CustomHotkey is provided as a class. The constructor takes Trigger as its first argument, Action as its second argument, and Condition as the optional third argument, and returns an instance.
In the following example, press b
if notepad is active, otherwise enter the a
key.
hotkeyInstance := new CustomHotkey("RCtrl & 1", "a")
hotkeyInstance2 := new CustomHotkey("RCtrl & 1", "b", "ahk_exe notepad.exe"))
hotkeyInstance.register()
hotkeyInstance2.register()
This instance has the following methods.
register() => this
: Register a hotkeyon() => this
: Enable a hotkey. If not yet registered, callregister
off() => this
: Disable a hotkey. If not yet registered, callregister
toggle() => this
: Toggle enable/disable a hotkey. If not yet registered, callregister
setState(state: boolean | -1 | "On" | "Off" | "Toggle")
: Set enable/disable state of a hotkey. Set the following values forstate
. If not yet registered, callregister
true
,1
,"On"
: Enable the hotkeyfalse
,0
,"Off"
: Disable the hotkey-1
,"Toggle"
: Toggle enable/disable the hotkey
setEnableBuffer(enabled: boolean) => this
: Set a Action to be taken when the limit on the number of threads set in #MaxThreadsPerHotkey is exceeded. Iftrue
, execution will wait until the number of threads is below the limit, and iffalse
, execution will be canceledsetMaxThreads(max: number) => this
: Set number of threads that can run simultaneously (pseudo-multithreading)setPriority(priority: number) => this
: Hotkey Thread PrioritysetInputLevel(level: number) => this
: Set a priority of #InputLevelsetFreeze() => this
: It will no longer change the state of this hotkey from the library. Also, use thesetPriority
method to set the highest priority. Some Actions disable hotkeys during execution, so use them for important hotkeys that should not be disabled, such as Force ExitsetOptions(options: string) => this
: Change options in the form of hotkey command such as"B1 T1"
The on
method can be used in place of the register
method. Also, since these methods return the instance itself, you can register a hotkey with a single line as follows.
hotkeyInstance := new CustomHotkey("RCtrl & 1", "^{a}").on()
If you simply want to register a Remap that replaces one key with another, use the CustomHotkey.Remap
class. This class has the same interface as CustomHotkey
.
The first argument is the key name you want to change, and the second argument is the key name after the change. The optional third argument is Condition.
See here for the key name.
The following special key names will not work.
AltTab
ShiftAltTab
AltTabMenu
AltTabAndMenu
AltTabMenuDismiss
new CustomHotkey.Remap("LCtrl", "Shift").on()
new CustomHotkey.Remap("LShift", "Ctrl").on()
new CustomHotkey.Remap("RShift", "MButton").on()
new CustomHotkey.Remap("RCtrl", "a", "ahk_exe notepad.exe").on()
The key/keys (a
, ^+a
) or combination (RCtrl & a
) to execute a hotkey is called a Trigger here.
It must be a valid string in the KeyName
argument of the Hotkey command. See here for details.
The following hotkey options can be additionally specified by appending "|"
after the Trigger. To specify options, separate them with a space such as "B1 T1"
.
B<1 | 0>
: SetsetEnableBuffer
method to a boolean valueF<1 | 0>
: SetsetFreeze
method to a boolean valueT<number>
: SetsetMaxThreads
method to a numberP<number>
: SetsetPriority
method to a numberI<number>
: SetsetInputLevel
method to a number
The following examples all have the same meaning.
new CustomHotkey("RCtrl & 1|B0 T5 I1", "{a}").on()
new CustomHotkey("RCtrl & 1", "{a}")
.setOptions("B0 T5 I1")
.on()
new CustomHotkey("RCtrl & 1", "{a}")
.setEnableBuffer(false)
.setMaxThreads(5)
.setInputLevel(1)
.on()
A process that is executed when a trigger is pressed is called an Action.
Also, an Action that switches the Action to be executed depending on the state of the key input, mouse, etc. is called a Combination Action.
Actions can also be defined by the user. See User-Defined Action for more information.
The Action defined depends on the data passed to the second argument of CustomHotkey's constructor. This data is called an Action Data.
In this section simple Actions will be covered.
This is the most basic Action that executes the specified keystroke. You can cancel at any time during key sending by pressing the Esc
key. If the Trigger includes the Esc
key, the key must be release once and then pressed again.
It can be defined by specifying a string or an object with the following fields. The send
field is required.
send
: A keys to send. Basically the same as the argument passed to the Send command, so see there for detailsmode
: Input mode. Specify the following string. Default is"Event"
"Event"
: Send a key using SendEvent command"Input"
: Send a key using the SendInput command"Play"
: Send a key using the SendPlay command"InputThenPlay"
: Same as"Input"
, but if SendInput is not available, SendPlay command is used to send keys
ime
: Change the IME state when sending keys. This may not work correctly because it has been checked only with the Japanese Microsoft IME. Can be specified in the following ways1
(ortrue
) to turn on IME,0
(orfalse
) to turn off IME and send key.- If you specify a time string or a number other than the numbers available above, the IME state is changed depending on whether the value is positive (on) or negative (off). After the specified time has elapsed, the IME state is restored to its previous state
sendLevel
: A number from1
to100
representing the send leveldelay
: Delay time when each key is pressed. If omitted, the same as A_KeyDelaypressDuration
: Delay time after key pressed. If omitted, the same as A_KeyDurationlimitLength
: A number representing the limit length of the keys to be sent. Counted by the actual key pressed. For example, if"{a}{b 3}"
is set, the length is4
. If-1
is set, there is no limit. Default is50
allowMultiline
: Iftrue
, allows keystrokes to span lines. However, theEnter
key is always allowed. Default isfalse
Passing a string is essentially the same as passing an object with a send
field, with the following differences.
-
Set the
mode
field by prefixing it with a string enclosed in curly brackets, such as"{Input}{a}"
-
Set a value for each field of
options
by passing the following options suh as"{Input|R L10}"
. If you want to specify more than one value, you must separate them with a spaceM
: Set thetrue
toallowMultiline
I<0|1>
: Set a number specified forime
S<number>
: Set a number tosendLevel
D<number>
: Set a number todelay
P<number>
: Set a number topressDuration
L<number>
: Set a number tolimitLength
In other words, the following examples have the same meaning.
new CustomHotkey("RCtrl & 1", "{Input}{a}").on()
new CustomHotkey("RCtrl & 1", { send: "{a}", mode: "Input" }).on()
In addition to the key names available in the Send command, the following special key names are available
{SuffixKey}
: Replace with the non-modifier key of the Trigger. For example,RCtrl & 1
will be replaced by{1}
{Clipboard}
: Replace with the clipboard content. Recommended to specify{Raw}
or{Text}
immediately before. Use with caution, since a large number of keys may be sent out depending on the clipboard contents. Remember that you can always interrupt a key send with theEsc
key{SelectedText}
: Replace with the selected text. See also{Clipboard}
and similar problems
new CustomHotkey("RCtrl & 1", "+{SuffixKey}").on()
If you want to change the IME state and send a key, use the I
option as follows. Please note that this feature has only been tested with the Japanese Microsoft IME and may not work properly in other environments.
The following is an example of sending a key with the IME state on or off and restoring the state after 1 second.
new CustomHotkey("RCtrl & 1", "{Input|I1}on").on()
new CustomHotkey("RCtrl & 2", "{Input|I0}off").on()
If you want to restore the IME state after sending a key, specify a value other than 0
or 1
for the I
option. The time when the key transmission finishes is different each time, so you need to adjust it by yourself.
new CustomHotkey("RCtrl & 1", "{Input|I1s}on").on()
new CustomHotkey("RCtrl & 2", "{Input|I-1s}off").on()
This Action outputs the specified string using the clipboard.
It can output strings faster than SendAction, but note that in rare cases when the clipboard is used by an external application, a conflict may occur and a string different from the specified string may be output.
It can be defined by specifying a string beginning with {Paste}
or an object with the following fields. The paste
field is required.
paste
: A string to output using clipboardreplace
: Iftrue
is specified,paste
is treated as Template StringrestoreClipboard
: A boolean value representing whether or not to restore the clipboard after the Action is done, or a delay time before restoring it. If a negative time is specified, such as-150ms
, the clipboard is restored using pseudo asynchronous processing. Note, that in this case non-string content will not be restored correctly. Note also that if the time specified is too short, this Action may not work correctly. Default is"150ms"
If you pass a string, you can specify the following options such as {Paste|R}
.
R
: settrue
toreplace
C<boolean | time>
: Set a boolean or time torestoreClipboard
; Output the `"abc"`
new CustomHotkey("RCtrl & 1", "{Paste}abc").on()
; Enclose the selected string in parentheses
new CustomHotkey("RCtrl & 2", "{Paste|R}({{SelectedText}})").on()
; Output today's date
new CustomHotkey("RCtrl & 3", "{Paste|R}{A_YYYY}/{A_MM}/{A_DD}").on()
This Action executes the specified file or URL.
It can be defined by specifying a string beginning with {Run}
or an object with the following fields. The run
field is required.
run
: A file path or URL to executeargs
: An arguments passed to the file, or URL parameters specified byrun
. It specifies an array consisting of a string or a callable objectrawArgsMode
: Disable processing of the arguments described below. However, processing by settingreplace
andlimitArgLength
is not disabled. Default isfalse
replace
: Iftrue
is specified, string specified byrun
andargs
are treated as Template String.workingDir
: A base directory (folder) when relative path is specified forrun
. Default is A_WorkingDirwait
: A boolean indicating whether to wait for the executed program to finishverb
: System verb that controls how the program is executed or not. Specify the following string. Default is"open"
"open"
: Open a file"properties"
: Open the properties window"find"
: Find in explorer"explore"
: Open in explorer"edit"
: Open in the associated text editor. If no action is assigned toedit
, nothing will be done"print"
: Open in the print application"*RunAs"
: Start with administrative privileges
launchMode
: Specify the following string. Not effective for some applications. It is case-insensitive"Max"
: Maximize the window on launch"Min"
: Minimize the window on launch"Hide"
: Hidden the window on launch
If run
begins with http://
or https://
, treated as URL mode. This mode converts args
using percent encoding if they are recognizable as query values. Specifically, if the preceding argument begins with &
or ?
and ends with =
or /
, such as "&search="
Otherwise, in file call mode, and each string of args
is enclosed in double quotes. However, if it can be recognized as a flag, such as starting with /
or -
, not enclosed.
If you want to disable this process, set true
to rawArgsMode
.
new CustomHotkey("RCtrl & 1", { run: "notepad", args: [ A_LineFile ] }).on()
new CustomHotkey("RCtrl & 2", { run: "https://www.google.com/search", replace: true, args: [ "?q=", "{{SelectedText}}" ] }).on()
If you want the values of run
and args
to be set when the Action is executed, specify a callable object. This object will be called when the Action is executed and its return value will be the value.
The following is an example of using a callable object.
; Change the URL to open depending on the extension included in the window title
new CustomHotkey("RCtrl & 1", { run: Func("GetDocumentUrl") }).on()
GetDocumentUrl() {
WinGetTitle, title, A
if (title ~= "\.ahk") {
return "https://www.autohotkey.com/docs/AutoHotkey.htm"
}
if (title ~= "\.(ahk2|ah2)") {
return "https://lexikos.github.io/v2/docs/AutoHotkey.htm"
}
return "https://www.google.com"
}
If you pass a string, you can specify the following options such as {Run|R Mmin}
.
R
: Set thetrue
toreplace
W
: Set thetrue
towait
M<"min" | "max" | "hide">
: Set a string tolaunchMode
L<number>
: Set a number tolimitArgLength
new CustomHotkey("RCtrl & 1", "{Run|R Mmax}notepad {'" . A_LineFile . "':Q}").on()
new CustomHotkey("RCtrl & 2", "{Run|R}https://www.google.com/search?q={{SelectedText}}").on()
This Action displays a tooltip.
It can be defined by specifying a string beginning with {ToolTip}
or an object with the following fields. The tooltip
field is required.
tooltip
: A string representing message to display in tooltip. If you want to hide existing tooltip, specify an empty string orfalse
replace
: Iftrue
is specified, strings specified bytooltip
are treated as Template String.id
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setdisplayTime
: Display time of tooltip. If a negative number is specified, the tooltip hiding process is asynchronous. Also, if0
is specified, the hide process is disabled. Default is1s
x
: A number representing the x-coordinate of the tooltip's display position. Default is0
y
: A number representing the y-coordinate of the tooltip's display position. Default is0
origin
: An origin of thex
andy
new CustomHotkey("RCtrl & 1", { tooltip: "This message will be displayed for 3 seconds.", displayTime: "3s" }).on()
; Always show and hide tooltip
new CustomHotkey("RCtrl & 2", { tooltip: "This message is always displayed", id: 19 }).on()
new CustomHotkey("RCtrl & 3", { tooltip: "", id: 19 }).on()
If you pass a string, you can specify the following options such as {ToolTip|R T1s}
.
R
: Set thetrue
toreplace
I<number>
: Set a number toid
T<time>
: Set a time todisplayTime
X<number>
: Set a number tox
Y<number>
: Set a number toy
O<string>
: Set a string toorigin
new CustomHotkey("RCtrl & 1", "{ToolTip|T3s}This message is displayed for 3 seconds.").on()
This Action displays a traytip (Also known as balloon tip).
It can be defined by specifying a string beginning with {TrayTip}
or an object with the following fields. The traytip
field is required.
traytip
: A string representing message to display in traytipreplace
: Iftrue
is specified,traytip
is treated as Template Stringtitle
: A string representing title to display in traytipicon
: Icon of the traytip. The following strings can be specified. If omitted, the icon is not displayed"info"
: Display the information icon"warn"
: Display for warning icon"error"
: Display for error icon
silent
: Iftrue
is specified, no sound is emitted when displaying. Default isfalse
If you pass a string, you can specify the following options such as {TrayTip|R Iwarn}
.
R
: Set thetrue
toreplace
S
: Set thetrue
tosilent
I<string>
: Set the string toicon
T<string>
: Set the string totitle
new CustomHotkey("RCtrl & 1", "{TrayTip|TInfo Iinfo}Display tray tip with information icon").on()
This Action restarts the currently script. Essentially the same as the Reload command, but with an restart message.
It can be defined by specifying a string beginning with {Reload}
or an object with the following fields. The reload
field is required.
reload
: A string representing message to display when before reloading scriptreplace
: Iftrue
is specified,reload
is treated as Template Stringtip
: Setting of tooltip to display the message. Specify an object with the following fieldsid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setx
: A number representing the x-coordinate of the tooltip. Default is0
y
: A number representing the y-coordinate of the tooltip. Default is0
origin
: An origin of thex
andy
coordinatesdisplayTime
: Display time of the tooltip. Default is"1s"
If you pass a string, you can specify the following options such as {Reload|T1s}
.
R
: Set thetrue
toreplace
X<number>
: Set the number totip.x
Y<number>
: Set the number totip.y
O<string>
: Set the string totip.origin
T<time>
: Set the time totip.displayTime
The following examples have the same meaning.
new CustomHotkey("RCtrl & 1", "{Reload|T0.5s}Restart the script").on()
new CustomHotkey("RCtrl & 1", { reload: "Restart the script", tip: { displayTime: "0.5s" } }).on()
This Action terminates the currently script. Essentially the same as the ExitApp command, but with an exit message.
It can be defined by specifying a string beginning with {Exit}
or an object with the following fields. The exit
field is required.
exit
: A string representing message to display when before exiting scriptreplace
: Iftrue
is specified,exit
is treated as Template Stringtip
: Setting of tooltip to display the message. Specify an object with the following fieldsid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setx
: A number representing the x-coordinate of the destination. Default is0
y
: A number representing the y-coordinate of the destination. Default is0
origin
: An origin of thex
andy
coordinatesdisplayTime
: Display time of the tooltip. Default is1s
If you pass a string, you can specify the following options such as {Exit|T1s}
.
R
: Set thetrue
toreplace
X<number>
: Set a number totip.x
Y<number>
: Set a number totip.y
O<string>
: Set a string totip.origin
T<time>
: Set a time totip.displayTime
The following examples have the same meaning.
new CustomHotkey("RCtrl & 1", "{Exit|T0.5s}Exit the script").on()
new CustomHotkey("RCtrl & 1", { exit: "Exit the script", tip: { displayTime: "0.5s" } }).on()
This Action terminates all AutoHotkey scripts.
It can be defined by specifying a string beginning with {ExitAll}
or an object with the following fields. The exitAll
field is required.
exitAll
: A string representing message to display when before exiting scriptsreplace
: Iftrue
is specified,reload
is treated as Template String.tip
: Setting of tooltip to display the message. Specify an object with the following fieldsid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setx
: A number representing the x-coordinate of the destination. Default is0
y
: A number representing the y-coordinate of the destination. Default is0
origin
: An origin of the x and y coordinatesdisplayTime
: Display time of the tooltip. If0
is specified, it will always remain visible. Default is1s
excludeSelf
: Exclude itself from the termination target
If a string is passed, the following options can be specified as in {ExitAll|T1s}
.
R
: Set thetrue
toreplace
E
: Set thetrue
toexcludeSelf
X<number>
: Set a number totip.x
Y<number>
: Set a number totip.y
O<string>
: Set a string totip.origin
T<time>
: Set a time totip.displayTime
The following examples have the same meaning.
new CustomHotkey("RCtrl & 1", "{ExitAll|T0.5s}Exit all the script").on()
new CustomHotkey("RCtrl & 1", { exitAll: "Exit all the script", tip: { displayTime: "0.5s" } }).on()
This Action delays processing. It has no meaning by itself and is used in CustomActions.
It can be defined by specifying a string beginning with {Delay}
, a pure number or an object with the following fields. The delay
field is required.
delay
: Delay time
If you specify a string beginning with {Delay}
, then time is specified after it.
If you pass a pure number, the unit is milliseconds.
The following three examples delay processing for one second when the Trigger is pressed. But thease alone is meaningless.
new CustomHotkey("RCtrl & 1", { delay: "1s" }).on()
new CustomHotkey("RCtrl & 1", 1000).on()
new CustomHotkey("RCtrl & 1", "{Delay}1s").on()
The following is an incorrect example. Treated as a string instead of a pure number, so defined as SendAction instead.
new CustomHotkey("RCtrl & 1", "1000").on()
The following is an example of CustomActions that sends keys at 250
millisecond intervals.
new CustomHotkey("RCtrl & 1", [ "a", 250, "b", 250, "c"]).on()
This Action executes the specified Action in a pseudo asynchronous process using SetTimer. Like DelayAction, is not useful on its own, but is used in CustomActions.
It can be defined by specifying an object with the following fields. The async
field is required.
The following is an example of executing three Actions with a delay. In this example, keys are sent in the order b
, c
, a
.
new CustomHotkey("RCtrl & 1", [ { async: "a", delay: 250 }
, { async: "b" }
, { async: "c", delay: 150 } ]).on()
This Action moves the mouse to the specified position.
It can be defined by specifying an object with one of the following fields.
x
: A number representing the x-coordinate of the destination. Default is0
y
: A number representing the y-coordinate of the destination. Default is0
origin
: An origin of thex
andy
coordinatesspeed
: A0
(fast) -100
(slow) representing the speed of cursor movement. If omitted, the same as if A_DefaultMouseSpeed were specified
; Move mouse to center of screen
new CustomHotkey("RCtrl & 1", { origin: "screen-center" }).on()
; Move 50 pixels to the right from the current position
new CustomHotkey("RCtrl & 2", { x: 50 }).on()
This Action clicks on the specified position.
It can be defined by specifying an object with the following fields. Either the button
or count
field is required.
button
: A name of the mouse button to use for clicking. The following string can be specified. case-insensitive. Default isLButton
"LButton"
,"Left"
,"L"
: Left button"RButton"
,"Right"
,"R"
: Right button"MButton"
,"Middle"
,"M"
: Middle button"XButton1"
,"X1"
: Extension 1 button. Usually placed at the front side"XButton2"
,"X2"
: Extension 2 button. Usually located at the back- In addition to the above, the following suffix can be additionally specified with a space between them, such as
"LButton Up"
. It is case-insensitive"Up"
,"U"
: Release the mouse button"Down"
,"D"
: Leave the mouse button pressed
mode
: Send mode of the click. Specify the following string. Default is"Event"
count
: A number of clickcs. Default is1
x
: A number representing the x-coordinate of the click position. Default is0
y
: A number representing the y-coordinate of the click position. Default is0
origin
: The origin of the x and y coordinates. Default is"mouse"
speed
: A0
(fast) -100
(slow) representing the speed of cursor movement. If omitted, it is the same as if A_DefaultMouseSpeed were specifiedrestore
: Iftrue
is specified, the mouse position will be restored withspeed
set to0
after the Action is done. If you want to specify the speed of the mouse when restoring, specify a number from-1
to-100
The following is an example of double-clicking on the center of the screen.
new CustomHotkey("RCtrl & 1", { button: "LButton", count: 2, origin: "screen-center" }).on()
This Action drags from a specified position to a position.
It can be defined by specifying an object with following fields. The to
field is required.
button
: A name of the mouse button to use for dragging. The following string can be specified. It is case-insensitive. Default isLButton
"LButton"
,"Left"
,"L"
: Left button"RButton"
,"Right"
,"R"
: Right button"MButton"
,"Middle"
,"M"
: Middle button"XButton1"
,"X1"
: Extension 1 button. Usually placed at the front side"XButton2"
,"X2"
: Extension 2 button. Usually located at the back
mode
: Send mode of the click. Specify the following string. Default is"Event"
from
: An object with the following fields representing the starting position of the drag. If omitted, the current mouse positionx
: A number representing the x-coordinate of the start position of the drag. If omitted, the x coordinate of the current position if omittedy
: A number representing the y-coordinate of the start position of the drag. If omitted, the x coordinate of the current position if omittedorigin
: An origin of thefrom.x
andfrom.y
coordinates. Default is"mouse"
to
: An object with the following fields representing the end position of the dragx
: A number representing the x-coordinate of the end position of the drag. If omitted, the x coordinate of the current position if omittedy
: A number representing the y-coordinate of the end position of the drag. If omitted, the x coordinate of the current position if omittedorigin
: An origin of theto.x
andto.y
coordinates. Default is"mouse"
speed
: A0
(fast) -100
(slow) representing the speed of cursor movement. If omitted, the same as if A_DefaultMouseSpeed were specifiedrestore
: Iftrue
is specified, the mouse position will be restored withspeed
set to0
after the Action is finished. If you want to specify the speed of the mouse when restoring, specify a number from-1
to-100
The following is an example of dragging from the current position toward the center of the screen.
new CustomHotkey("RCtrl & 1", { to: { origin: "screen-center" } }).on()
The Action is to click on a location that matches the specified image. If no match is found, nothing is done.
It can be defined by specifying an object with the following fields. The image
field is required.
image
: A path and flag of the image to click. In case of relative path, based on A_WorkingDir. The specification method is the same asImageFile
argument in ImageSearch. Alternatively, you can specify an object with the following fieldspath
: A path of the image. In case of relative path, based on A_WorkingDirpathType
: Change the treatment ofpath
. Specify the following string. It is case-insensitive. If omitted, treated as a file path"bitmap"
: Treat as a bitmap handle"icon"
: Treat as an icon handle
imageNumber
: A image number, if the file specified bypath
(e.g. dll) contains imagesvariation
: A number from0
-255
representing the amount of tolerance when comparing colors; if0
is specified, only exact matches will be matched. Conversely, a value of255
will match all colors. This is used to match a degraded imagetrans
,transparent
: A color to be transparentresize
: A boolean representing whether to resize or not, or an object with the following fields. Default istrue
width
: Width of the image to be loaded. If-0
is specified, the image is not resized. If-1
is specified, the image will be resized keeping the ratioheigth
: Height of the image when loading. If-0
is specified, the image is not resized. If-1
is specified, the image is resized keeping the ratio
targetRect
: A rectangle to use as the search range. Default is"window"
button
: A name of the mouse button to use for clicking. The following string can be specified. It is case-insensitive. Default isLButton
"LButton"
,"Left"
,"L"
: Left button"RButton"
,"Right"
,"R"
: Right button"MButton"
,"Middle"
,"M"
: Middle button"XButton1"
,"X1"
: Extension 1 button. Usually placed at the front side"XButton2"
,"X2"
: Extension 2 button. Usually located at the back- In addition to the above, the following suffix can be additionally specified with a space between them, such as
"LButton Up"
. It is case-insensitive"Up"
,"U"
: Release the mouse button"Down"
,"D"
: Leave the mouse button pressed
mode
: Send mode of the click. Specify the following string. Default is"Event"
count
: Number of clickcs. Default is1
offset
: Offset from the found image. Used to correct the click position. Specify an object with the following fieldsx
: Offset in x-coordinate from the found imagey
: Offset in y-coordinate from the found image
speed
: A0
(fast) -100
(slow) representing the speed of cursor movement. If omitted, the same as if A_DefaultMouseSpeed were specifiedrestore
: Iftrue
is specified, the mouse position will be restored withspeed
set to0
after the action is finished. If you want to specify the speed of the mouse when restoring, specify a number from-1
to-100
The following is an example of clicking on an image and restoring the mouse position.
; Note: If you want to run the following example, you will need to set up your own path
new CustomHotkey("RCtrl & 1", { image: "path/to/image", speed: 0, restore: true }).on()
If this Action is used in CustomActions as in the following example, subsequent Actions will be aborted if the image is not found.
; Note: If you want to run the following example, you will need to set up your own path
; Drag the image 100 pixels to the right
new CustomHotkey("RCtrl & 1", [ { button: "LButton Down", image: { path: "path/to/image" }, speed: 0 }
, { x: 100 }
, { button: "LButton Up"} ] ).on()
This Action displays information (color, coordinates, etc.) under the mouse in a tooltip while the non-modifier key in trigger (e.g. 1
of RCtrl & 1
) is pressed, and copies that information to the clipboard when the non-modifier key is released.
It can be defined by specifying an object with the following fields. The dropper
field is required.
dropper
: A method to retrieve information. Specify the following string or callable object"color"
: Get a color code under the mouse"coord"
,"coordinate"
: Get a coordinates under the mouse"window"
: Get a window information (title, class, etc.) under the mouse
tip
: Setting for a tooltip that displays a hint. Specify an object with the following fields. Normally, you do not need to specify thisid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setx
: A number representing the x-coordinate of the destination. Default is0
y
: A number representing the y-coordinate of the destination. Default is0
origin
: An origin of thetip.x
andtip.y
coordinatesdelay
: Delay time to display the tooltip. Default is100ms
options
: Options to pass to thedropper
If called from a KeyStrokeCombiAction, the Action will be executed as long as the key at the time of the call (q
, w
, or e
in the example below) is pressed, not the non-modifier key.
new CustomHotkey("RCtrl & 1", [ { key: "q", desc: "color", action: { dropper: "color" } }
, { key: "w", desc: "coordinates", action: { dropper: "coordinates" } }
, { key: "e", desc: "window", action: { dropper: "window" } } ]).on()
If "color"
is specified for dropper
, the color information under the mouse will be retrieved.
options
is a string or an object with the following fields. If you pass a string, the same as specifying template
.
template
: Template String to display the retrieved information. The following variables can be specified. Default is"#{R:X}{G:X}{B:X}"
R
: A number representing red colorG
: A number representing green colorB
: A number representing blue color
method
: A method to get the color. The following strings can be specified. Default is"Default"
. It is case insensitive"Default"
: Get a color in the normal way"Alt"
: Get in a different way from the usual way. The speed is a little slower, but you may be able to get a color even if you cannot get it with"Default"
"Slow"
: Get a color in a more complicated way. However, slower than"Alt"
new CustomHotkey("RCtrl & 1", { dropper: "color" }).on()
new CustomHotkey("RCtrl & 2", { dropper: "color", options: { template: "R: {R}, G: {G}, B: {B}", method: "Slow" } }).on()
If "coordinates"
or "coord"
is specified for dropper
, the information of coordinates under the mouse will be retrieved.
options
is a string or an object with the following fields. If you pass a string, the same as specifying template
.
template
: Template String to display the retrieved information. The following variables can be specified. Default is"{x}, {y}"
x
: A number representing the x-coordinate of the mousey
: A number representing the y-coordinate of the mouse
origin
: An origin of the x and y coordinates. Default is"mouse"
new CustomHotkey("RCtrl & 1", { dropper: "coordinates" }).on()
new CustomHotkey("RCtrl & 2", { dropper: "coordinates", options: "x: {x}`ny: {y}" }).on()
new CustomHotkey("RCtrl & 3", { dropper: "coordinates", options: { origin: "window" } }).on()
If "window"
is specified for dropper
, the information of the window under the mouse is targeted for retrieval.
options
is an object with the following fields. If you pass a string, the same as specifying template
.
template
: Template String to display the retrieved information. The following variables can be specified.title
: A title under the mouseclass
: A window class under the mouseahk_class
: Same as above but with prefix"ahk_class"
exe
: A process name of the window under the mouseahk_exe
: Same as above but with prefix"ahk_exe"
path
: A process path of the window under the mouseid
,hwnd
: A window handle of the window under the mouseahk_id
: Same as above but with prefix"ahk_id"
pid
: A process name of the window under the mouseahk_pid
: Same as above but with prefix"ahk_pid"
controlName
: A name of the control under the mousecontrolId
,controlHwnd
: A control handle under the mouse
new CustomHotkey("RCtrl & 1", { dropper: "window" }).on()
new CustomHotkey("RCtrl & 2", { dropper: "window", options: "{ahk_id}" }).on()
If you specify a callable object for the dropper
, you can customize what information is retrieved.
The first argument is passed an object with an x
or y
field, the coordinates of the mouse with the origin in the upper left corner of the screen.
The second argument is the data passed in the options
.
new CustomHotkey("RCtrl & 1", { dropper: Func("CustomTarget"), options: { template: "{}, {}" } }).on()
CustomTarget(position, options) {
return Format(options.template, position.x, position.y)
}
This Action changes the state of the IME. Note, that this has not been tested with anything other than the Japanese Microsoft IME, so it may not work correctly in other environments.
It can be defined by specifying an object with the following fields.
ime
: IME status to set. Iftrue
, turn on; iffalse
, turn off
new CustomHotkey("RCtrl & 1", { ime: false }).on()
new CustomHotkey("RCtrl & 2", { ime: true }).on()
This is a function-style user-defined Action. If you want to define them in class style, see User-Defined Action.
It can be defined by specifying a callable object (function, method, BoundFunc, etc.).
The following is an example of defining an Action to maximize the active window.
new CustomHotkey("RCtrl & 1", Func("MoveActiveWindow").bind(0, 0, A_ScreenWidth, A_ScreenHeight)).on()
MoveActiveWindow(x := "", y := "", width := "", height := "") {
WinMove, A, , %x%, %y%, %width%, %height%
}
Since all Actions are callable objects, they can be specified directly as follows.
; The following defines the same action
new CustomHotkey("RCtrl & 1", "^{a}").on()
new CustomHotkey("RCtrl & 2", new CustomHotkey.SendAction("^{a}")).on()
This Action executes the specified Actions subsequently.
It can be defined by specifying an array consisting of the Action Data.
; Send keys with delay
new CustomHotkey("RCtrl & 1", [ "a", 250, "b", 250, "c" ]).on()
; Reproduce MouseDragAction by combining Actions
new CustomHotkey("RCtrl & 2", [ { button: "LButton down" }
, { x: 200, y: 200 }
, { button: "LButton up" } ]).on()
If a callable object is specified, the first argument is the return value of the last Action that returned a non-empty value, and the second argument is an ActionDone
object. Passing it as return value will abort Actions.
With the Actions described above, only one Action could be assigned to a hotkey.
The Combination Actions described next allow more Actions to be assigned.
Also, possible to define Combination Actions for Combination Actions, allowing for more complex Action assignments.
This Combination Action that switches an Action depending on how the non-modifier key (1
in the case of RCtrl & 1
) of the Trigger is pressed.
It can be defined by passing an object with one of the following fields.
single
: An Action to be executed when the Trigger is pressedlong
: An Action to be executed when a Trigger is pressed and an non-modifier key is pressed for a long time. The following option string can be specified:long|T150ms
T<time>
. Set time totimeout_long
described next
double
: An Action to be executed when an additional non-modifier key is pressed (i.e. double press) following the Trigger. The following option string can be specified:double|T150ms
T<time>
. Set time totimeout_double
described nextN
: Settrue
tonodelay
described next
The following fields can also be added.
targetKey
: Override the target key for the event. Default is the non-modifier key of the trigger. Usually does not need to be specifiedtimeout_long
: A time to be recognized as a long presstimeout_double
: A time to be recognized as a double pressnodelay
: Iftrue
is specified, it disables the delay processing until the second press is determined. That is, the action assigned tosingle
will be executed regardless of whether pressed double or not
new CustomHotkey("RCtrl & 1", { single: "{ToolTip}single press"
, long: "{ToolTip}long press"
, double: "{ToolTip}double press" }).on()
nodelay
is useful in cases where a double
overrides a single
Action, as in the following example. In this example, nodelay
is set by using the N
option for the double
field.
new CustomHotkey("RCtrl & 1", { single: [ "{ToolTip}IME OFF", { ime: false } ]
, "double|T1s N": [ "{ToolTip}IME ON", { ime: true } ] }).on()
Complex definitions such as pressing five times and long pressing are also possible by combining this Action as follows.
new CustomHotkey("RCtrl & 1", { single: "{ToolTip}single"
, long: "{ToolTip}long"
, double: { single: "{ToolTip}double"
, long: "{ToolTip}double+long"
, double: { single: "{ToolTip}triple"
, long: "{ToolTip}triple+long"
, double: { single: "{ToolTip}quadruple"
, long: "{ToolTip}quadruple+long"
, double: { single: "{ToolTip}quintuple"
, long: "{ToolTip}quintuple+long" } } } } }).on()
In practice, such complex definitions are not very easy to visualize, so the following fields are provided for simplified settings.
triple
: An Action when triple pressquadruple
: An Action when quadruple pressquintuple
: An Action when quintuple press
new CustomHotkey("RCtrl & 1", { single: "{ToolTip}single"
, long: "{ToolTip}long"
, double: "{ToolTip}double"
, triple: "{ToolTip}triple"
, quadruple: "{ToolTip}quadruple"
, quintuple: "{ToolTip}quintuple"}).on()
Note that key that is virtual modifier key (Up
in the example below) cannot be detected as long presses, so the Action will not be executed. Also, single and double presses will cause the Action to be executed when the key is released, not when pressed.
new CustomHotkey("Up & Down", "").on()
new CustomHotkey("Up", { single: "{ToolTip}single"
, long: "{ToolTip}long" ; This action cannot be executed
, double: "{ToolTip}double" }).on()
This Combination Action, like PressEventCombiAction, switches the Action according to the pressing of the non-modifier key (1
of RCtrl & 1
) of the Trigger.
It can be defined by specifying an object with the following fields. The hold
field is required.
tap
: An Action to be executed when a Trigger is pressed and an non-modifier key is released within the specified time. You can use the following option string astap|T80ms
.T<time>
: Set time totimeout_tap
described nextN
: Settrue
tonodelay
described next
hold
: An Action to be executed while an non-modifier key is pressed. You can use the following option string ashold|R10ms
R<time>
: An Action repeat interval. If not specified, the action will be executed only once
release
: An Action to be executed when an non-modifier key is released. Only executed if the Action ofhold
has been executed at least once
The following fields can also be added.
targetKey
: Override the target key for the event. Default is the non-modifier key of the Trigger. Usually does not need to be specifiedtimeout_tap
: A time to be recognized as a tap inputnodelay
: Iftrue
is specified, thetap
Action will always be executed before the Action assigned tohold
is executed, regardless of thetimeout_tap
setting
new CustomHotkey("RCtrl & 1", { hold: { button: "LButton down" }
, release: { button: "LButton up" } }).on()
new CustomHotkey("RCtrl & 2", { tap: "{ToolTip}tap"
, "hold|R50ms": "{ToolTip}hold"
, release: "{ToolTip}release" }).on()
This Combination Action that switches the Action depending on the specified modifier key is pressed at the time of Trigger pressing.
It is useful when using keyboard that are rarely used but have very easy-to-press non-modifier key, such as henkan-key of Japanese keyboard, but may not be very useful otherwise.
It can be defined by specifying an object with one of the following fields.
trigger
: An Action when only a Trigger is pressedA modifier key name or its array
: An Action to be executed if the modifier key is pressed in addition to the trigger. If the modifier key is specified as an array, it will be executed if all of its keys are pressed
new CustomHotkey("z & 1", { trigger: "{ToolTip}trigger"
, shift: "{ToolTip}trigger+shift"
, [ "shift", "ctrl" ]: "{ToolTip}trigger+shift+ctrl" }).on()
This Combination Action that switches the Action based on the specified additional key is pressed while pressing the Trigger. You can define hotkey for combinations of three or more keys, such as a & b & c
, which are not allowed in the normal syntax.
Like ModifierPressCombiAction, it may not be very useful depending on the keyboard layout used.
It can be defined by specifying an object whose key is one of the following fields.
- Key name : An Action to be executed when the specified key is pressed in addition to the Trigger. You can also specify the following option string as
a|R10ms
R<time>
: Set time tokeyRepeat
individually
release
: An Action when the non-modifier key of the Trigger is released. Use when you want to assign an Action to the Trigger itself as wellkeyRepeat
: Default time for pseudo-key repeat interval,0
orfalse
to disable key repeat. Default is15ms
The following is an example of a 3-key hotkey definition.
new CustomHotkey("PgUp & PgDn", { q: "^{c}" , w: "^{v}", "e|R10ms": "^{z}" }).on()
This Action can be combined to define four or more hotkeys. In the following example, you need to type PgUp
-> PgDn
-> q
-> w
-> e
in that order.
new CustomHotkey("PgUp & PgDn", { q: { w: { "e|R10ms": "{ToolTip}PgUp & PgDn & q & w & e" } } }).on()
This Combination Action that accepts key input when the Trigger is pressed and switches Actions in response to the input.
It will continue until the specified key is pressed or one of the following Cancel keys
is pressed: Escape
, Backspace
, or Delete
.
It can be defined by specifying an object with the following fields. The items
field is required.
tip
: Setting for a tooltip that displays a hint. Specify an object with the following fieldsx
: A number representing the x-coordinate of the tooltip. Default is0
y
: A number representing the y-coordinate of the tooltip. Default is0
origin
: An origin of thetip.x
andtip.y
coordinatesid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setlimitDescriptionLength
: Limit length of theaction
description. Default is100
items
: Specify an object with the following fieldskey
: A string representing either a key name, a virtual key, or a scan code. If"$"
or"F$"
is specified, the key is automatically assigned as described belowdescription
,desc
: A description ofaction
action
: An Action to be executed when akey
is pressed
You can directly specify an array to be passed to items
. In other words, the following two hotkeys have the same meaning.
items := [ { key: "a", description: "Show A in tooltip", action: "{ToolTip}A" } ]
new CustomHotkey("RCtrl & 1", items).on()
new CustomHotkey("RCtrl & 2", { items: items }).on()
If you specify "$"
for key
, keys are set in the order 1
-0
, q
-p
, a
-l
, and z
-m
.
Also, by specifying "F$"
, keys from F1
-F24
will be set in this order.
new CustomHotkey("RCtrl & 1", [ { key: "$", desc: "1", action: "{ToolTip}1" }
, { key: "$", desc: "2", action: "{ToolTip}2" }
, { key: "$", desc: "3", action: "{ToolTip}3" }
, { key: "F$", desc: "F1", action: "{ToolTip}F1" }
, { key: "F$", desc: "F2", action: "{ToolTip}F2" }
, { key: "F$", desc: "F3", action: "{ToolTip}F3" } ]).on()
This auto-assigned key can be changed by specifying the following additional fields.
autokeys
: An array of keys to be replaced if"$"
is specifiedautoFunctionkeys
: An array of keys to be replaced if"F$"
is specified
new CustomHotkey("RCtrl & 1", { autoKeys: [ "a", "b", "c"]
, autoFunctionKeys: [ "F1", "F5", "F9" ]
, items: [ { key: "$", action: "{ToolTip}a" }
, { key: "$", action: "{ToolTip}b" }
, { key: "$", action: "{ToolTip}c" }
, { key: "F$", action: "{ToolTip}F1" }
, { key: "F$", action: "{ToolTip}F5" }
, { key: "F$", action: "{ToolTip}F9" } ] }).on()
This Action can be combined to define a hot-string-like action.
new CustomHotkey("RCtrl & 1", [ { key: "b"
, desc: "by"
, action: [ { key: "t"
, desc: "the"
, action: [ { key: "w"
, desc: "way"
, action: "{ToolTip}by the way" } ] } ] } ]).on()
As in the example above, if this Action is combined, pressing the Cancel key will re-execute the previous Action.
In other words, after pressing the b
key, pressing Escape
will accept the b
key input again.
If you want to exit completely, hold down Ctrl
and press the Cancel key
.
This Combination Action searches and executes registered commands, like Command Palette in VSCode.
The following limitations exist because the UI is created with tooltip.
- Flickering occurs when refreshing contents
- IME cannot be used, so search strings are limited to characters that can be entered directly with the keyboard
It can be defined by specifying an object with the following fields. The items
field is required.
tip
: Setting up tooltip to be used in the UI. Specify an object with the following fieldsx
: A number representing the x-coordinate of the tooltip. Default is0
y
: A number representing the y-coordinate of the tooltip. Default is0
origin
: An origin of thetip.x
andtip.y
coordinatesid
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is setmaxRows
: Maximum number of commands to be displayed at one time. Default is20
limitDescriptionLength
: Maximum length of thedescription
. Default is100
input
: Initial value of user inputlimitInputLength
: Limit number of user input. Default is100
caretPosition
: Initial position of the input (1-base). If omitted, the length ofinput
plus 1caretChar
: Specify the character that represents the caret. Default is"|"
fontType
: Change the alphanumeric font if the command matches or not. Can be a number or a string1
,"serif"
,"default"
: e.g.aA0
,𝐚𝐀𝟎
2
,"serif-italic"
: e.g.𝑎𝐴0
,𝒂𝑨𝟎
3
,"sans-serif"
: e.g.aA𝟢
,𝐚𝐀𝟬
4
,"sans-serif-italic"
: e.g.𝘢𝘈𝟢
,𝙖𝘼𝟬
cursorPosition
: Initial cursor position (1-base). Default is1
matcher
: Algorithm used for matching commands. If omitted, fuzzy search is used for matching. See fuzzy search and custom search for more informationitems
: An array or call object consisting of objects with the following fields. There is no limit, but recommended to limit the length of the array to about1000
for processing speedcommand
: A command name. Must be a string that can be typed directly on the keyboardicon
: A string that appear beforecommand
. By using emoji, you can express the kind of command, etc.description
,desc
: Anaction
descriptionaction
: An Action when the command is executed
The following hotkeys are available while in input mode (Tip: ^
indicates Ctrl
, !
indicates Alt
).
Up
: Move the cursor to the item above. If the current cursor is on the first item, move it to the last item^Up
: Move the cursor to the first itemDown
: Move the cursor to the item below. If the current cursor is on the last item, move it to the first item^Down
: Move the cursor to the last itemPgUp
: Move the cursor up one pagePgDn
: Move the cursor down one pageLeft
: Move caret to the left and update the listingHome
,^Left
: Move caret to the first position and update the listingRight
: Move caret to the right and update the listingEnd
,^Right
: Move caret to the last position and update the listingEnter
,Tab
: Execute tha ActionEscape
: Delete all input. If there is no input, the Action is terminated. Also, if there is a chain of Actions and a corresponding Action exists, the state is restored and the Action is reexecuted^Escape
: Terminate the Action completelyBacspace
: Delete the character before the caret^Bacspace
: Delete all characters before caretDelete
: Delete the character after the caretAlt
: Display full description
new CustomHotkey("RCtrl & 1", { items: [ { command: "copy"
, description: "Copy selected text"
, action: "^c" }
, { command: "cut"
, description: "Cut selected text"
, action: "^x" }
, { command: "paste"
, description: "Paste clipboard contents"
, action: "^v" } ] }).on()
You can directly specify an array to be passed to items
. In other words, the following two hotkeys have the same meaning.
items := [ { command: "a", action: "a" } ]
new CustomHotkey("RCtrl & 1", { items: items }).on()
new CustomHotkey("RCtrl & 2", items).on()
Passing a callable object in the items
field can be used to delay the creation of a command.
Also, using the ModifierPressCombiAction, you can switch the Action to be executed depending on the state of the modifier key when the Enter
or Tab
key is pressed.
Using these mechanisms, possible to define a file explorer-like Action as follows.
new CustomHotkey("RCtrl & 1", { tip: { limitDescriptionLength: 0 }, items: Func("Explorer").bind("C:") }).on()
Explorer(root) {
list := []
Loop Files, %root%\*, FD
{
try {
FileGetAttrib, attribute, %A_LoopFileLongPath%
if (InStr(attribute, "H") || InStr(attribute, "S")) {
continue
}
if (InStr(attribute, "D")) {
list.push({ command: A_LoopFileName
, icon: "📂"
, desc: A_LoopFileLongPath
, action: { trigger: { tip: { limitDescriptionLength: 0 }
, items: Func("Explorer").bind(A_LoopFileLongPath) }
, ctrl: "{ToolTip}" . A_LoopFileLongPath } })
}
else {
list.push({ command: A_LoopFileName
, icon: "📄"
, desc: A_LoopFileLongPath
, action: "{ToolTip}" . A_LoopFileLongPath })
}
}
}
return list
}
The following is an example of expressing the kind of command as in VSCode.
new CustomHotkey("RCtrl & 1", { input: ">", items: Func("Commands") }).on()
new CustomHotkey("RCtrl & 2", { input: "@", items: Func("Commands") }).on()
new CustomHotkey("RCtrl & 3", { input: "?", items: Func("Commands") }).on()
Commands() {
return [ { command: ">group-a", action: "{ToolTip}a" }
, { command: "@group-b", action: "{ToolTip}b" }
, { command: "?group-c", action: "{ToolTip}c" } ]
}
The default is to search for commands by fuzzy search. This search algorithm has the following features.
In fuzzy search, a score is given based on the number of characters matched, and the higher the given score, the higher the command is displayed.
Matching is usually done from the beginning, but if a match is found at the beginning of each word, that is given priority. As will be explained below, this match is given a bonus, so that the desired command can be retrieved with less input. The beginning of a word means the following.
- The first letter of the
command
and the character is an alphabet - The immediately preceding character is lowercase and the matching character is uppercase
- The immediately preceding character is space or Any of the symbols in
!"#$%&'()*+,-. /:;<=>? @[]^_`{
, and the matching character is the alphabet
This word first match is disabled if matched consecutively. For example, if the command is FoobarBar
and the input is foob
, the B
in Bar
will not match. If you want to force a match to the beginning of a word, use capital letters. In the previous example, if the input is fooB
, it will match the B
in Bar
.
If the following conditions are met when a match is made, a bonus will be given to the score.
- Matched the beginning of a
command
- Matched the beginning of a word
- Matched consecutive words
- Exact case match
- User input and
command
matched exactly. The case is not sensitive. An additional bonus will be given after the above bonuses are added
If the matched characters are alphanumeric characters and any of the . -_//\
, it will be highlighted as follows.
ABC123.-_/\
𝐀𝐁𝐂𝟏𝟐𝟑۔⁃‗⌿⍀
You can change the search algorithm by specifying an object with the following callable objects in matcher
.
score(a: any, b: any, options: any) => number
: A callable object that computes the similarity betweena
andb
. The higher the number returned, the higher the similarity. Theoptions
is passedmatcherOptions
parse(a: any, b: any, options: any) => Array<[ string, boolean ]>
: A callable object that computes information to highlight matches. Returns an array of arrays containing pairs of the compared substrings and a boolean indicating whether or not there was a match. Theoptions
is passedmatcherOptions
The following is an example implementation of a forward match search.
items := []
items.push({ command: "foo", action: "{ToolTip}foo"})
items.push({ command: "foobar", action: "{ToolTip}foobar"})
new CustomHotkey("RCtrl & 1", { matcher: ForwardMatcher, items: items }).on()
new CustomHotkey("RCtrl & 2", { matcher: ForwardMatcher, matcherOptions: { caseSensitive: true }, items: items }).on()
class ForwardMatcher {
score(a, b, options) {
if (b == "") {
return 1
}
if (this._startsWith(a, b, options.caseSensitive)) {
return StrLen(b)
}
return 0
}
parse(a, b, options) {
segments := []
if (b == "") {
segments.push([ a, false ])
return segments
}
if (this._startsWith(a, b, options.caseSensitive)) {
segments.push([ SubStr(a, 1, StrLen(b)), true ])
segments.push([ SubStr(a, StrLen(b) + 1), false ])
return segments
}
return segments
}
/**
* Determine if `str` starts with `prefix` or not.
*/
_startsWith(str, prefix, caseSensitive := false) {
str_prefix := SubStr(str, 1, StrLen(prefix))
return InStr(str_prefix, prefix, caseSensitive)
}
}
This Combination Action switches an Action by mouse operation.
The mouse operation is accepted while the non-modifier key of the Trigger (e.g. 1
of RCtrl & 1
) is held down, and the Action is terminated when the key is released.
While the Action is running, a transparent window is displayed to fill the screen, blocking mouse clicks. If for some reason the Action does not terminate, please quit AutoHotkey by pressing Alt & Tab
to switch to another window, or by pressing ^+Esc
to start the task manager.
It can be defined by specifying an object with the following fields. The items
field is required.
tip
: Setting for a tooltip that displays a hint. Specify an object with the following fieldsx
: A number representing the x-coordinate of the position where the tooltip will be displayed. Default is0
y
: A number representing the y-coordinate of the position where the tooltip will be displayed. Default is0
origin
: An origin of thetip.x
andtip.y
coordinates. Default is"caret-bottom-right"
id
: A number from1
to20
representing the ID of the tooltip. If a tooltip with the same ID already exists, the content will be overwritten. If omitted, an unused ID is set
style
: Change a style of the mouse trail, such as its color. Specify an object with the following fieldscolor
: A color of the mouse trail. Default is"lime"
.width
: Width of the mouse path. Default value is6
threshold
: A threshold (in pixels) to judge mouse movement. Default is50
items
: Specify an object with the following fieldsgestures
: An array of string representing mouse Actions. The following string is specified"LButton"
,"Left"
,"L"
: Left button"RButton"
,"Right"
,"R"
: Right button"MButton"
,"Middle"
,"M"
: Middle button"XButton1"
,"X1"
: Extension 1 button. Usually placed at the front side"XButton2"
,"X2"
: Extension 2 button. Usually located at the back"MoveUp"
,"MU"
,"↑"
,"🡡"
,"🡩"
,"🡱"
,"🡹"
,"🢁"
: Move mouse up"MoveDown"
,"MD"
,"↓"
,"🡣"
,"🡫"
,"🡳"
,"🡻"
,"🢃"
: Move mouse down"MoveLeft"
,"ML"
,"←"
,"🡠"
,"🡨"
,"🡰"
,"🡸"
,"🢀"
: Move mouse to the left"MoveRight"
,"MR"
,"→"
,"🡢"
,"🡪"
,"🡲"
,"🡺"
,"🢂"
: Move mouse to the right"MoveUpLeft"
,"MUL"
,"↖"
,"🡤"
,"🡬"
,"🡴"
,"🡼"
,"🢄"
: Move mouse to the upper left"MoveUpRight"
,"MUR"
,"↗"
,"🡥"
,"🡭"
,"🡵"
,"🡽"
,"🢅"
: Move mouse to the upper right"MoveDownLeft"
,"MDL"
,"↙"
,"🡧"
,"🡯"
,"🡷"
,"🡿"
,"🢇"
: Move the mouse to the lower left"MoveDownRight"
,"MDR"
,"↘"
,"🡦"
,"🡮"
,"🡶"
,"🡾"
,"🢆"
: Move the mouse to the lower right
description
,desc
: Anaction
descriptionaction
: An Action to be executed when the specified mouse operation is done
The following is an example of assigning Actions by mouse cursor movement or button press.
new CustomHotkey("RButton", { items: [ { gestures: [ "MoveUp", "MoveRight", "MoveDown", "MoveLeft" ]
, description: "↑→↓←"
, action: "{ToolTip}↑→↓←" }
, { gestures: [ "MoveUp", "MoveDown" ]
, description: "↑↓"
, action: "{ToolTip}↑↓" } ] }).on()
new CustomHotkey("RCtrl & Up", { items: [ { gestures: [ "LButton", "RButton", "MButton", "XButton1", "XButton2" ]
, description: "LButton"
, action: "{ToolTip}Pressed all mouse buttons" } ] }).on()
You can directly specify an array to be passed to items
. In other words, the following two hotkeys have the same meaning.
items := [ { gestures: [ "MoveUp" ], action: "{ToolTip}MoveUp" }]
new CustomHotkey("RCtrl & Up", { items: items }).on()
new CustomHotkey("RCtrl & Down", items).on()
This Combination Action displays custom context menu.
It can be defined by specifying an object with the following fields. The items
field is required.
x
: A number representing the x-coordinate of the display position of the context menu. Default is0
y
: A number representing the y-coordinate of the display position of the context menu. Default is0
origin
: An origin of thex
andy
coordinatesitems
: An array consisting of object with the following fields or a string containing"-"
or"="
. If the string is specified, a delimiter will be added
The following is an example of creating a context menu with two items.
new CustomHotkey("RCtrl & 1", { items: [ { label: "a", action: "{ToolTip|T1s}a" }
, { label: "b", action: "{ToolTip|T1s}b" } ] }).on()
You can directly specify an array to be passed to items
. In other words, the following two hotkeys have the same meaning.
items := [ { label: "a", action: "{ToolTip}a" } ]
new CustomHotkey("RCtrl & 1", { items: items }).on()
new CustomHotkey("RCtrl & 2", items).on()
If you want to create a submenu, pass the ContextMenuCombiAction
or its Action Data to action
.
submenu := [ { label: "sub item", action: "{ToolTip}sub item" } ]
new CustomHotkey("RCtrl & 1", [ { label: "top item"
, action: submenu } ]).on()
Also, if you want to add a delimiter, add a string containing "-"
or "="
to the items
element. All other characters are ignored and can be used as comment.
new CustomHotkey("RCtrl & 1", [ { label: "a", action: [ { label: "b", action: "{ToolTip}b" } ] }
, "---Comment---"
, { label: "c", action: "{ToolTip}c" }
, "===Comment==="
, { label: "d", action: "{ToolTip}d" } ]).on()
If you pass a callable object for action
, the following arguments will be passed.
itemName: string
: A name of the itemitemPos: number
: Number of the itemmenuName: string
: A menu name. a string of the formCustomHotkey.ContextMenuCombiAction:<action-address>
.
new CustomHotkey("RCtrl & 1", [ { label: "custom", action: Func("CustomMenuItem") } ]).on()
CustomMenuItem(itemName, itemPos, menuName) {
MsgBox, Clicked on "%itemName%", the %itemPos% item in "%menuName%"
}
If you want to display item only when they match specific Condition, use condition
.
The following is an example of displaying a dedicated item when viewing a specific site in a browser.
items := []
items.push({ label: "This item is always displayed"
, action: "{ToolTip}This item is always displayed" })
items.push({ condition: "{Active|Mbackward}AutoHotkey - Google Chrome"
, label: "AutoHotkey Official Document"
, action: "{ToolTip}AutoHotkey Official Document" })
items.push({ condition: "{Active|Mbackward}YouTube - Google Chrome"
, label: "Youtube"
, action: "{ToolTip}Youtube" })
new CustomHotkey("RCtrl & 1", items).on()
This Combination Action switches Actions according to Condition result.
It has almost the same meaning as defining a context-sensitive hotkey by passing a Condition as the third argument to the CustomHotkey constructor, but with the following advantages.
- A highly loaded Condition such as ImageCondition can be set with a minimum load. In the case of context-sensitive hotkey, all assigned Conditions are evaluated until they match when a Trigger is pressed, so registering a Condition with a high load may slow down the execution of the Action due to the time required for evaluation
- Additional Conditions can be defined for context-sensitive hotkeys
- Readability may be higher than context-sensitive hotkey definitions due to different writing style
It can be defined by specifying an object with the following fields. The items
field is a required.
defaultAction
: An Action to execute if the Conditions is not matcheditems
: An array of objects with the following fields. The order of precedence is given to the element with the youngest index
The following two examples have the same meaning, although implementation differences may cause differences in performance.
new CustomHotkey("RCtrl & 1", "{ToolTip}default").on()
new CustomHotkey("RCtrl & 1", "{ToolTip}notepad", "ahk_exe notepad.exe").on()
new CustomHotkey("RCtrl & 1", "{ToolTip}chrome", "ahk_exe chrome.exe").on()
new CustomHotkey("RCtrl & 1", [ { condition: false, action: "{ToolTip}default" }
, { condition: "ahk_exe notepad.exe", action: "{ToolTip}notepad" }
, { condition: "ahk_exe chrome.exe", action: "{ToolTip}chrome" } ]).on()
You can directly specify an array to be passed to items
. In other words, the following two hotkeys have the same meaning.
items := [ { condition: "ahk_exe notepad.exe", action: "{ToolTip}notepad" } ]
new CustomHotkey("RCtrl & 1", { items: items }).on()
new CustomHotkey("RCtrl & 2", items).on()
The following is an example of a web search for the selected text. In this example, the search site is changed according to the extension of the file being edited. This example is only valid for editors that display the path of the file being edited in the window title.
new CustomHotkey("RCtrl & 1", [ { condition: false, action: "{Run|R}https://www.google.com/search?q={{SelectedText}:P}" }
, { condition: { matchMode: "regex", active: { title: "\.(js|ts)" } }, action: "{Run|R}https://developer.mozilla.org/ja/search?q={{SelectedText}:P}" }
, { condition: { matchMode: "regex", active: { title: "\.(ahk|ahk2|ah2)" } }, action: "{Run|R}https://www.autohotkey.com/search?q={{SelectedText}:P}" } ]).on()
This Combination Action similar to ConditionCombiAction that switches between two Actions when a Condition is matched or not matched.
It can be defined by specifying an object with the following fields. The condition
field is required.
condition
: A Conditionaction
: An Action to be executed ifcondition
returnstrue
altAction
: An Action to be executed ifcondition
returnsfalse
The following is an example of sending the symbol for the assignment operator according on the file extension of the file being edited. This example is only valid for editors that display the path of the file being edited in the window title.
new CustomHotkey("RCtrl & 1", { condition: { matchMode: "regex", active: { title: "\.(ahk|ahk2|ah2)\b" } }
, action: "{Paste} := "
, altAction: "{Paste} = " }).on()
The condition under which a Action is executed is called to here as a Condition.
Using Condition, you can define a context-sensitive hotkey that is valid only under certain condition.
The following Conditions are defined by the data passed to the third argument of the CustomHotkey constructor.
This data is called here Condition Data.
This Condition enables/disables hotkeys depending on whether the target window is active or existent.
The matching process changes as follows depending on the Condition Data passed.
If an object is specified with a string beginning with {Active}
or the following fields, it will be matched using WinActive. active
field is required.
active
: A window information to match. The following data can be specifiednumber
: A pure number to be treated as a window handle. This is the same as passing the first argument of WinActive with the prefixahk_id
string
: A string beginning with{Active}
. The string is treated as the window title. This is the same as passing it as the first argument of WinActive. You can also specify the following options such as"{Active|Mregex D}"
. If no options are specified,{Active}
can be omittedI
: Set thetrue
toignoreCase
to be described belowM<string>
: Set a string tomatchMode
to be described belowD<string>
: Set thetrue
or a string todetectHidden
to be described below
- An object with the following fields
title
: A window title to matchid
,hwnd
: A window handle to matchclass
: A window class to matchpid
: A process ID to matchexe
: A process name/path to matchgroup
: A window group to matchtext
: A window text to match. Passed to the second argument of WinActiveexcludeTitle
: A window title that should be excluded from the match. Passed to the third argument of WinActiveexcludeText
: A window text that should be excluded from the match. Passed to the fourth argument of WinActive
matchMode
: The following number, string or object can be specified. If omitted, the same as A_TitleMatchMode1
,"forward"
: Change to match forward matching2
,"partial"
: Change to match partial matching3
,"exact"
: Change to match exact matching4
,"backward"
: Change to match backward matching5
,"regex"
: Change to match regex matching- An object with the following fields
title
: A title match mode. Specify a number or string as described abovetext
: A method of detectingtext
andexcludeText
. Specify the following string"fast"
: Detect a text in the control in the normal way"slow"
: Detect more text in the control than"fast"
at the cost of reduced speed
The following five examples all have the same meaning.
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is active", { active: "ahk_exe notepad.exe" }).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is active", { active: { exe: "notepad.exe" } }).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is active", "ahk_exe notepad.exe").on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is active", "{Active}ahk_exe notepad.exe").on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is active", [ "ahk_exe notepad.exe" ]).on()
If a pure number is specified, treated as a window handle. The following is an example of assigning a hotkey to Gui.
Gui, +LastFound
Gui Add, Edit, , Example
Gui Show
guiHwnd := (WinExist() + 0) ; Convert to pure number
new CustomHotkey("RCtrl & 1", "a", guiHwnd).on()
; The following has the same meaning as above
new CustomHotkey("RCtrl & 2", "a", "ahk_id " guiHwnd).on()
If an object is specified with a string beginning with {Exist}
or the following fields, it will be matched using WinExist. exist
field is required.
exist
: A window information to match. The following data can be specifiednumber
: A pure number to be treated as a window handle. This is the same as passing the first argument of WinExist with the prefixahk_id
string
: A string beginning with{Exist}
. The string is treated as the window title. This is the same as passing it as the first argument of WinExist. You can also specify the following options such as"{Exist|Mregex D}"
I
: Set thetrue
toignoreCase
to be described belowM<string>
: Set a string tomatchMode
to be described belowD<string>
: Set thetrue
or a string todetectHidden
to be described below
- An object with the following fields
title
: A window title to matchid
,hwnd
: A window handle to matchclass
: A window class to matchpid
: A process ID to matchexe
: A process name/path to matchgroup
: A window group to matchtext
: A window text to match. Passed to the second argument of WinExistexcludeTitle
: A window title that should be excluded from the match. Passed to the third argument of WinExistexcludeText
: A window text that should be excluded from the match. Passed to the fourth argument of WinExist
matchMode
: The following number, string or object can be specified. If omitted, the same as A_TitleMatchMode1
,"forward"
: Change to match forward matching2
,"partial"
: Change to match partial matching3
,"exact"
: Change to match exact matching4
,"backward"
: Change to match backward matching5
,"regex"
: Change to match regex matching- An object with the following fields
title
: A title match mode. Specify a number or string as described abovetext
: A method of detectingtext
andexcludeText
. Specify the following string"fast"
: Detect a text in the control in the normal way"slow"
: Detect more text in the control than"fast"
at the cost of reduced speed
The following four examples have the same meaning.
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", { exist: "ahk_exe notepad.exe" }).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", { exist: [ "ahk_exe notepad.exe" ] }).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", { exist: { exe: "notepad.exe" } }).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", "{Exist}ahk_exe notepad.exe").on()
If a pure number is specified, it is treated as a window handle. The following is an example of assigning a hotkey to Gui.
Gui, +LastFound
Gui Add, Edit, , Example
Gui Show
guiHwnd := (WinExist() + 0) ; Convert to pure number
new CustomHotkey("RCtrl & 1", "a", { exist: guiHwnd }).on()
; The following has the same meaning as above
new CustomHotkey("RCtrl & 2", "a", { exist: "ahk_id " guiHwnd }).on()
This Condition enables/disables hotkeys depending on the IME status. Note, that this has not been tested with anything other than the Japanese Microsoft IME, so it may not work correctly in other environments.
It can be defined by specifying an object with the following fields. The ime
field is required.
ime
: Iftrue
, enables hotkeys when IME is on, iffalse
, enables hotkeys when IME is off
new CustomHotkey("RCtrl & 1", "a", { ime: true }).on()
new CustomHotkey("RCtrl & 1", "b", { ime: false }).on()
This Condition enables the hotkey when the specified image is found.
It can be defined by specifying an object with the following fields. Many are common to ImageClickAction. The image
field is required.
image
: A path and flag of the image to click. In case of relative path, based on A_WorkingDir. The specification method is the same asImageFile
argument in ImageSearch. Alternatively, you can specify an object with the following fieldspath
: A path of the image. In case of relative path, based on A_WorkingDirpathType
: Change the treatment ofpath
. Specify the following string. It is case-insensitive. If omitted, treated as a file path"bitmap"
: Treat as a bitmap handle"icon"
: Treat as an icon handle
imageNumber
: A image number, if the file specified bypath
(e.g. dll) contains multiple imagesvariation
: A number from0
-255
representing the amount of tolerance when comparing colors; if0
is specified, only exact matches will be matched. Conversely, a value of255
will match all colors. This is used to match a degraded imagetrans
,transparent
: A color to be transparentresize
: A boolean representing whether to resize or not, or an object with the following fields. Default istrue
width
: Width of the image to be loaded. If-0
is specified, the image is not resized. If-1
is specified, the image will be resized keeping the ratioheigth
: Height of the image when loading. If-0
is specified, the image is not resized. If-1
is specified, the image is resized keeping the ratio
targetRect
: A rectangle to use as the search range. Default is"window"
The following is an example of switching between Actions when an image is found and when not found.
; To execute the following example, specify the image path in the `image` field
condition := { image: "path/to/image.png", targetRect: "window" }
new CustomHotkey("RCtrl & 1", "{ToolTip}Image found", condition).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}Image not found").on()
This Condition enables hotkey when the mouse is in the specified position when a Trigger is pressed. It is generally used to implement hot-edge and hot-corner that are executed when a edge/corner of the monitor is clicked.
It can be defined by specifying an object with the following fields. mousepos
field is required.
mousepos
: A rectangle or a string containing a combination of the following prefix and suffix, such as"window-top-left-corner"
- Specify the following prefix. If omitted, it is the same as specifying
"monitor"
"monitor"
,"screen"
: Target the active monitor. You can additionally specify the following strings to change the target monitor-<number>
: Target the monitor with the specified number. e.g."screen-1"
-primary
: Target the primary monitor. e.g."screen-primary"
"monitors"
,"screens"
: Target the virtual monitor. It treats all connected monitors as one."window"
: Target the active window
- Specify the following suffix
"-top-left-corner"
,"-top-left"
: The rectangle representing the top left corner of the target is set"-top-right-corner"
,"-top-right"
: The rectangle representing the top right corner of the target is set"-bottom-left-corner"
,"-bottom-left"
: The rectangle representing the bottom left corner of the target is set"-bottom-right-corner"
,"-bottom-right"
: The rectangle representing the bottom right corner of the target is set"-top-edge"
,"-top"
: The rectangle representing the top edge of the target is set"-bottom-edge"
,"-bottom"
: The rectangle representing the bottom edge of the target is set"-left-edge"
,"-left"
: The rectangle representing the left edge of the target is set"-right-edge"
,"-right"
: The rectangle representing the right edge of the target is set
- Specify the following prefix. If omitted, it is the same as specifying
The following illustration is a rectangle that sets when a string is specified in mousepos
. If you want to change the size of the rectangle representing a edge/corner, specify a number (in pixels) to CustomHotkey.MousePositionCondition.edgeSize
. The default value is 5
.
`top-left` `top` `top-right`
`top-left-corner` `top-edge` `top-right-corner`
┌↓┬───────────────↓───────────────┬↓┐
├─┼───────────────────────────────┼─┤
│ │ │ │
`left` │ │ `screen` │ │ `right`
`left-edge` → │ `monitor` │ ← `right-edge`
│ │ `window` │ │
│ │ │ │
├─┼───────────────────────────────┼─┤
└↑┴───────────────↑───────────────┴↑┘
`bottom-left` `bottom` `bottom-right`
`bottom-left-corner` `bottom-edge` `bottom-right-corner`
monitors
(alias screens
) treat all connected monitors as a virtual one monitor. The following is an example of three monitors placed in a non-rectangular form.
`top-left` `top` `top-right`
`top-left-corner` `top-edge` `top-right-corner`
┌↓┬───────────────↓───────────────┬↓┐
├─┼───────────────┬───────────────┼─┤
│ │ | │ │
│ │ [1] | [3] │ │
`left` │ │ | │ │ `right`
`left-edge` → ├───────────────┼───────────────┤ ← `right-edge`
│ │ | . .
│ │ [2] | . .
│ │ | . .
├─┼───────────────┴ - - - - - - - . .
└↑┴───────────────↑ - - - - - - - -↑-
`bottom-left` `bottom` `bottom-right`
`bottom-left-corner` `bottom-edge` `bottom-right-corner`
The following example opens the start menu by clicking in the right corner of the primary monitor.
new CustomHotkey("LButton", "{LWin}", { mousepos: "screen-primary-right-edge" }).on()
This Condition enables a hotkey only within a specified time after mouse operation.
It can be defined by specifying an object with the following fields. mouseTimeIdle
field is required.
mouseTimeIdle
: A time to enable the hotkey after mouse operation
The following is an example of executing the Windows default shortcut key without pressing Ctrl
for one second after mouse operation.
new CustomHotkey("c", "^{c}", { mouseTimeIdle: "1s" }).on()
new CustomHotkey("v", "^{v}", { mouseTimeIdle: "1s" }).on()
new CustomHotkey("a", "^{a}", { mouseTimeIdle: "1s" }).on()
This User-Defined Condition in function style. If you want to define it in class style, please see here.
It can be defined by specifying a callable object (function, method, BoundFunc, etc.).
The following is an example of switching Actions depending on whether the mouse cursor is positioned on the left or right half of the screen.
new CustomHotkey("RCtrl & 1", "{ToolTip|T3s}The mouse cursor is on the right side of the screen").on()
new CustomHotkey("RCtrl & 1", "{ToolTip|T3s}The mouse cursor is on the left side of the screen", Func("CustomCondition")).on()
CustomCondition() {
MouseGetPos, x
return x < (A_ScreenWidth / 2)
}
The first argument of the specified callable object is passed an object with the following dynamic properties.
title
: Get a window titleclass
: Get a window classahk_class
: Same as above, but prefixed with"ahk_class"
id
: Get a window handleahk_id
: Same as above, but prefixed with"ahk_id"
pid
: Get a process IDahk_pid
: Same as above, but prefixed with"ahk_pid"
exe
: Get a process nameahk_exe
: Same as above, but prefixed with"ahk_exe"
path
: Get a full path of the processtext
: Get a text in the window
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", Func("CustomCondition")).on()
CustomCondition(info) {
return info.exe == "notepad.exe"
}
Since all Conditions are callable objects, they can be specified directly as follows.
new CustomHotkey("RCtrl & 1", "{ToolTip}Notepad is activated", new CustomHotkey.WindowCondition("ahk_exe notepad.exe")).on()
new CustomHotkey("RCtrl & 1", "{ToolTip}VSCode is activated", new CustomHotkey.WindowCondition("ahk_exe Code.exe")).on()
This Condition enables the hotkey when Conditions all match.
It can be defined by specifying an object with the following fields. The and
field is required.
and
: An array of Conditions to match
The following example enables the hotkey only when YouTube is open in Google Chrome.
conditions := [ "ahk_exe chrome.exe"
, "{Active|Mbackward}YouTube - Google Chrome" ]
new CustomHotkey("RCtrl & 1", "{ToolTip}YouTube", { and: conditions }).on()
This Condition enables a hotkey when one of Conditions is matched.
It can be defined by specifying an object with the following fields. The or
field is required.
or
: An array of Conditions to match
The following example enables the hotkey in some browsers.
conditions := [ "ahk_exe chrome.exe"
, "ahk_exe msedge.exe"
, "ahk_exe firefox.exe" ]
new CustomHotkey("RCtrl & 1", "{ToolTip}Browser", { or: conditions }).on()
The CustomHotkey.Group
class is a class for managing hotkeys. It can group hotkeys and change their state at once.
It has a CustomHotkey interface plus an add
method for adding hotkeys to a group.
The add
method has the following signature.
add(hotkey: CustomHotkey) => this
: Add a CustomHotkey instance to the groupadd(trigger: string | string[], action: CustomHotkey.ActionBase, condition?: CustomHotkey.ConditionBase) => this
: Create a CustomHotkey instance then add it to the groupadd({ [key: string | string[]]: CustomHotkey.ActionBase }, condition?: CustomHotkey.ConditionBase) => this
: Add hotkeys at once. The first argument specifies an object with the Trigger as the key and the Action as the value. The second argument can optionally be a Conditionadd(group: CustomHotkey.Group) => this
: Add an instance of theCustomHotkey.Group
class or a class that extends that class to the group
The following example adds a hotkey to the group and enables it.
defaultHotkeys := new CustomHotkey.Group()
defaultHotkeys.add(new CustomHotkey("RCtrl & 1", "a"))
defaultHotkeys.add("RCtrl & 2", "c")
notepadHotkeys := new CustomHotkey.Group()
notepadHotkeys.add(new CustomHotkey("RCtrl & 1", "b", "ahk_exe notepad.exe"))
notepadHotkeys.add("RCtrl & 2", "d", "ahk_exe notepad.exe")
hotkeys := new CustomHotkey.Group()
hotkeys.add(defaultHotkeys)
hotkeys.add(notepadHotkeys)
hotkeys.on()
You can assign the same Action to them by passing an array of Triggers as the first argument of the add
method.
The following two examples mean the same thing.
hotkeys := new CustomHotkey.Group()
hotkeys.add([ "RCtrl & 1", "RCtrl & 2" ], "^{v}")
hotkeys.on()
hotkeys := new CustomHotkey.Group()
hotkeys.add("RCtrl & 1", "^{v}")
hotkeys.add("RCtrl & 2", "^{v}")
hotkeys.on()
You can also define hotkeys at once by passing objects.
hotkeys := new CustomHotkey.Group()
hotkeys.add({ "RCtrl & 1": "a"
, [ "RCtrl & 2", "RCtrl & 3" ]: "b" })
hotkeys.on()
; The second argument can be a condition
notepadHotkeys := new CustomHotkey.Group()
notepadHotkeys.add({ "RCtrl & 1": "c"
, [ "RCtrl & 2", "RCtrl & 3" ]: "d" }, "ahk_exe notepad.exe")
notepadHotkeys.on()
CustomHotkey.Template
is a class to assist in defining hotkeys in a class style.
This class inherits from CustomHotkey.Group class and has the same interface. However, the add
method cannot specify a Condition.
To specify a Condition, define a condition
instance field or method.
new DefaultHotkeys().on()
class DefaultHotkeys extends CustomHotkey.Template {
__NEW() {
this.add("RCtrl & 1", "{ToolTip}1")
this.add({ "RCtrl & 2": "{ToolTip}2", "RCtrl & 3": "{ToolTip}3" })
this.add([ "RCtrl & 4", "RCtrl & 5" ], this.fullscreen)
}
fullscreen() {
WinMove, A, , 0, 0, %A_ScreenWidth%, %A_ScreenHeight%
}
}
new NotepadHotkeys().on()
class NotepadHotkeys extends CustomHotkey.Template {
static condition := "ahk_exe notepad.exe"
__NEW() {
this.add("RCtrl & 1", "{ToolTip}Notepad is activated")
}
}
If condition
is defined as a method, treated as a CustomCondition.
new NotepadHotkeys().on()
class NotepadHotkeys extends CustomHotkey.Template {
condition(winInfo) {
return winInfo.exe == "notepad.exe"
}
__NEW() {
this.add("RCtrl & 1", "{ToolTip}Notepad is activated")
}
}
In addition, the following events are provided, each of which can be used by defining a method.
onExecuting() => any
: Call before the Action starts. The return value is passed as the first argument of theonExecuted
eventonExecuted(dataFromExecuting)
: Call after the Action is done. The first argument is passed the return value of theonExecuting
eventonWindowActivate(winInfo) => any
: Call if the Condition matches when the window changes. This arguments passed are the same as for CustomCondition. The return value is passed as the second argument of theonWindowInactivate
eventonWindowInactivate(winInfo, dataFromActivate)
: Call if the Condition not matches when the window changes. The first argument is the same asonWindowActivate
. The second argument is passed the return value of theonWindowActivate
event
new NotepadHotkeys().on()
class NotepadHotkeys extends CustomHotkey.Template {
condition := "ahk_exe notepad.exe"
__NEW() {
this.add("RCtrl & 1", [ 150, "{ToolTip}1" ])
}
onExecuting() {
OutputDebug Execute Action`n
return A_TickCount
}
onExecuted(startTime_ms) {
elapsedTime_ms := A_TickCount - startTime_ms
OutputDebug Action took %elapsedTime_ms% ms to execute`n
}
onWindowActivate() {
ToolTip Notepad is activated
return A_TickCount
}
onWindowInactivate(activeWindowInfo, startTime_ms) {
elapsedTime_ms := A_TickCount - startTime_ms
ToolTip
OutputDebug, Window was active for %elapsedTime_ms% ms`n
}
}
This class is also available on an instance basis. The first argument of the constructor can optionally be a Condition. The following has the same meaning as in the example above.
notepad := new CustomHotkey.Template("ahk_exe notepad.exe")
notepad.add("RCtrl & 1", [ 150, "{ToolTip}1" ])
notepad.onExecuting := Func("onExecuting")
notepad.onExecuted := Func("onExecuted")
notepad.onWindowActivate := Func("OnWindowActivate")
notepad.onWindowInactivate := Func("OnWindowInactivate")
notepad.on()
OnExecuting() {
OutputDebug Execute Action`n
return A_TickCount
}
OnExecuted(startTime_ms) {
elapsedTime_ms := A_TickCount - startTime_ms
OutputDebug, Action took %elapsedTime_ms% milliseconds to execute`n
}
OnWindowActivate() {
ToolTip Notepad is activated
return A_TickCount
}
OnWindowInactivate(activeWindowInfo, startTime_ms) {
elapsedTime_ms := A_TickCount - startTime_ms
ToolTip
OutputDebug, Window was active for %elapsedTime_ms% ms`n
}
When defining an application with common features, such as a text editor, you may want to make the Trigger common and change only the Action. In that case, use constructor arguments as follows.
; Class-based Actions definition
class NotepadActions {
static condition := "ahk_exe notepad.exe"
static clearLine := "{End}+{Home}{Delete}"
onWindowActivate() {
ToolTip Notepad is activated
}
onWindowInactivate() {
ToolTip
}
}
; Object-based Actions definition
VsCodeActions := { condition: "ahk_exe Code.exe"
, clearLine: "^+k"
, onWindowActivate: Func("OnWindowActivate")
, onWindowInactivate: Func("OnWindowInactivate") }
OnWindowActivate() {
ToolTip VSCode is activated
}
OnWindowInactivate() {
ToolTip
}
; Register hotkeys
new EditorHotkeys(NotepadActions).on()
new EditorHotkeys(VsCodeActions).on()
class EditorHotkeys extends CustomHotkey.Template {
__NEW(actions) {
this.condition := actions.condition
this.add("RCtrl & 1", actions.clearLine)
this.onWindowActivate := actions.onWindowActivate
this.onWindowInactivate := actions.onWindowInactivate
}
}
Each Action class has a static field named defaultOptions
that contains default values for Action Data. By changing the value of this field, you can change the default value of each data.
The following is an example of changing the default value of SendAction.
CustomHotkey.SendAction.defaultOptions.mode := "Input"
CustomHotkey.SendAction.defaultOptions.limitLength := 1
new CustomHotkey("RCtrl & 1", "{a}{b}{c}").on()
Set the following string to set the specified point as the origin of coordinates.
"monitor"
,"screen"
: Set the origin to the top left corner of the active monitor. You can change the target monitor by specifying the following suffix such as"monitor-primary"
-<number>
: Set the origin to the upper left corner of the monitor of the specified number. e.g."monitor-1"
-primary
: Set the origin at the upper left corner of the primary monitor. e.g."monitor-primary"
"monitors"
,"screens"
: Set the origin to the upper left corner of the virtual monitor, which treats all connected monitors as one. If you want to specify absolute coordinates, it is recommended to specify this instead of"monitor"
"window"
: Set the origin to the top left corner of the active window"mouse"
: Set the origin to the top left of the mouse cursor"caret"
: Set the origin to the top left of the caret (input position)
The position of the origin can be adjusted by adding the following suffix such as "window-top-center"
. If omitted, the same as when -top-left
is specified.
-top-left
-top-center
,-top
-top-right
-middle-left
,-left
-middle-center
,-center
-middle-right
,-right
-bottom-left
-bottom-center
,-bottom
-bottom-right
The adjustment position of the origin is as follows respectively.
`top`
`top-left` `top-center` `top-right`
↓ ↓ ↓
□───────────────□───────────────□
| `center` |
| `middle-center` |
`left` │ ↓ │ `right`
`middle-left` → □ □ □ ← `middle-right`
│ │
│ │
│ │
□───────────────□───────────────□
↑ ↑ ↑
`bottom-left` `bottom-center` `bottom-right`
`bottom`
The "monitors"
(alias "screens"
) treats all connected monitors as a virtual one monitor. The following illustration is an example of the suffix adjustment when three monitors are placed in a non-rectangular configuration.
`top`
`top-left` `top-center` `top-right`
↓ ↓ ↓
□───────────────□───────────────□
| | │
| [1] | [3] │
`left` │ | │ `right`
`middle-left` → □───────────────□───────────────□ ← `middle-right`
│ │ ↖ .
│ [2] │ `center` .
│ │`middle-center`.
□───────────────□ - - - - - - - □
↑ ↑ ↑
`bottom-left` `bottom-center` `bottom-right`
`bottom`
Some Actions can specify the following data representing a rectangle
- the following string
"screen"
,"monitor"
: It is converted to the rectangle data of the active monitor. The target monitor can be changed by specifying the following suffix-<number>
: Target the monitor with the specified number. e.g."monitor-1"
-primary
: Target the primary monitor. e.g."monitor-primary"
- An object with the following fields. e.g.
{ x: 0, y: 0, width: 30, height: 30 }
x
: A x-coordinate of the rectangley
: A y-coordinate of the rectanglewidth
: A width of the rectangleheight
: A height of the rectangleorigin
: An origin of thex
andy
coordinates. Default is"monitors"
- An array consisting of objects with the following fields. e.g.
[ { x: 0, y: 0 }, { x: 30, y: 30 } ]
x
: A number representing the x-coordinate of the start or end pointy
: A number representing the y-coordinate of the start or end pointorigin
: An origin of thex
andy
coordinates. Default is"monitors"
- An array of arrays with the following two or three elements. e.g.
[ [ [ 0, 0 ], [ 30, 30 ]
- A number representing the x-coordinate of the start or end point
- A number representing the y-coordinate of the start or end point
- An origin of the coordinates. If omitted,
"monitors"
is used
In some Actions there is an opportunity to specify a time.
In addition to specifying the time as a number, the unit of time can be changed by adding the following suffix. If no suffix is added, the unit is milliseconds.
ms
: Change the unit to milliseconds. Can be omitted, but used if you want to make the units clears
: Change the unit to secondsm
: Change the unit to minutesh
: Change the unit to hours
This library supports data representing the following RGB.
- CSS color keywords from Lv1 to Lv4 such as
"red"
- Hexadecimal color codes such as
0xFF0000
- HTML format color codes such as
#FF0000
Some Actions use a template string to embed the value of a variable in a string.
The format extends that of the Format function, with the following additional formats available.
- Embed the value of a variable by specifying its name, such as
"{variable}"
. But some variables, such as A_ThisFunc, do not work correctly. It also has the following features- If the variable is an object, you can also specify the field as
"{variable.field}"
- If the value of the variable is a callable object such as a function, its return value is embedded
- If the variable is an object, you can also specify the field as
- The following dedicated variables are available
{SelectedText}
: Embed the currently selected text{Monitor}
: Embed the primary monitor's bounding coordinates in the form"top,left,right,bottom"
. It has the following features- Specifying
MonitorWorkArea
instead ofMonitor
will get the bounding coordinates of the work area excluding the taskbar, etc. - Specifying the following string after
Monitor
orMonitorWorkArea
, such asMonitorTop
, will embed only a part of the bounding coordinates. It is case-insensitiveTop
: Embed the upper bounding coordinatesLeft
: Embed the left bounding coordinateRight
: Embed right bounding coordinatesBottom
: Embed the bottom bounding coordinates
- You can target a specific monitor by specifying a numeric value representing the monitor number at the end. If omitted, the primary monitor is targeted
- Specifying
- If you specify a number such as
{80}
, the information is retrieved using SysGet and embedded in the template
- If you want to convert a part of a string without using variables, enclose the string in single quotation marks, such as
"A{'B':L}C"
. In this example,"AbC"
is output - In addition to the format specifier of the Format function, the following additional specifiers are case-sensitive
W
: Convert the value to a whitespace delimiter, such as"abc abc"
. Combined with theU
orT
specifier, it can be converted to word capitalization ("Abc Abc"
) or a sentence case ("Abc abc"
), respectivelyS
: Convert the value to a snake case, such as"abc_abc"
K
: Convert the value to a kebab case, such as"abc-abc"
C
: Convert the value to a camel case, such as"AbcAbc"
. Combined with theU
orL
specifier, it can be converted to upper camel case ("AbcAbc"
) or lower camel case ("abcAbc"
), respectivelyP
: Convert by percent encodingB
: Escape some characters with backslash using percent encoding. Valid only if theP
option is specifiedQ
: Enclose the value in double quotesq
: Enclose the value in single quotes
The following is an example of using PasteAction to replace a selection string with an upper snake case.
new CustomHotkey("RCtrl & 1", "{Paste|R}{{SelectedText}:US}").on()
Although this library provides many Actions, it will not satisfy all users requirements.
In that case, you can define your own Actions and register them with CustomHotkey
. Registered Actions can be handled in the same way as existing Actions.
If you want to define an Action in function style, see CustomAction.
How to define a Combination Action is the same. In this library, an Action that switches between two or more Actions is called a Combination Action.
You are free to name your Action, however, recommend that classes treated as Action end with Action
and classes treated as Combination Action with CombiAction
.
To define an Action, you need to extend CustomHotkey.ActionBase
and define the following methods.
isActionData(data: any) => boolean
: Determine if the passeddata
is used by this Action.CustomHotkey
uses this method to automatically select an Actioncall(params*: any[]) => any
: Define an Action to be executed. Arguments and return value are optional
If you want to normalize a data, define the following additional method.
normalizeActionData(data: any) => any
: Normalize the data passed as the first argument and must be returns the normalized data. If omitted, thesetDefaultOptions
method described below will set default values for the data
Utility methods are also provided for data normalization.
setDefaultOptions(data: object, defaultOptions := "defaultOptions") => any
: Set default values for the given data. Normally not required,defaultOptions
argument is the name of an object with default values for the data or a static field containing those values
If you want to execute another Action from within an Action, use the executeAction
method. This method will execute the corresponding Action by passing the Action Data as its first argument.
The following is an example of executing the specified string at the command prompt. The CustomHotkey.Action.add
is described in the following section.
CustomHotkey.Action.add(CommandPromptAction)
new CustomHotkey("RCtrl & 1", { command: "echo example", wait: false, pause: true }).on()
class CommandPromptAction extends CustomHotkey.ActionBase {
static defaultOptions := { command: "", wait: true, pause: false }
isActionData(data) {
return IsObject(data) && ObjHasKey(data, "command")
}
call() {
data := this.data
command := data.command
if (data.pause) {
command .= " & pause"
}
this.executeAction({ run: A_ComSpec
, args: [ "/c", command ]
, wait: data.wait })
}
}
The defined Action can be registers by passing it as the first argument of the CustomHotkey.Action.add
method.
CustomHotkey.Action.add(ExampleUserDefinedAction)
Like Action, Condition can also be defined freely by the user.
If you define a Condition in function style, see CustomCondition.
Recommended that class names treated as Condition be suffixed with Condition
.
To define an Condition, you need to extend CustomHotkey.ConditionBase
and define the following methods.
isConditionData(data: any) => boolean
: Determine if the passeddata
is used by this Condition.CustomHotkey
uses this method to automatically select a Conditioncall(params*: any[]) => boolean
: Defines a Condition matching process. Arguments is optional. It should returntrue
if the condition is matched andfalse
otherwise
If you want to normalize the data, define the following additional methods. These methods are common to User-Defined Action.
normalizeActionData(data: any) => any
: Normalize the data passed as the first argument and must be returns the normalized data. If omitted, thesetDefaultOptions
method described below will set default values for the data
Utility methods are also provided for data normalization.
setDefaultOptions(data: any, defaultOptions := "defaultOptions") => any
: Set default values for the given data. Normally not required,defaultOptions
is the name of an object with default values for the data or a static field containing those values
The following is an example of a user-defined condition that assigns a different action to each user. The CustomHotkey.Condition.add
is described in the next section.
CustomHotkey.Condition.add(UserCondition)
new CustomHotkey("RCtrl & 1", "{ToolTip}Logon " . A_UserName, { user: A_UserName }).on()
new CustomHotkey("RCtrl & 2", "{ToolTip}Logon user_b", { user: "user_b" }).on()
new CustomHotkey("RCtrl & 2", "{ToolTip}user_b is not login").on()
class UserCondition extends CustomHotkey.ConditionBase {
isConditionData(data) {
return IsObject(data) && ObjHasKey(data, "user")
}
call() {
return this.data.user == A_UserName
}
}
The defined Condition can be registers by passing it as the first argument of the CustomHotkey.Condition.add
method.
CustomHotkey.Condition.add(ExampleUserDefinedCondition)
If you want to change the Action, Condition or etc. processing depending on the Trigger status, CustomHotkey.Trigger
class is useful.
This constructor's first argument is a Trigger string. Normally, specify A_ThisHotkey.
This instances have the following members.
raw: string
: Return the string passed to the constructorisCombination: boolean
: Get a boolean value representing whether the Trigger is a combination key such asa & b
. Returnsfalse
if+^!b
isReleaseMode: boolean
: Get a boolean value representing whether the Action is executed on release, such asa up
modifiers: string[]
: Get an array of modifier keys for the Trigger. If+^!a
you get[ "Shift", "Ctrl", "Alt"]
, ifa & b
you get[ "a" ]
.key: string
,suffixKey
: Get a non-modifier key of the Trigger. For+^!a
you geta
, fora & b
you getb
pressing: boolean
: Get a boolean value representing whether the key retrieved bykey
is being pressed or notpressingModifiers: boolean
: Get a boolean value representing whether all keys retrieved bymodifiers
are being pressedpressingAll: boolean
: Get a boolean value representing whether all keys of the Trigger are being pressedequals(trigger: string | CustomHotkey.Trigger) => boolean
: Determines if the same as the specified Triggerincludes(key: string) => boolean
: Determines if the specified key is included in the Triggerrelease() => this
: Virtually release of the key retrieved withkey
releaseModifiers() => this
: Virtually release all keys retrieved withmodifiers
.releaseAll() => this
: Virtually release all keys of the TriggerwaitRelease() => void
: Wait until the key retrieved withkey
is releasedwaitReleaseModifiers() => void
: Wait until all keys retrieved withmodifiers
is releasedwaitReleaseAll() => void
: Wait until all keys of the Trigger is released
The following are aliases for handling combination key such as a & b
.
prefixKey: string
: Same asmodifiers[1]
, but returns an empty string if not a combination key, such as+^!b
secodnKey: string
,suffixKey: string
: Same askey
new CustomHotkey("RCtrl & 1", Func("SendKeyWithShift")).on()
new CustomHotkey("RCtrl & 2", Func("SendKeyWithShift")).on()
new CustomHotkey("RCtrl & 3", Func("DisplayTooltipWhilePressedTrigger")).on()
SendKeyWithShift() {
trigger := new CustomHotkey.Trigger(A_ThisHotkey)
key := trigger.key
SendInput, +{%key%}
trigger.waitRelease()
}
DisplayTooltipWhilePressedTrigger() {
trigger := new CustomHotkey.Trigger(A_ThisHotkey)
ToolTip, Pressing trigger
while (trigger.pressingAll) {
Sleep, 50
}
ToolTip
}