Skip to content

Instantly share code, notes, and snippets.

@possibilities
Created April 2, 2026 02:30
Show Gist options
  • Select an option

  • Save possibilities/a16c604fdc1e5f6ea7c50d26224e0b99 to your computer and use it in GitHub Desktop.

Select an option

Save possibilities/a16c604fdc1e5f6ea7c50d26224e0b99 to your computer and use it in GitHub Desktop.
prise ctrl+space keybind bug discovery and fix
session-id a6f70396-000d-4337-87c0-60777a182af3

User

/arthack:ask

When I type Ctrl+Space and then press | or - it doesn't split the prise frame as it should. Is it configured correctly? Or maybe prise server needs reboot?

Skill loaded: arthack:ask

Assistant

Thought (1 line)

Let me check your prise configuration.

Glob prise/**/* (1 file)

Bash cat ~/.config/prise/confi... 2>/dev/null || echo "No ~/.config/prise/ directory" (5 lines)

Read ~/code/dotfiles/prise/.config/prise/init.lua (55 lines)

Thought (1 line)

Let me check what prise actually expects for its config format.

Bash ~/.local/bin/prise --help...0; echo "---"; ls -la ~/.local/bin/prise 2>/dev/null (18 lines)

Bash knowctl list-topics 2>/de... | grep -i prise || echo "No prise topic in knowctl" (1 line)

Bash cd ~/src/rockorager--pris...nd . -name "*.md" -maxdepth 2 2>/dev/null | head -20 (20 lines)

Bash cd ~/src/rockorager--pris...ua" src/ --include="*.zig" -l 2>/dev/null | head -10 (10 lines)

Read ~/src/rockorager--prise/docs/prise.5.md (504 lines)

Found the issue. Your config binds | and _, but you're pressing | and -. The | should actually work (it's Shift+), but - won't — your config has _ (Shift+-), not -.

But the real problem is likely different. Looking at the key notation docs, | is a plain character, so <leader>| should work after Ctrl+Space. Let me check if prise is even running as server:

Bash pgrep -fl prise 2>/dev/null; echo "---"; ps aux | grep -i prise | grep -v grep (8 lines)

Prise server is running fine. The config is also correct — init.lua is the right file and the Lua API matches the docs.

Here's what's going on:

Your bindings require Shift:

  • <leader>| → Ctrl+Space, then Shift+\ (pipe is Shift+backslash)
  • <leader>_ → Ctrl+Space, then Shift+- (underscore is Shift+minus)

If you're pressing Ctrl+Space then just - (no shift), that won't match _. And | should work if you're actually pressing Shift+\.

If | also doesn't work, the issue is likely that your terminal (Ghostty) is intercepting Ctrl+Space before prise sees it. Let me check:

Bash grep -r "ctrl+space\|cont...ontrol+space" ~/code/dotfiles/karabiner/ 2>/dev/null (1 line)

No conflicts from Ghostty, skhd, or Karabiner. The keybindings should reach prise.

Most likely cause: You're pressing - (minus) instead of _ (Shift+minus). The | binding should work — are you sure you're pressing Shift+\ and not just \?

If you'd prefer tmux-style - without shift for splits, change the config to:

["<leader>-"] = "split_vertical",    -- was "_"
["<leader>\\"] = "split_horizontal", -- was "|"

Want me to make that change?

Permission mode: default

User

It doesn't work even with shift. Can you reboot prise server first?

Assistant

Thought (1 line)

Bash launchctl list 2>/dev/nul...*prise* 2>/dev/null || echo "No prise launchd plist" (3 lines)

Bash launchctl kickstart -k gui/$(id -u)/system.prise-server (1 line)

Bash launchctl list | grep prise (1 line)

Prise server restarted (new PID 32849). Try your Ctrl+Space then Shift+| split now — you may need to reconnect your prise client first (prise or reattach the session).

User

Nope, didn't work. Maybe my leader key isn't working. How can we test it?

Assistant

Quickest test — try a binding that's hard to miss. Your config has <leader>t for new tab. Press Ctrl+Space then t. If a new tab appears, leader works and the issue is with | and _ specifically. If nothing happens, leader is broken.

Also try <leader>d (detach) — that's unmistakable since it'll kick you out of the session.

And your Alt bindings don't use leader at all — try Alt+h/j/k/l for focus movement. If those work but leader ones don't, we know it's specifically Ctrl+Space that's not registering as leader.

User

Ctrl+space then d doesn't detach

Assistant

Thought (1 line)

Leader itself is broken. Ctrl+Space in terminals traditionally sends NUL (0x00 / C-@). Let me check if Ghostty is eating it or if prise can even see it.

Grep ctrl.space|control.space|keybind.*space (1 line)

Grep C-Space|ctrl.*space|NUL|\\x00|0x00 (1 line)

Read ~/src/rockorager--prise/src/keybind.zig (80 lines)

Grep C-Space|C_Space|ctrl_space|space.*leader|leader.*space (1 line)

Read ~/src/rockorager--prise/src/key_string.zig (100 lines)

Read ~/src/rockorager--prise/src/key_string.zig (182 lines)

Read ~/src/rockorager--prise/src/keybind_matcher.zig (100 lines)

Thought (1 line)

Now I need to understand how prise receives key events from the terminal — does it use the Kitty keyboard protocol?

