Writing KSL
KSL is the Keybind Scripting Language. It reads like JavaScript or Python, with real variables, functions, and control flow — plus keyboard-first constructs like bind and hotstring built into the language. This page covers the fundamentals; every builtin is in the Function Library.
Binds
A bind maps a key or combo to an action:
bind Ctrl+Alt+H => notify("Hello!")
# A multi-line body goes in braces
bind Win+Up => {
snap_to("max")
notify("Maximized")
}Hotstrings
Type an abbreviation, get an expansion:
hotstring "kb" => "Keybind"
hotstring "sll" => "Stanbren LLC"Variables and types
Declare with let. Values are numbers, strings, booleans, null, arrays, and maps. String interpolation uses {...}:
let name = "Ada"
let count = 3
let tags = ["work", "urgent"]
let user = { id: 1, name: "Ada" }
notify("Hello {name}, you have {count} items")Functions
Functions are first-class — name them, or pass them inline as closures:
fn greet(name) {
return "Hello, {name}"
}
let words = str_split("the quick brown fox", " ")
let long = arr_filter(words, fn(w) { return str_len(w) > 3 })Control flow
if count > 0 {
notify("has items")
} else {
notify("empty")
}
for word in words {
notify(word)
}Error handling
Wrap fallible calls in try/catch:
try {
let data = file_read("C:/inbox/orders.csv")
} catch (e) {
notify("Failed: {e.message}")
}Capabilities
Anything sensitive — the filesystem, network, clipboard, launching processes, AI — is gated behind a capability. A script declares the ones it uses at the top, and Keybind asks your approval once, then remembers it:
#! requires: process, notify
on_load {
on_interval(5000, fn() {
if !process_exists("notepad.exe") { run("notepad.exe") }
})
}The tokens include filesystem, network, clipboard, process, window, display, notify, store, ai, and more. Declare only what you actually use — the Function Library lists the capability each builtin needs.
Resident scripts
A script that declares on_load, bind, hotstring, or a timer becomes a resident Script Module: it loads once, keeps persistent global state, and reacts to events in the background (great for always-on watchers). A plain per-fire snippet, by contrast, just runs and exits.
> The complete single-file language spec ships with the app and lists every builtin. For the searchable online version, see the Function Library.