From 4c382ae797d00d805592a2a95a821ac1829d397d Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Wed, 22 Jul 2026 08:18:18 -0400 Subject: [PATCH] fix: harden mode acceptance startup Give the daemon its normal five-second handshake window before switching the mode-system acceptance client to short frame polling. Document reload and session-persistence boundaries and correct stale describe-key guidance. --- docs/mode-system-wiring-framing.md | 7 +++++++ src/editor.rs | 6 +++--- tests/mode_system_wiring_acceptance.rs | 7 +++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/mode-system-wiring-framing.md b/docs/mode-system-wiring-framing.md index d45a9d6..68d233a 100644 --- a/docs/mode-system-wiring-framing.md +++ b/docs/mode-system-wiring-framing.md @@ -316,6 +316,9 @@ silently change an existing API unrelated to describe-key. views. The hidden-buffer (registry-only) gap is pre-existing: those buffers receive neither language detection nor syntax attachment and need their own fix. + An explicit nil clear is persistent across switches, not across a future + reload path that deliberately fires `buffer.after-load`; reload re-detects + the language just like a fresh open. 4. **GPU optimistic-edit bypass is a non-issue for mode-scoped bindings** — the GPU frontend optimistically inserts plain printable characters (outside `BUILTIN_PAIR_CHARS`) and Tab without round-tripping @@ -342,6 +345,10 @@ silently change an existing API unrelated to describe-key. side-quest (`side-quest-backlog.md:43`). This framing just wires the mechanism; modeline detection can override the initialized mode via `pmacs.buffer.set_major_mode` when it lands. +- **Explicit-mode session persistence** — desktop restore reopens files and + recovers detected modes through `buffer.after-load`, but explicit overrides + and clears are not serialized. Design that with session/settings persistence, + not as hidden state in this wiring layer. - **Mode help display** (`describe-mode`) — straightforward once the mode is stored, but not table-stakes for wiring. diff --git a/src/editor.rs b/src/editor.rs index dc7deea..642ecd0 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -8552,9 +8552,9 @@ mod tests { /// T M5.6f: `M-x editor.describe-instance-buffer` switches the /// active window to *pmacs-instance* and binds buffer-local `q` - /// to `buffer.kill-this`. The buffer-local binding is verified by - /// resolving directly against the keymap stack — `pmacs.describe.key` - /// only consults global scope. + /// to `buffer.kill-this`. Resolve directly against the keymap stack + /// to pin the exact buffer-local scope independently of the Lua + /// describe-key rendering surface. #[test] fn editor_describe_instance_buffer_switches_and_binds_q() { let mut state = EditorState::new(); diff --git a/tests/mode_system_wiring_acceptance.rs b/tests/mode_system_wiring_acceptance.rs index e1c9d0a..256da9b 100644 --- a/tests/mode_system_wiring_acceptance.rs +++ b/tests/mode_system_wiring_acceptance.rs @@ -71,8 +71,8 @@ impl Grid { fn attach(daemon: &TestDaemon) -> (Client, Grid) { let mut stream = daemon.connect(); stream - .set_read_timeout(Some(Duration::from_millis(100))) - .expect("set daemon read timeout"); + .set_read_timeout(Some(Duration::from_secs(5))) + .expect("set daemon handshake timeout"); let hello: Hello = read_message(&mut stream).expect("read daemon Hello"); assert_eq!(hello.protocol_version, PROTOCOL_VERSION); write_message( @@ -84,6 +84,9 @@ fn attach(daemon: &TestDaemon) -> (Client, Grid) { }, ) .expect("attach grid frontend"); + stream + .set_read_timeout(Some(Duration::from_millis(100))) + .expect("set daemon frame timeout"); let deadline = Instant::now() + Duration::from_secs(5); let mut grid = Grid::new();