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.
The problem
Section titled “The problem”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.
QWERTZ preset (German, Swiss, Austrian)
Section titled “QWERTZ preset (German, Swiss, Austrian)”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()AZERTY preset (French, Belgian)
Section titled “AZERTY preset (French, Belgian)”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" },})Hyper key preset (any layout)
Section titled “Hyper key preset (any layout)”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" } ]}Choosing a modifier
Section titled “Choosing a modifier”| 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.