A terminal file manager (TUI) written in Rust using ratatui + crossterm.
sb (Shell Buddy) is a keyboard-driven explorer focused on fast local navigation with optional integrations for previews, archive handling, searching, remote mounts, and lightweight Git workflows.
- In-TUI Git workflow — diff preview → status review → commit → push → optional tag, all without leaving the file manager (
G) - Inline path filters — type
^prefix,suffix$, or~containsdirectly in the path bar to live-filter the listing (Tab) - Integration manager with one-key install — see which optional tools are missing and install them via Homebrew without leaving the TUI (
I) - Age encryption — protect or decrypt
.agefiles in-place with a single keypress (p) - Per-file notes — attach notes to any file, stored in a hidden
.sbfile per directory (Ctrl+n) - tmux-aware splits —
iopens a shell + preview pane;Eopens a shell + editor pane - Clipboard edit —
Ctrl+eopens the current clipboard contents in$EDITORfor quick manipulation - CLI list/tree modes —
sb -l,sb -t,sb -l2produce TUI-consistent column output;sb <file>skips the TUI and opens with the best available viewer
Build and Run
cargo build
cargo runRelease build:
cargo build --releaseRelease binary path:
target/release/sb
List mode examples:
# Current directory
sb -l
# Include hidden entries
sb -a
sb -la
# Recursive display size + percent share columns
sb -l --total-size
# Full tree output
sb -t
# Tree output limited to depth 2
sb -l2
sb -l 2
# Path can appear before or after --total-size
sb -la /var/log --total-size
sb --total-size -l /var/log
# Open a file directly with the best available previewer/viewer
sb README.md
sb diagram.mmd
# Open a file with pager mode enabled
sb -l README.md
# Open a file in $EDITOR (fallback: nano)
sb -e README.mdCLI List Mode
-l [PATH]: list directory entries and exit.-a [PATH]: same as-l, but includes hidden files.-la [PATH]: same as-l, but includes hidden files.-e [FILE]: open file in$EDITOR(fallback:nano) and exit.-t [PATH]: tree-list recursively (full depth) and exit.-lN [PATH]/-l N [PATH]: tree-list to depthNand exit.--total-size: when used with-l,-a, or-la, shows recursive display size for each entry and a%column with that entry's share of the listed total.
Notes:
PATHis optional and can be placed after-l/-a/-laor after--total-size.- The list output reuses the file manager's auto-calculated owner/group column widths for consistent alignment.
- When invoked as
sb <FILE>, the app skips the TUI and opens the file directly with best-available viewer output (no pager). - When invoked as
sb -l <FILE>, direct file mode uses pager-enabled output.
Installation
cargo install shell-buddybrew install hjelev/tap/sbgit clone https://github.com/hjelev/sb.git
cd sb
cargo install --path .Prebuilt binaries and the auto-installer script are available in GitHub Releases. Use the installer there if you want the fastest setup without building from source.
Core Controls
q/Esc: quit- ```: toggle modes
Enter/Right: open entry / preview fileLeft/Backspace: go to parent / leave mounted view- mouse left-click: select clicked entry
- mouse double left-click: open clicked entry (same behavior as
Right) - mouse right-click: go to parent / leave mounted view (same behavior as
Left) Up/Down/PageUp/PageDown/Home/End: navigationSpace: mark/unmark current entry*: toggle all markscorF5: copy to internal clipboardCtrl+c: copy selected full path(s) to system clipboardCtrl+e: edit system clipboard text in$EDITORv: pastem: move (cut+paste behavior) from internal clipboardd: delete (with confirmation)x: toggle executable bit on selected file(s)p: protect/unprotect file withage(.age)F2orr: rename (or bulk rename withvidirwhen multiple are marked)eorF4: open in$EDITOR(orhexeditfor binary if available)E: split tmux session with shell on the left and$EDITORon the right (Ctrl+eis clipboard edit)n: new file or folder (folder starts with/)Ctrl+n: add/edit note for selected item(s)t: open~/.todoin$EDITOR(creates it if missing)Z: archive create/extract flowC: compare marked file vs cursor file withdeltaG: Git commit workflow with diff preview,git status, commit/push, and optional post-push tag creationo: open with system GUI opener (openon macOS,xdg-open/gio openelsewhere)f: open Search overlay (filename search; uses built-in search iffzfis missing)g: content search (rg, optionalfzfhandoff; falls back to built-in Search content mode whenrgis missing);: open command prompt, run shell command, then wait for keypress before returning to TUIS: SSH/rclone remote pickeri: split shell (left) +lesspreview (right 30%)I: integrations panelb: bookmarks panelCtrl+z: drop to interactive shell in current directoryTab(in browsing): edit current path inline; supports/path/^prefix,/path/suffix$, and/path/~containsfiltersTab/Shift+Tabin Help/Search/Bookmarks/Remote Mounts/Sorting/Integrations: cycle tabs forward/backwards: toggle folder size calculation in listingCtrl+s: open sort mode menu+: expand selected/marked non-empty folder(s) by one tree level-: contract selected/marked folder(s) by one tree level- quick
++: expand selected/marked non-empty folder(s) to max depth - quick
--: collapse all opened folders in tree view 0-9: jump to bookmark (SB_BOOKMARK_0..9).: toggle hidden files~: jump to homeh: help overlay
Search Overlay Functions
When Search is open (f or fallback from g):
Up/Down: move result selectionEnter: open selected matchEsc: close SearchCtrl+t: toggle scope betweenFilenameandContent- Query supports regex forms:
re:patternor/pattern/i - Content-mode results render as
path:linewith highlighted matching snippets - Content-mode scanning runs asynchronously (UI remains responsive)
Content limits editor (content scope):
Ctrl+l: open/close limits editorUp/Down: select which limit to editLeft/Rightor-/+: decrease/increase selected limitShift+ adjust: 10x stepr: reset limits from environment/default valuesEnter/Esc: close limits editor
Path Editing and Filters
Press Tab while browsing to edit the current path in place.
- Enter a directory path and press
Enterto jump there. - Add a suffix filter to keep the current directory but narrow visible entries:
/some/path/^foo: names starting withfoo/some/path/bar$: names ending withbar/some/path/~baz: names containingbaz
Escfrom path-edit mode clears the active filter and returns to browsing.
The active filter remains visible in the header until you change directories.
Git Workflow
Press G in a Git working tree to:
- preview the current diff (
deltaside-by-side when available) - view
git status - confirm whether to continue
- enter a commit message inside the TUI
- auto-run
git add --all,git commit, andgit push origin HEAD - optionally press
timmediately after a successful push to create and push a tag
When tagging, the tag input box is prefilled from the latest reachable Git tag when one exists.
Integrations
Required behavior:
less: file viewing fallback$EDITOR: file editing command (defaults tonanoif unset)
Optional integrations (auto-detected, toggle in I panel):
-
In the Integrations panel, pressing
Enteron a missing integration asks for confirmation and can install with Homebrew when available (macOS and Linux/Homebrew). -
VCS:
git -
Viewers/previews:
bat,glow,mmdflux,jnv,csvlens,hexyl,chafa,viu,sox,pdftotext,asciinema,links -
Diff/edit helpers:
delta,hexedit,vidir,tmux -
Archives:
zip/unzip,tar,7zfamily (7z/7zz/7zr),rar/unrar,fuse-zip,archivemount -
Security:
age -
Remote mounts:
sshfs,rclone -
Search:
rg,fzf -
Clipboard backends:
wl-copy/wl-paste,xclip,xsel,pbcopy/pbpaste
Remote picker (S) also lists existing local mounted folders discovered under:
/media/$USER/run/media/$USER/mnt/run/user/$UID/gvfs
If an optional tool is not available, the feature is skipped or falls back gracefully.
Environment Notes
NERD_FONT_ACTIVE=1: enable Nerd Font iconsNO_COLOR=1: disable file name colors (modifiers like bold/dim still apply)TERMINAL_ICONS=0: hide all file icons (Nerd Font glyphs and emoji)EDITOR: editor command used bye/F4,E,Ctrl+e, andtSB_BOOKMARK_0...SB_BOOKMARK_9: bookmark directoriesSB_SEARCH_CONTENT_MAX_FILES: built-in Search content-mode max files scanned (default:20000)SB_SEARCH_CONTENT_MAX_HITS: built-in Search content-mode max matches returned (default:2000)SB_SEARCH_CONTENT_MAX_FILE_BYTES: built-in Search content-mode per-file byte cap (default:2097152/ 2 MiB)
Shell Integration
To enable automatic directory change on exit, add the following function to your shell configuration file (e.g., ~/.bashrc, ~/.zshrc):
sb() {
"$HOME/.cargo/bin/sb" "$@"
if [ -f /tmp/sb_path ]
then
cd "$(cat /tmp/sb_path)"
rm -i -f /tmp/sb_path
fi
}After adding the function, reload your shell configuration:
source ~/.bashrc # or source ~/.zshrcProject Structure
Current code layout is modular:
src/main.rs: app state, event loop, orchestration, and top-level workflowssrc/app_input.rs: input editing helperssrc/app_meta.rs: permissions/owner/group metadata helperssrc/app_render_cache.rs: entry render-cache generationsrc/app_search.rs: built-in search and path-filter matching helperssrc/app_files.rs: file-type classification helperssrc/app_sizes.rs: folder-size and aggregate-size scanning helperssrc/app_git.rs: Git status/background cache helperssrc/app_archive.rs: archive mount and preview lifecycle helperssrc/integration/: integration catalog, probing, rows, and install flowsrc/ui/: CLI output, icons, panels, search spans, and status renderingsrc/util/: shared formatting helpersCargo.toml: dependencies and release profile settings
Dependencies
From Cargo.toml:
ratatui(UI)crossterm(terminal events/raw mode)chrono(timestamps)devicons(file icons)hostname(header prompt)users(owner metadata)clap(present as dependency)regex(search regex mode)rayon(parallel entry render-cache build)unicode-width(display-width-aware list-mode alignment)







