Skip to content

fix: prevent Herdr from swallowing Escape#17

Merged
kunchenguid merged 1 commit into
mainfrom
fm/dpub-herdr-mousecap-s9
Jul 11, 2026
Merged

fix: prevent Herdr from swallowing Escape#17
kunchenguid merged 1 commit into
mainfrom
fm/dpub-herdr-mousecap-s9

Conversation

@kunchenguid

Copy link
Copy Markdown
Owner

Intent

Ship both required halves of the verified Herdr Escape-swallow mitigation to this public teaching dotfiles repo so it is actually effective for viewers who follow this setup. Herdr computes should_capture_host_mouse = ui.mouse_capture || pane_requests_mouse, so the mitigation only works when host mouse capture is off on BOTH sides: (1) Herdr's own config (home/.config/herdr/config.toml) - add a new [ui] table with mouse_capture = false; and (2) the pane side, Neovim (home/.config/nvim/lua/vim_config.lua) which currently defaults to mouse-on - add o.mouse = '' in the existing 'local o = vim.opt' / o. style. Deliberate decisions: exactly these two additions, nothing else; each carries a short explanatory comment matching each file's existing comment style; no other files touched; do not rewrite historical recorded video-source/snippet content (none exists in this repo); no AGENTS.md/CLAUDE.md agent files added; .no-mistakes/ stays untracked. A Herdr-only change would be a no-op here because Neovim defaults to mouse-on, which is exactly why both halves are required.

What Changed

  • Disable Herdr host mouse capture to prevent trackpad events from causing Escape to be swallowed.
  • Disable Neovim mouse handling so Herdr can consistently keep host mouse capture off.

Risk Assessment

✅ Low: The change is narrowly scoped, uses valid configuration patterns, and consistently disables both Herdr host capture and Neovim pane mouse reporting without introducing a material regression.

Testing

After an initial overlong-socket-path setup failure was corrected with isolated worktree-local sockets, Herdr 0.7.3 accepted and live-reloaded the shipped configuration without diagnostics, Neovim 0.12.0 evaluated the shipped configuration with mouse disabled, deployment wiring for both files was confirmed, runtime evidence was captured, and the worktree was left clean.

Evidence: Escape mitigation runtime evidence

Herdr reload: status applied, diagnostics []. Neovim runtime: vim.opt.mouse = {}. Combined state: Herdr host capture disabled and Neovim mouse disabled.

Herdr live config reload (Herdr 0.7.3):
{"id":"cli:server:reload-config","result":{"diagnostics":[],"status":"applied","type":"config_reload"}}

Neovim runtime option (Neovim 0.12.0, repository vim_config.lua sourced):
vim.opt.mouse = {}

Combined mitigation state:
Herdr ui.mouse_capture = false; Neovim mouse = empty
Evidence: Herdr server runtime log

Herdr startup, reload, and clean shutdown log.

2026-07-11T18:49:09.451835Z  INFO herdr::platform::macos: raised server file descriptor soft limit previous=256 target=8192
2026-07-11T18:49:28.502645Z  INFO herdr::platform::macos: raised server file descriptor soft limit previous=256 target=8192
2026-07-11T18:49:28.502983Z  INFO herdr::api::server: api server listening path=.herdr-test.sock
2026-07-11T18:49:28.503253Z  INFO herdr::app: using pane scrollback configuration pane_scrollback_limit_bytes=10000000
2026-07-11T18:49:28.512603Z  INFO herdr::logging: checking for updates event="update.check.start" subsystem="update" outcome="started"
2026-07-11T18:49:28.512716Z  INFO herdr::server::headless: client protocol socket listening path=.herdr-test-client.sock
2026-07-11T18:49:28.512735Z  INFO herdr::server::headless: herdr server started api_socket=.herdr-test.sock client_socket=.herdr-test-client.sock
2026-07-11T18:49:28.512760Z  INFO herdr::logging: herdr starting event="app.startup" subsystem="server" outcome="started" pid=6216
2026-07-11T18:49:28.807000Z  WARN herdr::detect::manifest_update: skipping unknown remote manifest agent agent="maki"
2026-07-11T18:49:36.200176Z  INFO herdr::logging: api request received event="api.request.start" subsystem="api" outcome="started" request_id="cli:server:reload-config" method="server.reload_config" changes_ui=true
2026-07-11T18:49:36.200406Z  INFO herdr::logging: api request completed event="api.request.complete" subsystem="api" outcome="ok" request_id="cli:server:reload-config" method="server.reload_config"
2026-07-11T18:49:39.381855Z  INFO herdr::server::headless: server shutdown initiated
2026-07-11T18:49:39.482472Z  INFO herdr::server::headless: completing server shutdown
2026-07-11T18:49:39.482828Z  INFO herdr::logging: session cleared event="persist.clear" subsystem="persist" outcome="ok" path=/var/folders/5x/4nqprlbx0518k3ybcb1sz6gr0000gn/T/no-mistakes-evidence/01KX984321VX7RYR01C3NDMVMK/.config/herdr/session.json
2026-07-11T18:49:39.482866Z  INFO herdr::server::headless: headless server exiting
2026-07-11T18:49:39.483691Z  INFO herdr::logging: herdr exiting event="app.shutdown" subsystem="server" outcome="completed" pid=6216

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • git diff --stat f068d43326867f8b531526d9b5fffbf6a02072c0..a0f8972b367f4edbbfda5f8fb35dadc1d8e2831b and the corresponding full diff to confirm only the intended two files changed
  • Started Herdr 0.7.3 with HERDR_CONFIG_PATH=$PWD/home/.config/herdr/config.toml and isolated worktree-local sockets
  • Ran herdr server reload-config against the isolated server and observed status: applied with no diagnostics
  • Ran nvim --clean --headless -u NONE with the repository vim_config.lua sourced and observed vim.opt.mouse = {}
  • Verified home.nix deploys both repository configuration directories through Home Manager out-of-store symlinks
  • Stopped the isolated Herdr server, removed its worktree-local sockets, and verified the working tree remained clean
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Turn off Herdr's host mouse capture ([ui] mouse_capture = false) and set
Neovim mouse off (o.mouse = ''). Herdr computes should_capture_host_mouse
as ui.mouse_capture || pane_requests_mouse, so both halves are required:
with either side leaving mouse on, a trackpad event can tailgate a held
Escape and get swallowed in the pane (e.g. Neovim stuck in insert mode).
@kunchenguid
kunchenguid merged commit 207ffe8 into main Jul 11, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant