Skip to content

IPC commands

Control Shoji from the command line through Hammerspoon’s IPC mechanism. Use it for shell scripts, keyboard shortcuts from other tools, and automation.

Prerequisites

Load the hs.ipc module in Hammerspoon config:

-- ~/.hammerspoon/init.lua
require("hs.ipc")

This enables the hs CLI tool. If hs is not in PATH, run hs.ipc.cliInstall() in the Hammerspoon console.

Basic usage

Send commands via the hs CLI:

Terminal window
# Get current status
hs -c 'spoon.Shoji:cmd("status")'
# Cycle to next layout
hs -c 'spoon.Shoji:cmd("cycle-layout")'
# Set specific layout (varargs style)
hs -c 'spoon.Shoji:cmd("set-layout", "wide")'
# Set specific layout (array style - also supported)
hs -c 'spoon.Shoji:cmd("set-layout", {"wide"})'

Available commands

list-commands

Returns all available command names.

Terminal window
hs -c 'spoon.Shoji:cmd("list-commands")'

The response includes all commands: cycle-layout, dec-nmaster, focus, focus-down, focus-left, focus-next, focus-prev, focus-right, focus-up, get-layout, inc-nmaster, list-commands, list-layouts, nmaster, ratio, resize-main-dec, resize-main-inc, retile, retile-only, set-layout, status, swap, swap-main, swap-next, swap-prev, toggle-float.

status

Returns the current state of the focused space.

Terminal window
hs -c 'spoon.Shoji:cmd("status")'

Response:

{
success = true,
data = {
spaceID = 1,
layout = "tall",
mainRatio = 0.5,
nmaster = 1,
windowCount = 3
}
}

cycle-layout

Cycles to the next layout in the enabled layouts list.

Terminal window
hs -c 'spoon.Shoji:cmd("cycle-layout")'

Response:

{
success = true,
data = { cycled = true }
}

set-layout

Sets a specific layout by name.

Terminal window
hs -c 'spoon.Shoji:cmd("set-layout", {"bsp"})'

Arguments:

  • layoutName (required): Name of the layout to set

Response:

{
success = true,
data = { layout = "bsp" }
}

Error (unknown layout):

{
success = false,
error = "Unknown layout: nonexistent"
}

retile

Retiles the current space and resets layout parameters (mainRatio, nmaster, layoutState) to defaults.

Terminal window
hs -c 'spoon.Shoji:cmd("retile")'

Response:

{
success = true,
data = { spaceID = 1 }
}

retile-only

Retiles without resetting layout parameters. Preserves mainRatio, nmaster, and layout state. Useful for re-applying the layout after manual window moves.

Terminal window
hs -c 'spoon.Shoji:cmd("retile-only")'

Response:

{
success = true,
data = { spaceID = 1 }
}

list-layouts

Returns all available layout names.

Terminal window
hs -c 'spoon.Shoji:cmd("list-layouts")'

get-layout

Returns the current layout for the focused space.

Terminal window
hs -c 'spoon.Shoji:cmd("get-layout")'

toggle-float

Toggles floating state for the focused window.

Terminal window
hs -c 'spoon.Shoji:cmd("toggle-float")'

focus

Focus window in a direction.

Terminal window
# Focus directions: left, right, up, down, next, prev
hs -c 'spoon.Shoji:cmd("focus", "left")'
hs -c 'spoon.Shoji:cmd("focus", "next")'

swap

Swap focused window with another.

Terminal window
# Swap directions: next, prev, main
hs -c 'spoon.Shoji:cmd("swap", "next")'
hs -c 'spoon.Shoji:cmd("swap", "main")'

ratio

Adjust the main area ratio.

Terminal window
# Increase ratio by 0.05
hs -c 'spoon.Shoji:cmd("ratio", "0.05")'
# Decrease ratio by 0.1
hs -c 'spoon.Shoji:cmd("ratio", "-0.1")'

The ratio is clamped between 0.1 and 0.9.

nmaster

Adjust the number of master windows.

Terminal window
# Increase nmaster by 1
hs -c 'spoon.Shoji:cmd("nmaster", "1")'
# Decrease nmaster by 1
hs -c 'spoon.Shoji:cmd("nmaster", "-1")'

The nmaster count is clamped to a minimum of 1.

Shorthand commands

These commands provide shortcuts for common operations:

Terminal window
# Focus shortcuts
hs -c 'spoon.Shoji:cmd("focus-left")'
hs -c 'spoon.Shoji:cmd("focus-right")'
hs -c 'spoon.Shoji:cmd("focus-up")'
hs -c 'spoon.Shoji:cmd("focus-down")'
hs -c 'spoon.Shoji:cmd("focus-next")'
hs -c 'spoon.Shoji:cmd("focus-prev")'
# Swap shortcuts
hs -c 'spoon.Shoji:cmd("swap-next")'
hs -c 'spoon.Shoji:cmd("swap-prev")'
hs -c 'spoon.Shoji:cmd("swap-main")'
# Ratio shortcuts (uses default step)
hs -c 'spoon.Shoji:cmd("resize-main-inc")'
hs -c 'spoon.Shoji:cmd("resize-main-dec")'
# Nmaster shortcuts
hs -c 'spoon.Shoji:cmd("inc-nmaster")'
hs -c 'spoon.Shoji:cmd("dec-nmaster")'

Response format

All commands return a table with:

---@class IPCSuccessResult
---@field success true -- Whether the command succeeded
---@field data table -- Result data (on success)
---@class IPCErrorResult
---@field success false -- Whether the command succeeded
---@field error string -- Error message (on failure)
---@alias IPCResult IPCSuccessResult|IPCErrorResult

Error handling

Commands fail gracefully with descriptive error messages:

Terminal window
# Unknown command
hs -c 'spoon.Shoji:cmd("unknown")'
# { success = false, error = "Unknown command: unknown" }
# Shoji not started
hs -c 'spoon.Shoji:cmd("status")'
# { success = false, error = "Shoji is not started" }
# Missing argument
hs -c 'spoon.Shoji:cmd("set-layout")'
# { success = false, error = "Missing layout name argument" }

Scripting examples

Toggle between layouts

#!/bin/bash
CURRENT=$(hs -c 'return spoon.Shoji:cmd("status").data.layout')
if [ "$CURRENT" = "tall" ]; then
hs -c 'spoon.Shoji:cmd("set-layout", {"wide"})'
else
hs -c 'spoon.Shoji:cmd("set-layout", {"tall"})'
fi

Get window count

Terminal window
hs -c 'return spoon.Shoji:cmd("status").data.windowCount'

Conditional retile

Terminal window
# Only retile if using BSP layout
LAYOUT=$(hs -c 'return spoon.Shoji:cmd("status").data.layout')
if [ "$LAYOUT" = "bsp" ]; then
hs -c 'spoon.Shoji:cmd("retile-only")'
fi

tmux integration

Bind Shoji commands to tmux keys:

~/.tmux.conf
bind-key C-l run-shell "hs -c 'spoon.Shoji:cmd(\"cycle-layout\")'"
bind-key C-t run-shell "hs -c 'spoon.Shoji:cmd(\"set-layout\", {\"tall\"})'"

Lua API

Use the same commands from Lua:

-- In your Hammerspoon config
local result = spoon.Shoji:cmd("status")
if result.success then
print("Current layout: " .. result.data.layout)
end