Modules [v2.1-alpha.11+]

A module is basically a script within the script. Each module has its own:

Splitting the components of a script into modules can make the components easier to reuse and maintain.

By default, all lines of code and global variables (including functions and classes) are added to an implicitly-defined module named "__Main". The script can start a new module with #Module or load one from file with #Import.

An #Import directive can be used to make a module or some of its functions, classes and variables accessible within the current module.

All modules implicitly import from the built-in "AHK" module, which contains all built-in classes, variables and functions outside the KS module. A declaration or assignment within a module can reuse the name of a built-in class or function, in which case that class or function is not accessible except through the AHK module (e.g. #Import AHK, AHK.MsgBox()). Built-in (A_) variables do not require a declaration or explicit import to allow assignment, and a declaration or assignment cannot create a new variable with the same name. An explicitly imported alias can use such a name. In AutoHotkey v2.1, A_Args is the exception (it is a normal variable defined in __Main). In Keysharp, A_Args is a built-in variable which every module and function shares.

Named imports can introduce normal variables into AHK. These variables are available through implicit global lookup unless the current module declares or assigns the same name.

A module name is added to a module's global namespace only when imported, and conflicts can be resolved by giving the imported module an alias within the destination module.

#Include is able to include a file once per module.

#Warn can enable or disable warnings within the current module without affecting other modules. For details, see the #Warn remarks.

#HotIf affects only the current module. #HotIf and HotIf expressions are module-scoped, as they may contain references to module-level variables. For instance, the effect of #HotIf myToggle depends on what value myToggle has in the current module.

Module.__Ref [v2.1-alpha.33+]

Retrieves a VarRef for a module's global variable or explicitly imported name.

Reference := ModuleObject.__Ref(Name)

Name is the name of a member in the module, including a named or wildcard import. Imports may pass a name through multiple modules: every alias reaches the original variable and returns its reference. Bare and dynamic references to an explicitly imported variable share this reference and its native string memory. If the name cannot be resolved, the method returns unset without creating a variable.

A reference to a function, class or read-only built-in variable can be read, but assigning through it raises a read-only error.

Retrieving the reference does not read the variable's value. If that value is another VarRef, the returned reference still points to the variable holding it.

The reference operator uses this method: &ModuleObject.Member is equivalent to ModuleObject.__Ref("Member").

KS Module

The built-in KS module exports Keysharp-specific classes, functions and variables. A script must import a name to use it, and the names are not members of the AHK module.

#Import "Ks" { Image, A_DirSeparator }

Capture := Image.FromDesktop()
MsgBox A_DirSeparator

New methods or properties added to an existing built-in class, such as Array or Buffer, are available without importing KS.

The full set of exports is listed below.

Classes

ExportDescription
AppThe running application: its assembly identity and metadata, the command line it was launched with, and the exit in progress.
AudioPlays sounds from files or memory, operates audio devices and application sessions, meters levels, and records from a microphone or an output device.
Base64Converts between binary data and Base64 text.
BooleanThe type of a truth value, so that a boolean can be told apart from the Integer 1 or 0.
ClipboardReads and writes the system clipboard as text, images, files, HTML, RTF or a native format.
ClipboardHookThe EventHook returned by Clipboard.OnChange.
ClrLoads .NET assemblies and calls into them from a script.
CryptHashes values and files, encrypts and decrypts with AES, derives keys from passwords, and returns cryptographically secure random values.
EventHookThe base class of every event subscription, InputHook included: Start, Stop, InProgress and EndReason.
FontA font as a value object, plus the platform's standard interface, emoji and monospace families.
HashMapAn unordered hash table, faster than Map where ordering is not needed.
HighlightOutlines a region of the screen with a colored, click-through border.
HttpSends HTTP requests, as static shortcuts or as a session carrying headers, credentials and cookies.
Http.ResponseWhat a server answered: status, headers and body.
ImageCaptures, loads, draws, manipulates and saves images.
JsonConverts between JSON text and Keysharp objects.
LockA mutual-exclusion lock guarding code shared between real threads.
MonitorOne display: identity, metadata, brightness and DDC/CI control, and display-change notifications.
MonitorHookThe EventHook returned by Monitor.OnChange.
NamedArgsCarries the named arguments of one call, for building or inspecting them at run time.
OverlayDraws a click-through, always-on-top surface over the screen.
RealThreadRuns a callback on a real operating-system thread, and marshals work to and from it.
StringBufferA mutable text buffer for building large strings efficiently.
TaskWork that finishes later, such as the result of an asynchronous .NET call.
TaskbarDraws a badge and a progress bar on a window's taskbar button.
UrlPercent-encodes and decodes text for URLs and form bodies.
WinEventCalls a function when windows are created, activated, moved or closed.

Functions

ExportDescription
ATan2Returns the arc tangent of y/x, using the signs of both values to determine the quadrant.
AwaitWaits for work which finishes later and returns its value.
ClipCursorConfines the mouse cursor to a region of the screen, or releases it.
CollectRuns a garbage collection.
CompileScriptCompiles source in memory without running it and reports its errors and warnings.
CoshReturns the hyperbolic cosine.
FileCreateTempCreates a uniquely named temporary file.
FileFullPathExpands a path to its absolute form.
FormatCsFormats a string using .NET composite formatting.
GetKeyboardLayoutReturns the keyboard layout of a window or thread.
GetKeyInfoReturns the characters a key produces under a keyboard layout.
IsComponentAvailableReports whether the parser or compiler component is installed, compatible and loadable.
MailSends an email message over SMTP.
OutputDebugLineWrites a line to the system debug output.
RandomSeedSeeds the pseudo-random number generator.
RegExMatchCsMatches a .NET regular expression.
RegExReplaceCsReplaces text using a .NET regular expression.
ReplaceLineEndingsConverts line endings in a string to a single form.
RequestCapabilitiesRequests optional platform capabilities the script needs.
RunScriptCompiles and runs source code, returning a process object.
ShowDebugShows or hides the debug output window.
SinhReturns the hyperbolic sine.
TanhReturns the hyperbolic tangent.
ValidateScriptChecks the syntax of source without compiling or running it.
WinFromPointReturns the window at a screen point.

Variables

The KS module's variables are listed under KS Module Variables.

Execution

The body of each module is executed eagerly at program startup, by the auto-execute thread. A module normally executes after the modules it imports. Declaration order resolves modules which are otherwise unrelated or form a cycle.

This eager, import-aware order is a Keysharp difference from AutoHotkey v2.1, which starts from the last-defined module and can execute another module lazily when one of its variables or constants is first referenced. For example:

#module A
MsgBox "A executing"  ; Shown first.
global ANSWER := 42

#module B
#import A {ANSWER}
MsgBox "B executing"  ; Shown second.
MsgBox ANSWER

Search Path [v2.1-alpha.20+]

The module search path is a list of directories which the #Import statement looks in to find module files. The directory of the file which contains the #Import directive is always searched first. The AhkImportPath environment variable can contain a semicolon-delimited list of additional directories to search. If it is not defined, the default list is as follows:

%A_ScriptDir%;%A_MyDocuments%\AutoHotkey;%A_AhkPath%\..

Built-in variables may be used in the value of AhkImportPath by enclosing them in percent signs. Any percent signs which are not part of a valid variable reference are interpreted literally. References to environment variables are not resolved by AutoHotkey, as they are typically resolved before the process starts. List items can be absolute paths or relative to the directory containing the script (A_ScriptDir). The list is resolved only once, so A_LineFile always refers to the main script.

Directories are searched in the order they are listed. Within each directory, files are considered in this order:

For example, #Import M may load the file with exact name M, M\__Init.ahk or M.ahk. #Import "M" is the same except that the name M is not added to the current module.

Examples

Each module has its own global variables (MyVar and ShowVar).

#Import Other
MyVar := 1
      ShowVar()  ; Our MyVar is 1.
Other.ShowVar()  ; Other MyVar is still 2.
MsgBox "Within main, Other.MyVar = " (Other.MyVar ?? "inaccessible")  ; MyVar is accessible in v2.1-alpha.19+.
ShowVar() => MsgBox("Main MyVar = " MyVar)

#Module Other
MyVar := 2
ShowVar() => MsgBox("Other MyVar = " MyVar)

Use an alias to resolve a conflict. Each module has its own Calculate, which takes precedence over any wildcard import.

#Import "X" {Calculate as CalculateX}
#Import "Y" {*}

MyVar := 1
MsgBox Calculate()
MsgBox CalculateX()
MsgBox Check(3)
MsgBox "X = " (X ?? "not imported")
MsgBox "Y = " (Y ?? "not imported")

Calculate() => 1

#Module X
Calculate() => 2

#Module Y
Calculate() => 3
Check(n) => n = Calculate()

Access shadowed built-in functions.

#import AHK

MsgBox "Hello, world!",, "T2"

; Add the Info icon by default.
MsgBox(Text?, Title?, Options:="") {
    return AHK.MsgBox(Text?, Title?, "Iconi " Options)
}

#Module Other
MsgBox "Other still has the original MsgBox.",, "T2"