Skip to content

Navigation

Navigation actions move focus between windows without changing their positions. This page focuses on behavior and examples. For the full action list and defaults, see Actions reference.

Directional focus

Move focus in a direction relative to the currently focused window:

spoon.Shoji:bindHotkeys({
focus_left = { { "ctrl", "alt" }, "h" },
focus_down = { { "ctrl", "alt" }, "j" },
focus_up = { { "ctrl", "alt" }, "k" },
focus_right = { { "ctrl", "alt" }, "l" },
})

How it works

Given this tall layout:

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ │ 2 │
│ │ │
│ │ │
│ │ │
│ 1 ├─────────────────────────────┤
│ │ │
│ │ │
│ │ │
│ │ 3 │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

With focus on window 1:

  • focus_right focuses window 2 (same row, nearest to the right)
  • focus_down focuses window 3 (nearest window below)

The algorithm:

  1. Finds all windows in the target direction
  2. Prefers windows aligned in the same row (left/right) or column (up/down)
  3. For up/down, falls back to the nearest window in that direction
  4. For left/right, no fallback is used (no aligned window = no change)

Order-based focus

Move focus through windows by stack order rather than position:

spoon.Shoji:bindHotkeys({
focus_next = { { "ctrl", "alt" }, "n" },
focus_prev = { { "ctrl", "alt" }, "p" },
})

How it works

Window order is tracked by Shoji and updated on new windows and swaps. New windows are usually inserted after the last focused window. The order wraps around at both ends:

Window order: [1, 2, 3]
focus_next from 1 → 2
focus_next from 2 → 3
focus_next from 3 → 1 (wraps to start)
focus_prev from 1 → 3 (wraps to end)

When no window has focus

If no tiling window is focused, any navigation action focuses the first window in the stack order.

Floating windows

Navigation actions skip floating windows entirely. To focus a floating window, click it directly or use macOS window switching (Cmd+Tab, Mission Control).

Fullscreen layout

In fullscreen layout, all windows occupy the same screen position. Directional focus has no effect. Use focus_next and focus_prev instead.

Vim-style navigation

The default bindings use Vim-style hjkl:

KeyDirection
hLeft
jDown
kUp
lRight

Arrow keys work just as well:

spoon.Shoji:bindHotkeys({
focus_left = { { "ctrl", "alt" }, "left" },
focus_down = { { "ctrl", "alt" }, "down" },
focus_up = { { "ctrl", "alt" }, "up" },
focus_right = { { "ctrl", "alt" }, "right" },
})