Table of Contents
- Queries, commands, and actions
- 1. Queries: read current state
- 2. Commands: change state directly
- 3. Actions: describe what should happen
- Which style should you use?
- Examples side by side
- A note about spawn
- Common mistakes
- Returning the wrong hook shape
- Confusing queries and commands
- Using a command when the hook wants a returned action style
- Read next
Queries, commands, and actions
This page explains the three main ways Lua interacts with runtime state:
- queries
- direct commands
- returned actions
Understanding the difference makes configs much easier to read and design.
In the current evil examples, direct commands are the default style.
Returned actions are still supported when they make a hook clearer.
1. Queries: read current state
Queries do not change anything. They just ask for information.
Examples:
evil.state()evil.window.get(id)evil.window.focused()evil.output.list()evil.output.primary()evil.pointer.position()evil.canvas.viewport()
Example
local focused = evil.window.focused()
if focused then
print(focused.title)
end
2. Commands: change state directly
Commands apply a change immediately.
Examples:
evil.window.focus(id)evil.window.move(id, x, y)evil.window.resize(id, w, h)evil.window.set_bounds(id, x, y, w, h)evil.window.close(id)evil.canvas.pan(dx, dy)evil.canvas.zoom(factor)
Example
evil.on.move_update = function(ctx)
evil.window.move(ctx.window.id, ctx.window.x + ctx.dx, ctx.window.y + ctx.dy)
end
Return values
Commands usually return:
trueon successfalseif the target is invalid or the operation is rejected
3. Actions: describe what should happen
Instead of mutating state directly, a hook can return an action table.
Example:
return {
kind = "move_window",
id = ctx.window.id,
x = ctx.window.x + ctx.dx,
y = ctx.window.y + ctx.dy,
}
Or several actions:
return {
actions = {
{ kind = "focus_window", id = ctx.window.id },
{ kind = "begin_move", id = ctx.window.id },
}
}
This is still useful when a hook wants to describe several related operations together.
For a complete list of queries, commands, and returned actions, see the Lua API cheat sheet.
Which style should you use?
Prefer queries when:
- you only need to inspect state
- you are deciding what to do next
Prefer commands when:
- you want simple direct behavior
- the hook is tiny
- you want a quick prototype
- you want to match the default style used by the current examples
Prefer returned actions when:
- the hook is clearer as a description than as a sequence of commands
- you want to return several related operations together
Examples side by side
Direct command style
evil.on.move_update = function(ctx)
evil.window.move(ctx.window.id, ctx.window.x + ctx.dx, ctx.window.y + ctx.dy)
end
Returned action style
evil.on.move_update = function(ctx)
return {
kind = "move_window",
id = ctx.window.id,
x = ctx.window.x + ctx.dx,
y = ctx.window.y + ctx.dy,
}
end
Both are valid. The second is still useful in more structured configs, but the current examples prefer the first style by default.
A note about spawn
There are two related ways to launch things:
Bindings
evil.bind("Super+Return", "spawn", { command = "foot" })
Imperative command from a hook
evil.spawn("foot")
That is now the default example style when a key hook wants full ownership of launch behavior.
Common mistakes
Returning the wrong hook shape
Good:
return nil
return { kind = "focus_window", id = 10 }
return { actions = { ... } }
Bad:
return { 1, 2, 3 }
Confusing queries and commands
evil.window.get(id)reads stateevil.window.move(id, x, y)changes state
Using a command when the hook wants a returned action style
This is not always wrong, but if a hook becomes hard to follow, returning actions can make it clearer.
Read next
evil wiki
- Home
- Getting started
- Architecture and philosophy
- Configuration guide
- Writing your first config
- Lua basics for evil users
- Lua API guide
- Lua API cheat sheet
- Hooks guide
- Hook payload summary
- Queries, commands, and actions
- Drawing and visuals
- Example configs overview
- Example shared helpers and rules
- IPC protocol
- Testing and debugging
- Contributor validation matrix
- Feature status and limitations
- Feature and support matrix
- Recipes