This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Lua API cheat sheet
Quick reference for the evil.* API. Full explanations in the Lua API guide.
Hooks
All hooks receive a ctx table with common fields: ctx.event, ctx.state (full snapshot), ctx.super, ctx.alt, ctx.ctrl, ctx.shift, ctx.pointer. Hook-specific extras listed below.
-- Define hooks directly
function evil.on.key(ctx) end
function evil.on.resolve_focus(ctx) end
function evil.on.move_update(ctx) end
| Hook | Extras | Fires when |
|---|---|---|
key |
ctx.key (name like "H", "Return"), ctx.focused |
Key pressed |
resolve_focus |
ctx.reason ("window_mapped", "pointer_button", "window_unmapped"), ctx.button, ctx.pressed, ctx.previous |
Focus decision needed |
focus_changed |
ctx.previous_window, ctx.focused_window |
Focus moves |
place_window |
ctx.window — may set bounds before map |
New window about to appear |
window_mapped |
— | Window finished mapping |
window_unmapped |
— | Window removed |
window_property_changed |
ctx.property, ctx.old_value, ctx.new_value |
Title, app_id, etc. changes |
move_begin |
— | Interactive move starts |
move_update |
ctx.dx, ctx.dy |
Pointer moves during drag |
move_end |
ctx.dx, ctx.dy, ctx.pointer |
Drag finishes |
resize_begin |
ctx.edges ({ left, right, top, bottom }) |
Interactive resize starts |
resize_update |
ctx.dx, ctx.dy, ctx.edges |
Pointer moves during resize |
resize_end |
ctx.dx, ctx.dy, ctx.pointer, ctx.edges |
Resize finishes |
gesture |
ctx.kind ("swipe" / "pinch"), ctx.fingers, ctx.dx, ctx.dy, ctx.scale |
Trackpad gesture |
draw_background |
ctx.output.viewport |
Emit background shapes |
draw_window_overlay |
ctx.focused_window |
Emit shapes over focused window |
draw_overlay |
— | Emit shapes on top of everything |
For full context field reference: Hook payload summary.
Window commands
| Call | Description |
|---|---|
evil.window.focus(id) |
Focus a window |
evil.window.clear_focus() |
Clear focus |
evil.window.focused() |
Return focused window table or nil |
evil.window.next() |
Cycle focus to next window (MRU) |
evil.window.prev() |
Cycle focus to previous window |
evil.window.move(id, x, y) |
Move to world position |
evil.window.resize(id, w, h) |
Resize (clamped to min/max) |
evil.window.set_bounds(id, x, y, w, h) |
Set position and size |
evil.window.begin_move(id) |
Start interactive mouse drag |
evil.window.begin_resize(id, edges) |
Start interactive resize |
evil.window.set_floating(id, bool) |
Set floating state |
evil.window.toggle_floating(id) |
Toggle floating state |
evil.window.close(id) |
Close a window |
evil.window.list() |
Array of all window snapshot tables |
evil.window.get(id) |
One window snapshot or nil |
-- Window snapshot fields
window.id window.app_id window.title
window.x window.y window.w
window.h window.floating window.focused
window.exclude_from_focus window.fullscreen window.maximized
window.urgent window.mapped window.pid
window.mapped_at window.last_focused_at window.output_id
window.bounds
Resize edges: { left = true, right = false, top = false, bottom = true } — all four required.
Canvas commands
| Call | Description |
|---|---|
evil.canvas.pan(dx, dy) |
Pan the viewport by a world-space delta |
evil.canvas.zoom(factor) |
Zoom by a multiplier (e.g. 1.15) |
evil.canvas.overview() |
Fit all windows on screen |
evil.canvas.home() |
Reset viewport to origin at zoom 1.0 |
evil.canvas.viewport() |
Return viewport snapshot table |
-- Viewport snapshot fields
viewport.x viewport.y viewport.world_x
viewport.world_y viewport.zoom viewport.screen_w
viewport.screen_h viewport.visible_world -- { x, y, w, h }
Output queries
| Call | Returns |
|---|---|
evil.output.list() |
Array of output snapshots |
evil.output.get(id) |
One output or nil |
evil.output.primary() |
Primary output or nil |
evil.output.at_pointer() |
Output under pointer or nil |
-- Output snapshot fields
output.id output.viewport -- viewport table
output.logical_x output.logical_y
Pointer
evil.pointer.position() -- { x, y }
Spawn
evil.spawn("foot") -- runs through sh -c
Config-time
These only work during config loading, not inside hooks.
evil.config({ table }) -- set options (all fields optional with defaults)
evil.bind(keyspec, name, { amount? command? }) -- register a binding
evil.autostart(cmd) -- run command at startup
Most keys are best handled in function evil.on.key(ctx) instead of evil.bind(). Use evil.bind() when you need the simple declarative approach.
Config table
evil.config({
canvas = { min_zoom = 0.2, max_zoom = 4.0 },
draw = { clear_color = { 0.08, 0.05, 0.12, 1.0 } },
window = { hide_client_decorations = true },
placement = { default_size = { w = 900, h = 600 } },
tty = { quit_keyspec = "Ctrl+Alt+Backspace" },
rules = {
{ app_id = "foot", floating = true, size = { w = 900, h = 600 } },
},
})
Draw primitives
Only available in draw hooks (draw_background, draw_window_overlay, draw_overlay). Returns a draw command to include in the return array.
evil.draw.rect({ x, y, w, h, color, space? })
evil.draw.stroke_rect({ x, y, w, h, width, color, space?, outer? })
evil.draw.line({ x1, y1, x2, y2, width, color, space? })
evil.draw.circle({ x, y, radius, width, color, space? })
evil.draw.filled_circle({ x, y, radius, color, space? })
evil.draw.text({ x, y, text, color, space?, font_size? })
Common fields:
space—"world"(default, canvas coordinates) or"screen"(pixels)color—{ r, g, b, a }with values 0.0–1.0width— stroke width in pixels (must be > 0)radius— in pixels (must be > 0)
Built-in binding actions
For evil.bind() only. Not needed if you use function evil.on.key(ctx).
| Name | Effect |
|---|---|
pan_left / pan_right / pan_up / pan_down |
Pan canvas |
zoom_in / zoom_out |
Zoom canvas |
focus_next / focus_prev |
Cycle focus |
close_window |
Close focused window |
spawn |
Run a command ({ command = "..." }) |
quit |
Exit compositor |
See also
- Lua API guide — full explanations with examples
- Hook payload summary — every hook's context fields
- Hooks guide — how to combine hooks into policies
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