Seamless pane navigation between Herdr panes and Vim/Neovim splits: a port of christoomey/vim-tmux-navigator's core h/j/k/l navigation to Herdr.
This directory contains the Herdr-side helper, a small Rust binary. Pair it with the Vim/Neovim plugin in the same repository: vim-herdr-navigator.
With both installed, a single set of Ctrl-h/j/k/l keys moves between Vim/Neovim splits and Herdr panes as if they were one grid:
- If the active Herdr pane is running Vim/Neovim, the key is sent into the editor.
- Vim/Neovim moves between its windows first; at an edge it calls back to focus the neighboring Herdr pane.
- In any other pane, the key just moves Herdr focus.
The editor integration includes native Neovim Lua and classic Vimscript adapters.
vim-tmux-navigator works by pairing two halves:
- tmux keybindings detect whether the active pane is Vim-like. If yes, tmux sends
C-h/j/k/linto Vim; otherwise it selects the neighboring tmux pane. - the Vim plugin maps
C-h/j/k/l, runswincmd h/j/k/l, and if the Vim window did not change, forwards the navigation back to tmux.
This project ports that idea to Herdr using the public herdr CLI.
- Herdr (provides the
herdrCLI on yourPATH) - No Rust toolchain needed for prebuilt platforms (macOS arm64/x86_64, Linux arm64/x86_64);
cargo(1.85+) only for building from source.
All options put a vim-herdr-navigator binary on your PATH.
Plugin build hook (recommended): if you install the companion Vim/Neovim
plugin, its install.sh build hook installs this helper too —
see the root README. The options below are for managing
the helper yourself.
Shell installer (prebuilt binary, no Rust needed):
curl -LsSf https://github.com/AVGVSTVS96/vim-herdr-navigator/releases/latest/download/vim-herdr-navigator-installer.sh | shInstalls into ~/.local/bin.
cargo-binstall (prebuilt binary via cargo):
cargo binstall --git https://github.com/AVGVSTVS96/vim-herdr-navigator vim-herdr-navigatorcargo install (build from git):
cargo install --git https://github.com/AVGVSTVS96/vim-herdr-navigator --package vim-herdr-navigatorThis builds and installs into ~/.cargo/bin (make sure it's on your PATH).
From source:
git clone https://github.com/AVGVSTVS96/vim-herdr-navigator
cd vim-herdr-navigator
cargo build --release
# binary is at target/release/vim-herdr-navigator
ln -sf "$PWD/target/release/vim-herdr-navigator" ~/.local/bin/vim-herdr-navigatorMake sure the install target (~/.local/bin, ~/.cargo/bin, etc.) is on PATH.
Verify:
vim-herdr-navigator --version
vim-herdr-navigator doctor-
Install this helper (above) and check it's healthy with
vim-herdr-navigator doctor. -
Add the keybindings to your Herdr config. Generate a ready-to-paste snippet:
vim-herdr-navigator config
Paste the output into your Herdr config's keybindings, then restart Herdr or run
herdr server reload-config. -
Install the companion Vim/Neovim plugin vim-herdr-navigator.
vim-herdr-navigator config prints exactly this (one block per direction):
[[keys.command]]
key = "ctrl+h"
type = "shell"
command = "vim-herdr-navigator dispatch left"
description = "vim-aware pane left"
[[keys.command]]
key = "ctrl+j"
type = "shell"
command = "vim-herdr-navigator dispatch down"
description = "vim-aware pane down"
[[keys.command]]
key = "ctrl+k"
type = "shell"
command = "vim-herdr-navigator dispatch up"
description = "vim-aware pane up"
[[keys.command]]
key = "ctrl+l"
type = "shell"
command = "vim-herdr-navigator dispatch right"
description = "vim-aware pane right"Use --helper <name> if your command isn't named vim-herdr-navigator (e.g. a dev path). For extra keys, add more [[keys.command]] blocks with your own key = "..." values.
vim-herdr-navigator dispatch left # Herdr keybinding entrypoint
vim-herdr-navigator focus left # called by Vim/Neovim at an editor window edge
vim-herdr-navigator config # print a Herdr keybinding snippet
vim-herdr-navigator doctor # environment diagnostics
vim-herdr-navigator --versionPass --debug to any command to print diagnostic messages to stderr.
doctor reports the helper version, whether the herdr CLI is found, whether you're inside a Herdr session, and whether the cache dir is writable. It exits non-zero if a hard requirement (the herdr CLI) is missing.
The helper reads a few optional environment variables. Set them in your shell rc (e.g. ~/.zshrc) so the Herdr-spawned keybinding process inherits them, then restart Herdr.
| Variable | Default | Effect |
|---|---|---|
VIM_HERDR_NAVIGATOR_PATTERN |
(unset) | A regex OR-ed into the built-in Vim-like detection. Extends, never narrows, the set: the Herdr counterpart to tmux's @vim_navigator_pattern. Case-insensitive, unanchored. |
VIM_HERDR_NAVIGATOR_ZOOM |
preserve |
preserve keeps Herdr's native zoom across moves. unzoom un-maximizes the pane you move out of (runs herdr pane zoom --off before focusing). |
VIM_HERDR_NAVIGATOR_ENTRY_MARKERS |
(off) | Set to 1 so Vim/Neovim lands on the split nearest the entered edge. One switch: the helper writes the markers and the editor plugin (which inherits this variable) reads them; no separate plugin option. |
# Treat extra programs as "Vim-like" (here: also keep nav keys inside ssh):
export VIM_HERDR_NAVIGATOR_PATTERN='(view|l?n?vim?x?|fzf|ssh)'
# Un-maximize on directional moves instead of preserving zoom:
export VIM_HERDR_NAVIGATOR_ZOOM=unzoom
# Enable entry markers:
export VIM_HERDR_NAVIGATOR_ENTRY_MARKERS=1C-\(previous-pane toggle) is not yet ported; Herdr does not expose last-pane to the CLI. Inside Vim/Neovim you can still map<C-\>to<C-w>pyourself; a Herdr-side binding to the nativelast_paneaction is also possible, but the seamless cross-pane toggle (send to Vim/Neovim if the pane is an editor, else jump to the last pane) is blocked upstream until Herdr ships apane focus --lastCLI command.- Copy mode: navigation keys are unavailable while a pane is in Herdr's copy mode (copy mode consumes the keys). Exit copy mode to navigate.
- No edge wrapping: at the outer edge of the grid a directional key is a no-op; Herdr does not wrap focus around to the opposite side. This matches typical multiplexer behavior; there is nothing to configure.
The helper intentionally shells out to herdr pane ... commands instead of using Herdr's socket protocol directly. That keeps the implementation small and stable:
pane process-infoidentifies Vim/Neovim (and FZF) foreground processes.pane send-keysforwardsctrl+h/j/k/linto Vim-like panes.pane neighborlets the helper prepare a small entry marker when moving into a Vim/Neovim pane (opt-in, see Configuration).pane focusmoves Herdr focus.
It uses live pane process-info rather than persistent editor-pane registration, avoiding stale marker files when Vim/Neovim exits unexpectedly. Each herdr call is bounded by a short timeout so a stuck socket can't hang a keybinding.
The entry marker lives under:
${XDG_CACHE_HOME:-~/.cache}/vim-herdr-navigator/entry/<pane-id>
The Vim/Neovim plugin reads it on focus and jumps to the split nearest the edge that was entered.
The crate is laid out as:
helper/src/main.rs: CLI (clap) and command dispatchhelper/src/herdr.rs:herdrCLI invocation and JSON parsing (serde)helper/src/detect.rs: direction table and Vim-like process detectionhelper/src/config.rs: Herdr keybinding snippet renderinghelper/src/doctor.rs: environment diagnosticshelper/src/marker.rs: entry markers shared with the Vim/Neovim plugin
Build, format, lint, and test:
cargo build --release
cargo fmt
cargo clippy --all-targets
cargo testTests cover Vim-like process detection and config snippet rendering.