Skip to content

Non-QWERTY keyboards

Shoji defaults to Ctrl+Alt as the primary modifier. This works on US QWERTY keyboards, but on European layouts the Option (Alt) key produces special characters like @, {, }, ~, |, and accented letters. Holding Alt to navigate windows will type those characters instead.

This page provides ready-to-use keybinding presets for non-QWERTY layouts.

On QWERTZ (German, Swiss, Czech), AZERTY (French, Belgian), and Nordic layouts, Alt+key combinations produce essential characters:

Layout Alt conflicts
QWERTZ @ { } ~ | [ ]
AZERTY @ # { } [ ] | ~
Nordic @ $ { } [ ] ~ |

Shoji’s defaults already use Ctrl+Alt (not bare Alt) to reduce conflicts, but some combinations still collide. The presets below replace Alt entirely.

Uses Ctrl+Cmd as the primary modifier. No Alt key involved:

hs.loadSpoon("Shoji")
local mods = { "ctrl", "cmd" }
local modsShift = { "ctrl", "cmd", "shift" }
spoon.Shoji:configure({
default_layout = "tall",
enabled_layouts = { "tall", "wide", "bsp", "monocle" },
})
spoon.Shoji:bindHotkeys({
-- Navigation
focus_left = { mods, "h" },
focus_right = { mods, "l" },
focus_up = { mods, "k" },
focus_down = { mods, "j" },
focus_next = { mods, "n" },
focus_prev = { mods, "p" },
focus_last = { mods, "tab" },
-- Swapping
swap_left = { modsShift, "h" },
swap_right = { modsShift, "l" },
swap_up = { modsShift, "k" },
swap_down = { modsShift, "j" },
swap_next = { modsShift, "n" },
swap_prev = { modsShift, "p" },
swap_main = { modsShift, "return" },
-- Layout
cycle_layout_forward = { mods, "space" },
cycle_layout_backward = { modsShift, "space" },
increase_main_ratio = { mods, "=" },
decrease_main_ratio = { mods, "-" },
increase_main_count = { mods, "," },
decrease_main_count = { mods, "." },
retile_space = { modsShift, "r" },
reset_space = { modsShift, "0" },
-- Window state
toggle_float = { modsShift, "t" },
toggle_zoom = { mods, "f" },
-- Help
toggle_cheatsheet = { modsShift, "/" },
open_command_palette = { mods, "/" },
-- Regions
send_to_next_region = { mods, "]" },
send_to_prev_region = { mods, "[" },
balance_regions = { modsShift, "b" },
})
spoon.Shoji:start()

Same approach. Uses Ctrl+Cmd:

local mods = { "ctrl", "cmd" }
local modsShift = { "ctrl", "cmd", "shift" }
spoon.Shoji:bindHotkeys({
focus_left = { mods, "h" },
focus_right = { mods, "l" },
focus_up = { mods, "k" },
focus_down = { mods, "j" },
swap_left = { modsShift, "h" },
swap_right = { modsShift, "l" },
swap_up = { modsShift, "k" },
swap_down = { modsShift, "j" },
cycle_layout_forward = { mods, "space" },
swap_main = { modsShift, "return" },
toggle_float = { modsShift, "t" },
toggle_zoom = { mods, "f" },
})

Map Caps Lock to a “Hyper” key (Ctrl+Alt+Cmd+Shift) using Karabiner-Elements. Then bind Shoji to single keys under Hyper:

local hyper = { "ctrl", "alt", "cmd", "shift" }
spoon.Shoji:bindHotkeys({
focus_left = { hyper, "h" },
focus_right = { hyper, "l" },
focus_up = { hyper, "k" },
focus_down = { hyper, "j" },
swap_left = { hyper, "left" },
swap_right = { hyper, "right" },
swap_up = { hyper, "up" },
swap_down = { hyper, "down" },
cycle_layout_forward = { hyper, "space" },
swap_main = { hyper, "return" },
toggle_float = { hyper, "t" },
toggle_zoom = { hyper, "f" },
})

This works on every keyboard layout because Hyper is a unique modifier combination that no OS or app reserves.

Karabiner rule for Caps Lock to Hyper (add to ~/.config/karabiner/karabiner.json):

{
"manipulators": [
{
"from": { "key_code": "caps_lock" },
"to": [
{
"key_code": "left_shift",
"modifiers": ["left_command", "left_control", "left_option"]
}
],
"type": "basic"
}
]
}
Modifier Pros Cons
Ctrl+Cmd No extra tools needed, no Alt conflicts May conflict with some app shortcuts
Hyper (Caps Lock) Zero conflicts, works on any layout Requires Karabiner-Elements
Ctrl+Alt (default) Works on QWERTY out of the box Conflicts with special chars on EU layouts

Pick the modifier that avoids conflicts with both your keyboard layout and the apps you use most. You only need to override the bindings that conflict – unspecified actions keep their defaults.