Skip to content

fix(input): leave navigate mode on ctrl+[ - #2340

Open
qaz74107410 wants to merge 3 commits into
herdrdev:masterfrom
qaz74107410:fix/1431-ctrl-bracket-navigate
Open

fix(input): leave navigate mode on ctrl+[#2340
qaz74107410 wants to merge 3 commits into
herdrdev:masterfrom
qaz74107410:fix/1431-ctrl-bracket-navigate

Conversation

@qaz74107410

Copy link
Copy Markdown

Ctrl+[ is the terminal-level equivalent of Esc, but navigate mode only checked KeyCode::Esc, so the mode stayed open.

On a legacy terminal Ctrl+[ sends 0x1b and already arrives as KeyCode::Esc, which is why this works for some people. Under the kitty keyboard protocol, which Herdr negotiates, the modified key is reported on its own and reaches the handler as Char('[') with CONTROL, so the Esc check missed it. The report came from foot, which speaks that protocol.

Adds is_navigate_cancel_key and uses it where navigate mode tested for Esc. Ctrl+Shift+[ keeps its own meaning because the match requires CONTROL alone.

Prefix mode needs no matching change. It already falls through to leave_command_mode for any unbound key, so Ctrl+[ cancels it today, and adding the same check there would shadow a custom Ctrl+[ binding under Prefix dispatch.

No doc change looks needed: the keyboard docs do not currently mention Esc for navigate mode. Happy to add one if you want the alias documented.

Checks on 1.96.1: cargo fmt --check and cargo clippy --all-targets --locked -- -D warnings are clean. cargo nextest run --locked is 3179/3181; the two failures, live_handoff::live_server_holds_one_pty_master_fd_per_pane and terminal::state::metadata::tests::metadata_clear_only_without_ttl_does_not_extend_old_ttl, fail the same way on unmodified master in my environment. I ran this in a Linux container because zig 0.15.2 cannot build the vendored libghostty-vt on macOS 26, so just windows-lint is untested here; the change is not platform-gated.

refs #1431

@kangal-bot kangal-bot added the ai-review Trigger automated AI reviews for pull requests admitted by the PR gate label Aug 5, 2026
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dfeb0806-5509-4eee-96c8-eacef5eeeb36

📥 Commits

Reviewing files that changed from the base of the PR and between 6e8b138 and deaf073.

📒 Files selected for processing (2)
  • docs/next/CHANGELOG.md
  • src/app/input/navigate.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/app/input/navigate.rs

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Navigate-mode cancellation now supports Ctrl+[ as a fallback after navigation bindings are checked. Escape and prefix keys retain immediate cancellation. Ctrl+Shift+[ remains non-canceling. Runtime and test handlers apply the same behavior.

Changes

Navigation input handling

Layer / File(s) Summary
Cancellation predicate and handler flow
src/app/input/navigate.rs, docs/next/CHANGELOG.md
is_ctrl_bracket_key recognizes Ctrl+[ across terminal representations without Shift. Runtime and test handlers apply cancellation after indexed navigation dispatch, so configured Ctrl+[ bindings take precedence. Escape and prefix-key handling remain immediate. Tests and the changelog document the behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to deaf0

This localized change makes Ctrl+[ exit navigate mode while preserving existing prefix-mode and Ctrl+Shift+[ behavior. No actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 1 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the Ctrl+[ Navigate mode fix, binding precedence, modifier behavior, tests, and validation results.
Title check ✅ Passed The title clearly and concisely identifies the primary change: Ctrl+[ now exits Navigate mode.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 1 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown

Greptile Summary

The PR makes Ctrl+[ leave Navigate mode when reported as a distinct Kitty keyboard-protocol key, while preserving configured binding precedence.

  • Adds a Ctrl+[ cancellation fallback after navigate-mode action dispatch.
  • Covers cancellation, configured-binding precedence, and Ctrl+Shift+[ behavior with tests.
  • Documents the fix in the next-release changelog.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/app/input/navigate.rs Adds the narrowly scoped Ctrl+[ Navigate-mode fallback after binding dispatch and tests the intended precedence and modifier behavior.
docs/next/CHANGELOG.md Records the Navigate-mode Ctrl+[ compatibility fix and configured-binding precedence.

Reviews (6): Last reviewed commit: "docs: note ctrl+[ navigate mode fix in c..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/input/navigate.rs (1)

1312-1312: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover both navigation handlers.

The new tests call App::handle_navigate_key only. Line 1312 changes the separate handle_navigate_key(&mut AppState, KeyEvent) handler. Add equivalent Ctrl+[ and Ctrl+Shift+[ assertions through that handler so the two paths cannot diverge.

Suggested additional coverage
+    #[test]
+    fn state_navigate_mode_cancel_keys_match_app_handler() {
+        let mut state = state_with_workspaces(&["one", "two"]);
+        state.mode = Mode::Navigate;
+        handle_navigate_key(
+            &mut state,
+            KeyEvent::new(KeyCode::Char('['), KeyModifiers::CONTROL),
+        );
+        assert_eq!(state.mode, Mode::Terminal);
+
+        state.mode = Mode::Navigate;
+        handle_navigate_key(
+            &mut state,
+            KeyEvent::new(
+                KeyCode::Char('['),
+                KeyModifiers::CONTROL | KeyModifiers::SHIFT,
+            ),
+        );
+        assert_eq!(state.mode, Mode::Navigate);
+    }

Also applies to: 2907-2932


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ac4deea-63fe-4cd6-bc83-4e32e490b329

📥 Commits

Reviewing files that changed from the base of the PR and between 15442a2 and 1d55a8f.

📒 Files selected for processing (1)
  • src/app/input/navigate.rs

@ogulcancelik ogulcancelik left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requesting changes because this currently overrides valid user configuration.

ctrl+[ is checked before navigate-mode keybinding dispatch, so any existing ctrl+[ binding is ignored while navigate mode is open. please treat it as a fallback cancel key only when no configured binding matched.

please cover both paths: unbound ctrl+[ cancels navigate mode, and a configured ctrl+[ binding still runs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app/input/navigate.rs (1)

1317-1337: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add tests for the state-only navigation handler.

handle_navigate_key(&mut AppState, KeyEvent) has a separate conversion and dispatch path. The new precedence test at Lines [2931-2943] covers only App::handle_navigate_key(TerminalKey). Add equivalent tests through the KeyEvent entry point for unbound Ctrl+[, a configured Ctrl+[ binding, and Ctrl+Shift+[. This prevents the two handlers from diverging.

As per coding guidelines, keep unit tests next to the Rust code in #[cfg(test)] mod tests.

Also applies to: 2931-2943

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 75966db5-3886-40ce-8eb5-694f825749b0

📥 Commits

Reviewing files that changed from the base of the PR and between 1d55a8f and 6474153.

📒 Files selected for processing (1)
  • src/app/input/navigate.rs

@qaz74107410

Copy link
Copy Markdown
Author

Good catch, ctrl+[ was shadowing the binding. Fixed in 6474153.

ctrl+[ is now checked last, after workspace up/down, reserved keys, non-indexed actions, custom commands, and indexed actions, so it only cancels when nothing else matched. Esc is back to the bare KeyCode::Esc check it had before this PR, so its behavior is unchanged. The helper is renamed to is_ctrl_bracket_key and its doc comment states the fallback-only contract.

Both paths are covered:

  • app_navigate_mode_ctrl_bracket_leaves_like_esc, unbound ctrl+[ cancels navigate mode, and Esc still does too.
  • app_navigate_mode_configured_ctrl_bracket_binding_wins_over_cancel, with navigate_workspace_down = "ctrl+[" the selection moves and navigate mode stays open.

The second test fails if the check is moved back above dispatch, so it pins the ordering rather than just passing.

@ogulcancelik

Copy link
Copy Markdown
Collaborator

@qaz74107410 the revised ordering now preserves configured ctrl+[ bindings, so my original blocker is resolved. please rebase onto current master, add the user-facing entry to docs/next/CHANGELOG.md, and rerun checks and both review bots; i’ll approve the updated head.

@qaz74107410
qaz74107410 force-pushed the fix/1431-ctrl-bracket-navigate branch from 7251638 to deaf073 Compare August 25, 2026 06:19
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@qaz74107410

Copy link
Copy Markdown
Author

Thanks for the review.

Rebased onto current master and added the changelog entry under Unreleased / Fixed in docs/next/CHANGELOG.md, crediting the reporter:

- Navigate mode now closes on `Ctrl+[` like Esc under the kitty keyboard protocol, while a configured `ctrl+[` binding keeps priority. (#1431, thanks @haoxianhan)

The rebase only touched src/app/input/navigate.rs, where the helper now sits next to the new tab move functions. Behavior is unchanged from the last pass: is_ctrl_bracket_key is still checked last, after navigate mode dispatch, and Esc keeps its bare KeyCode::Esc check.

Checks and both review bots have rerun on the new head and are green. Please let me know if anything else would help.

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

Labels

ai-review Trigger automated AI reviews for pull requests admitted by the PR gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants