Skip to content

feat: persistent command layer (vim-like navigation mode) - #2777

Closed
adrien-barret wants to merge 1 commit into
herdrdev:masterfrom
adrien-barret:feat/focus-nav-mode
Closed

feat: persistent command layer (vim-like navigation mode)#2777
adrien-barret wants to merge 1 commit into
herdrdev:masterfrom
adrien-barret:feat/focus-nav-mode

Conversation

@adrien-barret

@adrien-barret adrien-barret commented Aug 13, 2026

Copy link
Copy Markdown

What

Adds a persistent, vim-like command layer (Mode::FocusNav) — a normal-mode
counterpart to the terminal's insert mode. Enter it via a configurable focus_nav
keybind and the whole prefix keymap goes live on bare keys, staying open across
actions instead of exiting after one:

  • Movement and actions use your existing prefix bindings without the prefix:
    h/j/k/l focus panes, c new tab, v / - split, p / n switch tabs,
    w workspace picker, x close, z zoom, and so on.
  • The mode stays open after each action — chain as many as you like.
  • Escape (or re-pressing the trigger) exits back to the terminal.

A CMD status bar is shown while the layer is active.

Text dialogs suspend and return

Actions that open a text input (rename workspace/tab/pane, new-tab / new-workspace
name prompts, confirm-close) suspend the command layer so you can type. On
commit or cancel you return to the command layer — not to the terminal — so an
accidental rename never drops you out of navigation.

Why

Today, movement in the live layout is one-shot: prefix+h/j/k/l moves focus once
and returns to the terminal, and goto / workspace_picker are pickers that close
on selection. There is no sticky, modal layer to drive herdr with bare keys. This
adds a familiar normal/insert split over panes, tabs, and workspaces, reusing the
existing keymap so there is nothing new to learn.

Design

  • New Mode::FocusNav; handle_focus_nav_key dispatches the same prefix keymap
    (non_indexed_action_for_key / command_for_key / indexed_navigation_action
    with BindingDispatch::Prefix) but never auto-exits.
  • New AppState.command_layer flag, set on entry and kept across dialogs. The
    shared return helpers (leave_navigate_mode, leave_command_mode, leave_modal,
    confirm_close_cancel) route back to Mode::FocusNav while the flag is set — this
    is what makes dialogs suspend-and-return.
  • New bindable action EnterFocusNav, wired as focus_nav, unset by default
    no change to existing keymaps. Existing Navigate / Navigator behavior is
    untouched.

Config

[keys]
focus_nav = "prefix+space"   # unset by default

Testing

  • nix build .#herdr passes.
  • herdr config check accepts focus_nav and still flags unknown keys.
  • Manual: enter the layer, chain pane/tab/workspace actions, open a rename dialog
    and confirm both commit and Escape return to the command layer; Escape from the
    layer returns to the terminal.

Add a new Mode::FocusNav: a sticky navigation mode modeled on resize mode.
Enter it via the configurable `focus_nav` keybind (unset by default) and it
stays open so you can chain movements without re-pressing the prefix each time:

  h/j/k/l or arrows -> move pane focus
  Tab / Shift+Tab   -> next / previous tab
  ] / [             -> next / previous workspace
  esc / enter       -> exit

Unlike the existing one-shot prefix actions and the navigator/goto pickers,
focus stays in the mode until Escape, giving a vim-like modal navigation layer
over panes, tabs, and workspaces.
@kangal-bot

Copy link
Copy Markdown
Collaborator

Hi @adrien-barret, thanks for your interest in contributing.

Herdr does not accept unsolicited implementation pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS.

The pull request author is not an approved contributor.

If you encountered a reproducible bug, report the observed behavior through the bug issue template. A report does not reserve the work or authorize a pull request; accepted fixes are normally implemented by Herdr’s maintainer-controlled agents.

Feature requests, behavior changes, and other proposals belong in GitHub Discussions. Do not open an issue merely to justify an implementation that was already written.

If a maintainer explicitly wants this implementation, they can reopen the pull request. Reopening by anyone else will be closed again automatically.

See https://github.com/herdrdev/herdr/blob/master/CONTRIBUTING.md for the contribution policy.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 53f17736-585a-4c02-baf4-8749032954b2

📥 Commits

Reviewing files that changed from the base of the PR and between 952729e and 3fcae32.

📒 Files selected for processing (9)
  • src/app/input/mod.rs
  • src/app/input/modal.rs
  • src/app/input/navigate.rs
  • src/app/mod.rs
  • src/app/state.rs
  • src/config/keybinds.rs
  • src/config/model.rs
  • src/ui.rs
  • src/ui/menus.rs

📝 Walkthrough

Walkthrough

The application adds a configurable Mode::FocusNav. Users can enter it through a navigation action, move focus across panes, tabs, and workspaces, exit with configured keys, and view navigation hints in the mode bar.

Changes

Focus navigation

Layer / File(s) Summary
Configure the focus-navigation action
src/config/keybinds.rs, src/config/model.rs
Keybinding models, defaults, overlays, validation, deserialization, and profile generation now include focus_nav.
Enter focus-navigation mode
src/app/input/navigate.rs, src/app/state.rs
EnterFocusNav resolves through the configured binding and switches TUI and test navigation into Mode::FocusNav.
Route and process focus-navigation keys
src/app/input/mod.rs, src/app/mod.rs, src/app/input/modal.rs
FocusNav keys reach handle_focus_nav_key, which dismisses update notifications, exits on configured keys, and navigates panes, tabs, and workspaces.
Render the focus-navigation overlay
src/ui.rs, src/ui/menus.rs
The mode bar renders a NAV overlay with pane, tab, workspace, and exit key hints.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TerminalKey
  participant Keybinds
  participant NavigateAction
  participant App
  participant UI
  TerminalKey->>Keybinds: resolve focus_nav
  Keybinds->>NavigateAction: return EnterFocusNav
  NavigateAction->>App: switch to Mode::FocusNav
  TerminalKey->>App: send navigation key
  App->>App: handle_focus_nav_key
  App->>UI: render focus-navigation overlay
Loading

Possibly related PRs

Suggested labels: ai-review

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

Warning

⚠️ This pull request shows signs of AI-generated slop (description_diff_mismatch). It has been flagged by CodeRabbit slop detection and should be reviewed carefully.

@kangal-bot kangal-bot closed this Aug 13, 2026
@adrien-barret adrien-barret changed the title feat: persistent focus-navigation mode feat: persistent command layer (vim-like navigation mode) Aug 13, 2026
@adrien-barret

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Pull request is closed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants