bmrk — Bookmark Manager and Directory Navigator
A fast, compact TUI for directory navigation and bookmark management.
What is bmrk?
bmrk is a compact inline TUI that fits in 8 rows and never takes over your terminal screen. Navigate directories, manage bookmarks, search for folders and files — all from the keyboard.
The binary is bmrk. The shell wrapper bm wraps it and handles cd automatically — because a
process cannot change its parent shell's directory, a thin wrapper is required (the same approach
used by fzf, zoxide, and autojump).
Features
- Compact inline mode — 8 rows, no fullscreen takeover, terminal fully restored on exit
- Bookmarks — save and jump to favorite directories;
bm myprojectnavigates instantly - Interactive tree view — directory navigation with expand/collapse
- Fuzzy search — fast asynchronous search with intelligent matching
- Disk selection — browse and switch between all drives/mount points (
dkey) - Mouse support — click, double-click, scroll
- Customizable — TOML configuration with theme presets and custom colors
Installation
Step 1 — Install the bmrk binary
From crates.io:
From source:
The binary is at target/release/bmrk (Linux/macOS) or target\release\bmrk.exe (Windows).
Step 2 — Set up the bm wrapper
The repository includes three ready-made wrapper files. Each one integrates bmrk with a specific
shell so that cd works correctly. Pick the file that matches your environment.
bm.bat — Windows CMD
What it does. bm.bat is a batch script that runs bmrk.exe and redirects its stdout to a
temporary file. If the captured output is a valid directory path, it calls cd /d to change the
current session's directory. Non-directory output (help text, version, bookmark lists) is printed
as-is. The previous directory is saved in %BMRK_PREV_DIR% so that bm - can return to it.
Flags that do not trigger navigation (-h, --help, -v, --version, -l, --list, -a,
--add, -c, -d, --del) are passed straight through to bmrk.exe.
Installation:
-
Copy
bmrk.exeandbm.batto the same directory that is on yourPATH(e.g.C:\Users\<YourName>\bin\). -
If that directory is not on your PATH yet, add it and open a new CMD window:
setx PATH "%PATH%;C:\Users\<YourName>\bin" -
Test:
bm --version bm
bm.ps1 — Windows PowerShell
What it does. bm.ps1 defines a bm function for PowerShell. It runs bmrk.exe, captures
stdout to a temporary file, and calls Set-Location if the result is a valid directory path.
The previous directory is stored in $env:BMRK_PREV_DIR for bm - support. Pass-through flags
(-h, --help, -v, --version, -l, --list, -a, --add, -c, -d, --del) are forwarded
directly to bmrk.exe without any cd logic. Compatible with Windows PowerShell 5.1 and
PowerShell 7+.
Installation:
-
Copy
bmrk.exeto a directory on your PATH (e.g.C:\Users\<YourName>\bin\). -
Open your PowerShell profile for editing:
notepad $PROFILEIf the file does not exist yet, create it first:
New-Item -ItemType File -Force $PROFILE -
Add the following line to your profile:
. "C:\path\to\bmrk\bm.ps1" -
Reload the profile:
. $PROFILE -
Test:
bm --version bm
bm.sh — bash, zsh
What it does. bm.sh defines a bm function for POSIX-compatible shells (bash and zsh). It
runs bmrk via command substitution, captures stdout, and calls cd when the result is a valid
directory. The previous directory is stored in $BMRK_PREV_DIR for bm - support. Any output
that is not a directory path (help text, version, bookmark list) is echoed to the terminal
unchanged. For fish, use bm.fish instead (see below).
Installation — bash:
-
Copy the
bmrkbinary to a directory on your PATH:# or: sudo cp target/release/bmrk /usr/local/bin/ -
Source the wrapper from your shell config:
-
Reload and test:
Installation — zsh:
Same steps as bash, but add to ~/.zshrc instead of ~/.bashrc.
bm.fish — fish
What it does. bm.fish defines a bm function for fish. Fish uses its own function-file
format and cannot source bm.sh directly, so this is a separate file. It runs bmrk, captures
stdout, and calls cd when the result is a valid directory. The previous directory is stored in
$BMRK_PREV_DIR for bm - support. Any output that is not a directory path (help text, version,
bookmark list) is echoed to the terminal unchanged.
Installation:
-
Copy the
bmrkbinary to a directory on your PATH:# or: sudo cp target/release/bmrk /usr/local/bin/ -
Copy or symlink
bm.fishinto fish's functions directory:# or, to keep it in sync with the repo: -
Fish picks up functions in that directory automatically — no reload step needed. Test with:
Usage
# Bookmark management
Keyboard shortcuts (inside TUI)
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
l / → |
Expand directory |
h / ← |
Collapse directory; go to parent once collapsed (from the root row, always goes to parent) |
u |
Go to parent directory |
Backspace |
Go back (undo last navigation) |
Enter |
Go into directory (change root) |
q |
Exit and cd to selected dir |
Esc |
Exit without cd |
/ |
Search |
Tab |
Quick jump (type a folder name to jump to it) |
m |
Create bookmark |
' |
Select bookmark |
d |
Disk selection |
c |
Copy selected item's path to clipboard |
Configuration
Config file is created automatically on first run:
- Linux/macOS:
~/.config/bmrk/config.toml - Windows:
%APPDATA%\bmrk\config.toml
Bookmarks are stored as bookmarks.json in the same directory. A background-built directory
index cache lives alongside them as dir_index.txt — it's a performance optimization, not user
data, so it's safe to delete to force a rebuild.
[]
= "default" # default, gruvbox, nord, tokyonight, dracula, obsidian
= 80 # Truncate long names in the middle (0 = disabled)
= "unicode" # "unicode" (▼▶) or "ascii" (v>)
= true # Show the selected item's full path in the header (Tab mode too)
[]
# header_path_color = "cyan" # Path/label in the header row
# header_hints_color = "darkgray" # Key hints in the header row
# directory_color = "gray" # Directory names; also the header icon (▼)
# See docs/configuration.md for all available color fields
[]
= true
= true
= 1
[]
= ["/"]
= ["m"]
= ["'"]
= ["d"]
= ["u"]
= ["c"]
= ["Backspace"]
= ["q"]
= ["Esc"]
[]
= true # Background directory index accelerating Tab/`/` under `roots`
= 24 # Rebuild once the cached index is older than this
# roots = ["/home/username"] # Defaults to the home directory
# ignore_dirs = ["node_modules", "target", ".git"] # Replaces the default skip-list, not merged
How the wrapper works
bmrk writes its TUI to stderr (visible in the terminal) and the selected directory path to
stdout. The wrapper captures stdout via a temp file (CMD: set /p; PowerShell/bash: $t):
- If captured output is a valid directory path →
cdto it (saves previous dir forbm -) - If output is empty (Esc pressed) → do nothing
- Otherwise → print the output as-is (help, version, bookmark list)
| Command | bmrk stdout | Wrapper action |
|---|---|---|
bm (TUI → q) |
/selected/path |
cd there |
bm myproject |
/bookmarked/path |
cd there |
bm myproject/sub |
/bookmarked/path/sub |
cd there |
bm - |
(no bmrk call) | cd to previous dir |
bm -l |
Bookmarks: … (text) |
Print it (passthrough) |
bm -a work |
Bookmark 'work' added: … |
Print it (passthrough) |
bm -d work |
Bookmark 'work' removed |
Print it (passthrough) |
bm --help |
Help text | Print it (passthrough) |
bm -v |
Version + build info | Print it (passthrough) |
bm (TUI → Esc) |
(empty) | Do nothing |
License
MIT — see LICENSE.
See CHANGELOG.md for version history.