diff --git a/config/hypr/bindings.lua b/config/hypr/bindings.lua index 98d3ecbe..6da7b938 100644 --- a/config/hypr/bindings.lua +++ b/config/hypr/bindings.lua @@ -1,5 +1,5 @@ --- Keep only your personal keybinding overrides here. Add new bindings or --- unbind defaults before replacing them. +-- Keep only your personal keybinding overrides here. Add new bindings with +-- o.bind or replace defaults with o.rebind. -- See current bindings and descriptions: -- omarchy menu keybindings --print @@ -15,10 +15,9 @@ -- Add a new binding. -- o.bind("SUPER + SHIFT + R", "SSH", "alacritty -e ssh your-server") --- Change an existing binding by unbinding it first, then binding the key again. --- This example changes SUPER+SPACE from the launcher to the Omarchy root menu. --- hl.unbind("SUPER + SPACE") --- o.bind("SUPER + SPACE", "Omarchy menu", "omarchy-menu toggle root") +-- Change an existing binding. o.rebind takes the same arguments as o.bind. +-- This example replaces the default file manager with Flea. +-- o.rebind("SUPER + SHIFT + F", "File manager", { launch = "flea" }) -- Disable a default binding without replacing it. -- hl.unbind("SUPER + SHIFT + B") diff --git a/default/agents/skills/omarchy/SKILL.md b/default/agents/skills/omarchy/SKILL.md index aed1e38c..4ce34bb0 100644 --- a/default/agents/skills/omarchy/SKILL.md +++ b/default/agents/skills/omarchy/SKILL.md @@ -278,7 +278,7 @@ This skill intentionally does not cover Omarchy source development. Do not use t ## Example Requests - "Change my theme to catppuccin" -> `omarchy theme set catppuccin` -- "Add a keybinding for Super+E to open file manager" -> Check existing bindings first, call `hl.unbind` if needed, then `o.bind` in `~/.config/hypr/bindings.lua` +- "Add a keybinding for Super+E to open file manager" -> Check existing bindings first, then use `o.rebind` to replace one or `o.bind` to add one in `~/.config/hypr/bindings.lua` - "Configure my external monitor" -> Edit `~/.config/hypr/monitors.lua` - "Make the window gaps smaller" -> Edit `~/.config/hypr/looknfeel.lua` - "Turn on night light" -> `omarchy toggle nightlight` (for time-based schedules, edit `~/.config/hypr/hyprsunset.conf` profiles, then `omarchy restart hyprsunset`) diff --git a/default/agents/skills/omarchy/hyprland.md b/default/agents/skills/omarchy/hyprland.md index 961ff388..fd518ad3 100644 --- a/default/agents/skills/omarchy/hyprland.md +++ b/default/agents/skills/omarchy/hyprland.md @@ -43,18 +43,16 @@ View current bindings: `omarchy menu keybindings --print` **IMPORTANT: When re-binding an existing key:** 1. First check existing bindings: `omarchy menu keybindings --print` -2. If the key is already bound, you MUST call `hl.unbind(...)` BEFORE the new `o.bind(...)` +2. If the key is already bound, use `o.rebind(...)` to remove the existing binding and add its replacement. It takes the same arguments as `o.bind(...)`. 3. Inform the user what the key was previously bound to Example - rebinding SUPER+F (which is bound to fullscreen by default): ```lua --- Unbind existing SUPER+F (was: fullscreen) -hl.unbind("SUPER + F") --- New binding for file manager -o.bind("SUPER + F", "File manager", { launch = "nautilus" }) +-- Replace SUPER+F (was: fullscreen) with the file manager. +o.rebind("SUPER + F", "File manager", { launch = "nautilus" }) ``` -Always tell the user: "Note: SUPER+F was previously bound to fullscreen. I've added an unbind to override it." +Tell the user which action was replaced. Use `hl.unbind(...)` to remove a binding without replacing it. ## Display/Monitors diff --git a/default/hypr/helpers.lua b/default/hypr/helpers.lua index b1eb48fa..04964703 100644 --- a/default/hypr/helpers.lua +++ b/default/hypr/helpers.lua @@ -105,6 +105,11 @@ function o.bind(keys, description, dispatcher, options) hl.bind(keys, dispatcher, opts) end +function o.rebind(keys, description, dispatcher, options) + hl.unbind(keys) + o.bind(keys, description, dispatcher, options) +end + function o.launch(command) return "uwsm-app -- " .. command end diff --git a/manual/31-dotfiles.md b/manual/31-dotfiles.md index 11e0d762..ec148b44 100644 --- a/manual/31-dotfiles.md +++ b/manual/31-dotfiles.md @@ -66,10 +66,11 @@ Look, this is your computer. You can do whatever you want with it, but I would a You can change just about everything that way, like the default keybindings. Just edit `~/.config/hypr/bindings.lua` to, say, replace [Obsidian](https://obsidian.md/) with [Joplin](https://joplinapp.org/) (install with `omarchy-pkg-add joplin-bin`): +```lua +o.rebind("SUPER + SHIFT + O", "Joplin", "joplin-desktop") ``` -hl.unbind("SUPER + SHIFT + O") -o.bind("SUPER + SHIFT + O", "Joplin", "joplin-desktop") -``` + +`o.rebind` removes the existing binding before adding its replacement. It takes the same arguments as `o.bind`, including launch helpers and binding options. Use `o.bind` to add a binding, or `hl.unbind` to remove one without replacing it. If you insist on hacking on the internal Omarchy files, switch to the dev channel via _Update > Channel > Dev_. That links Omarchy to a git checkout of the source code in `~/omarchy`, which you're free to change to your heart's content. Ain't nobody here to tell you what to do! diff --git a/test/shell.d/hyprland-binding-conflicts-test.sh b/test/shell.d/hyprland-binding-conflicts-test.sh index c34d4bfd..d0eb9e0e 100755 --- a/test/shell.d/hyprland-binding-conflicts-test.sh +++ b/test/shell.d/hyprland-binding-conflicts-test.sh @@ -40,6 +40,13 @@ hl = setmetatable({ release = opts.release == true, }) end, + unbind = function(keys) + for index = #bindings, 1, -1 do + if bindings[index].keys == keys then + table.remove(bindings, index) + end + end + end, config = function() end, env = function() end, monitor = function() end, @@ -188,3 +195,17 @@ probe=$(PATH="$stub_bin:$PATH" list_bindings "$home" \ grep -Fqx "ALT+SHIFT+SUPER+RIGHT" <<<"$probe" || fail "the conflict check ignores modifier order" pass "the conflict check catches collisions across keycodes and modifier order" + +rebound=$(PATH="$stub_bin:$PATH" list_bindings "$home" \ + 'o.rebind("SUPER + SHIFT + F", "Flea", { launch = "flea" })' | \ + awk -F'\t' '$1 == "SHIFT+SUPER+F"') +[[ $rebound == $'SHIFT+SUPER+F\tSUPER + SHIFT + F\tFlea' ]] || + fail "rebinding replaces the default file manager without stacking actions" "$rebound" +pass "rebinding replaces the default file manager without stacking actions" + +rebound=$(PATH="$stub_bin:$PATH" list_bindings "$home" \ + 'o.rebind("F9", "Dictation on release", "voxtype record toggle", { release = true })' | \ + awk -F'\t' '$2 == "F9"') +[[ $rebound == $'F9 (release)\tF9\tDictation on release' ]] || + fail "rebinding replaces all bindings for a key and preserves binding options" "$rebound" +pass "rebinding replaces all bindings for a key and preserves binding options"