Grep kitty|progressive.*enhance|CSIu|\x1b\[ (4 lines)

Grep Space|space|0x20|NUL|0x00 (1 line)

Read ~/src/rockorager--prise/src/key_parse.zig (120 lines)

Grep parseKey|key_parse|handle_key|ghostty.*input|KeyEvent (1 line)

Grep key_parse|parseKey|handle_key|key_event|keyboard (1 line)

Read ~/src/rockorager--prise/src/key_parse.zig (120 lines)

Read ~/src/rockorager--prise/src/lua/tiling.lua (40 lines)

Grep handle_key|event\.data (1 line)

Read ~/src/rockorager--prise/src/keybind.zig (120 lines)

Read ~/src/rockorager--prise/src/keybind.zig (50 lines)

Now let me look at the critical piece — how extractKey converts the incoming key event data to a Key struct for matching:

Grep fn extractKey" (1 line)

Grep fn extractKey (1 line)

Thought (1 line)

Now I need to see how the server sends key events to the Lua UI — what fields does event.data contain?

Read ~/src/rockorager--prise/src/server.zig (80 lines)

Thought (1 line)

The server sends keys to PTY, but keybind matching happens in the UI layer. I need to find how the UI receives key events — what's in event.data.

Grep key_press|key_event|event.*key|dispatch.*key (1 line)

Grep send_key|key_press|fireEvent.*key|dispatchKey (1 line)

Read ~/src/rockorager--prise/src/lua_event.zig (80 lines)

The critical function is vaxisKeyToStrings at line 267 — that's what determines the key string that extractKey reads. Let me check it.

Grep vaxisKeyToStrings|KeyStrings (3 lines)

Read ~/src/rockorager--prise/src/vaxis_helper.zig (197 lines)

Thought (1 line)

Found the bug. Here's the full trace:

Config side (key_string.zig): <C-Space> parses to Key{ .key = "Space", .ctrl = true } → trie ID "C:Space"

Runtime side (vaxis_helper.zig): When you press Ctrl+Space, vaxisKeyToStrings builds the key field:

  1. key.text is likely null (Ctrl modifies it)
  2. Checks isNamedKey(Key.space)returns false! Space is missing from that list (line 33-75)
  3. Falls through to UTF-8 encode of the codepoint 0x20 → " " (literal space character)

So extractKey gets Key{ .key = " ", .ctrl = true } → matcher ID "C: "

"C:Space" never equals "C: " — the leader can never match.

This is a bug in prise's vaxis_helper.zigisNamedKey lists enter, tab, backspace, escape, etc., but forgot Key.space. The specialKeyCode function correctly maps it to "Space" for the code field, but the key field path bypasses that.

Workaround: Change your leader to something that doesn't hit this bug, like <C-a> (classic tmux style):

leader = "<C-a>",

Or if you want to keep Ctrl+Space, you could file a PR on prise to add Key.space to the isNamedKey function. Want me to do either?

User

Use our fork of @~/src/rockorager--prise/ to create a branch with fix. Don't make the PR yet though. Just make it and show me.

Assistant

Bash cd ~/src/rockorager--prise && git remote -v && git log --oneline -3 (7 lines)

Bash cd ~/src/rockorager--pris...meWithOwner == "rockorager/prise") | .nameWithOwner' (3 lines)

Bash gh repo list possibilitie...meWithOwner == "rockorager/prise") | .nameWithOwner' (1 line)

Bash gh api user/repos --pagin...meWithOwner' --json nameWithOwner,parent 2>/dev/null (2 lines)

Bash cd ~/src/rockorager--pris...github.com/possibilities/prise.git && git fetch fork (11 lines)

Bash cd ~/src/rockorager--pris...t checkout -b fix/space-keybind-matching origin/main (4 lines)

Read ~/src/rockorager--prise/src/vaxis_helper.zig (43 lines)

Edit ~/src/rockorager--prise/src/vaxis_helper.zig (1 line)

Now let me build to make sure it compiles, then commit and push.

Bash cd ~/src/rockorager--pris... build -Doptimize=ReleaseSafe -Dlua-check=false 2>&1 (2 lines)

Builds clean. Let me commit and push to the fork.

Bash cd ~/src/rockorager--prise && git diff (14 lines)

Bash cd ~/src/rockorager--prise && git log --oneline -3 (5 lines)

Bash cd ~/src/rockorager--pris...ces "Space" but the event data contained " ". EOF )" (4 lines)

Bash cd ~/src/rockorager--prise && git push fork fix/space-keybind-matching (8 lines)

Done. Branch fix/space-keybind-matching is pushed to possibilities/prise.

The fix: One line — add Key.space to the isNamedKey function in src/vaxis_helper.zig. Without it, pressing Space produced " " (literal char) as the key name, but the config parser expected "Space" (the word), so <C-Space> as leader could never match.

To test it now, install the fixed build:

cd ~/src/rockorager--prise && zig build -Doptimize=ReleaseSafe -Dlua-check=false install --prefix ~/.local

Then restart the prise server and try your Ctrl+Space bindings. Want me to install it and restart?

Permission mode: plan

User

What is the session id here?

Assistant

Bash claudectl show-context 2>/dev/null (3 lines)

Session ID: a6f70396-000d-4337-87c0-60777a182af3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment