herdr plugin · v0.1.0

herdr-oil

An oil.nvim-style explorer for herdr. The directory listing is a text buffer. Rename, create, delete, move and copy by editing lines with vim keys, then :w. A fuzzy finder, live grep and a project switcher live in the same popup.

109 tests passing 12,297 lines of Rust macOS · Linux
Oil~/atlas · pending edits, real capture
 ▸ ~/atlas/ [+]  pending +2 ~2 ⧉1 −2  :w                                                       name 
+  ◆ benches/render.rs
+  ▸ notes/
   ▸ assets/                                                                                 2 items
   ▸ docs/                                                                                   2 items
~  ▸ bin/                                                                                     1 item
   ▸ src/                                                                                    2 items
   ▸ tests/                                                                                   1 item
   ◆ Cargo.toml                                                                                  60B
   ↪ DESIGN.md → docs/design.md                                                                  14B
   ◆ LICENSE                                                                                     12B
⧉  ▤ LICENSE-APACHE                                                                              12B
~  ◆ INTRO.md                                                                                    72B










Install

Link it, bind a few keys

Needs Rust (cargo). bat and ripgrep are optional; they power previews and grep when installed.

# clone, then link (the build hook runs cargo build --release)
git clone https://github.com/christineecker/herdr-oil
herdr plugin link "$PWD/herdr-oil"
herdr server reload-config
# ~/.config/herdr/config.toml
[[keys.command]]
key = "prefix+d"            # explorer
type = "plugin_action"
command = "herdr-oil.explorer"

[[keys.command]]
key = "prefix+shift+f"      # fuzzy files
type = "plugin_action"
command = "herdr-oil.finder"

[[keys.command]]
key = "prefix+slash"        # live grep
type = "plugin_action"
command = "herdr-oil.grep"

[[keys.command]]
key = "prefix+shift+o"      # projects (any free chord)
type = "plugin_action"
command = "herdr-oil.projects"

Options go in $(herdr plugin config-dir herdr-oil)/config.toml. See config.example.toml for the editor, open target, Trash or permanent delete, and display settings.

Screens

One editing session, start to finish

Captured from a herdr pane running the release binary against a sample project. The keys under each screen are exactly what was sent. Nerd Font icons are shown as simple glyphs here.

Oil

  
Try the model

Edit the lines, watch the plan

Each line carries a hidden id, as in oil.nvim. This is the same rule set the planner uses, reduced to one directory. Type in the boxes, duplicate a line, delete one, add a new one.

~/atlas/

+ new~ renamed⧉ copy

:w would do

How :w works

Diff every buffer, then apply in three phases

Edits from all visited directories are planned together. Validation runs first, so a clash stops the save before any file moves.

Where the entry's id appears nowOperation
nowhereDELETE to the Trash, or permanently if configured
at its original path, plus other placeskept; every other place is a COPY
only somewhere elsefirst place is a MOVE (same folder shows as RENAME), the rest are copies
a line with no idCREATE; a trailing / makes a directory, a/b/c.txt creates parents
PHASE 1

Copy into staging

Copies are made first, while every source is still untouched, into hidden staging names.

PHASE 2

Moves and deletes, deepest first

A moved entry is parked inside the nearest folder that never moves. That makes swaps, case-only renames and "move the child out, delete the parent" safe.

PHASE 3

Land, shallowest first

Creates and staged entries land at their final paths, re-rooted under folders that were renamed. An occupied path is reported and the entry is put back.

Validation rejects two lines with the same name, a name that already exists and is not being vacated, moving a folder into itself, absolute paths, and an id line that was emptied. On macOS names are compared case-insensitively, which is how the session above caught DESIGN.md landing next to design.md.

Keys

Vim in the explorer, fzf in the finder

g? inside the popup shows the full sheet.

Design notes

Defaults worth knowing, and current limits

Decision

Enter views the file inside oil

The default open = "view" shows the file highlighted and scrollable in the oil window; e edits it in $EDITOR in the same popup. open = "auto" instead types $EDITOR file into the pane you came from when it idles at a shell prompt, and never types names that contain control characters.

Decision

Keybindings

The suggested prefix d, prefix ⇧F and prefix / are free in herdr’s defaults. If a key does nothing, a built-in action on the same chord wins; set that built-in to "" in [keys].

Decision

Esc closes the explorer

Esc keeps its vim meaning first: it leaves insert, visual or command mode and cancels a half-typed key. On a clean slate in normal mode it closes the popup, after a save, discard or cancel prompt when edits are unsaved.

Decision

Splits close with the editor

Split and tab targets run exec $EDITOR, so quitting the editor closes the pane. Typing into the origin pane does not use exec.

Decision

Confirm dialog stays on

Every save is reviewed by default. confirm = false skips it, except when something would be deleted.

Limit

No undo for applied changes

u undoes buffer edits only. Deleted files can be restored from the Trash; renames and moves have no history.

Limit

Relative symlinks keep their target text

Moving a relative symlink into another folder does not rewrite it, so it can break. The DESIGN.md move in the screens is an example.

Limit

Screens come from a regular pane

herdr gives popups no readable pane id, so the captures were taken in a normal herdr pane running the same binary.

Checked

Tested against real directories

The planner and apply engine tests run on temporary folders: swaps, case-only renames, nested renames, recursive copies with symlinks, and no leftover staging files.

Acknowledgements

Built on the idea of oil.nvim

herdr-oil exists because of oil.nvim by Steven Arcangeli. The central idea comes from oil: the directory listing is an ordinary editable buffer where every line carries a hidden entry id, and saving diffs that buffer against the disk and asks before applying creates, renames, moves, copies and deletes. Keys like - for the parent directory and g. for hidden files follow oil too.

herdr-oil is an independent Rust reimplementation for herdr popups, not a port, and uses no oil.nvim code. If you live in Neovim, use the original.

cargo test

109 tests, all passing

Source

Read the code

Every file in the plugin, in reading order. Search filters to lines that contain the text.