bcd — Bookmark-based Directory Navigation
A CLI tool for navigating to predefined directory bookmarks with hierarchical organization.
Features
- Static bookmarks defined in KDL config files
- Hierarchical organization with
basenodes - Local and global config file support
- Multi-file merging with precedence rules
- Shell integration for bash, zsh, and fish
Installation
cargo build --release
sudo cp target/release/bcd /usr/local/bin/
Shell Integration
Bash (~/.bashrc):
source /path/to/bcd/shell/bcd.bash
Zsh (~/.zshrc):
source /path/to/bcd/shell/bcd.zsh
Fish (~/.config/fish/config.fish):
source /path/to/bcd/shell/bcd.fish
Getting Started
Let's create your first bookmark to see how bcd works.
1. Create a global config file
mkdir -p ~/.config/bcd
touch ~/.config/bcd/config.kdl
2. Add your first bookmark
Open ~/.config/bcd/config.kdl in your editor and add:
bookmark"home""~"bookmark"config""~/.config"3. Try it out
bcd home # Jumps to your home directory
bcd config # Jumps to ~/.config
4. Add a hierarchical bookmark
Edit your config file to organize related directories:
bookmark"home""~"bookmark"config""~/.config"// Group project directories under a base
base"proj""~/projects"{ bookmark"work""work-stuff" bookmark"personal""personal-projects"}Now you can navigate with dot notation:
bcd proj.work # Jumps to ~/projects/work-stuff
bcd proj.personal # Jumps to ~/projects/personal-projects
5. See all your bookmarks
bcd -l
6. Add project-specific bookmarks (optional)
If you have a project directory where you want local bookmarks:
cd ~/projects/my-project
echo 'bookmark "src" "src"' > .bcd.kdl
bcd src # Jumps to ~/projects/my-project/src
That's it! You now have a working bookmark system. See the Configuration section below for advanced features like merging, precedence, and the root flag.
Configuration
Config File Locations
Global config: ~/.config/bcd/config.kdl (or $XDG_CONFIG_HOME/bcd/config.kdl)
Local configs (searched from cwd upward, in precedence order per directory):
.bcd.local.kdl(highest precedence, for gitignored overrides)bcd.local.kdl.bcd.config.kdlbcd.config.kdl.bcd.kdlbcd.kdl
Config Syntax
// Stop upward traversal at this config
roottrue// Top-level bookmark (absolute or home-relative)
bookmark"dot""~/.dotfiles"// Base with nested bookmarks (paths are relative)
base"projects""/home/user/projects"{ bookmark"hop""holistic-open-presence"// Nested bases join paths
base"rust""rust-projects"{ bookmark"bcd""bcd-tool"}}Path Rules:
- Global config: Can use absolute (
/) or home-relative (~) paths - Local configs: Must use relative paths only
- Inside
basenodes: Must use relative paths (for all configs)
Merging:
- All discovered configs are merged together
- Closer configs (to cwd) take precedence over distant ones
- Top-level names (bookmarks and bases) must be globally unique within a root scope
- Traversal stops when hitting a config with
root true
Usage
Navigate to a bookmark:
bcd dot # Jump to top-level bookmark
bcd projects.hop # Jump to nested bookmark
bcd projects.rust.bcd # Jump to deeply nested bookmark
List all bookmarks:
bcd --list
# or
bcd -l
Example Config
~/.config/bcd/config.kdl:
bookmark"dot""~/.dotfiles"bookmark"tmp""/tmp"base"work""/home/user/work"{ bookmark"api""services/api" bookmark"web""web-app"}~/projects/.bcd.kdl:
roottruebase"personal""."{ bookmark"blog""my-blog" bookmark"scripts""scripts"}With these configs and cwd in ~/projects/somewhere:
bcd dot→~/.dotfilesbcd work.api→/home/user/work/services/apibcd personal.blog→~/projects/my-blog
Development
Build:
cargo build
Run tests:
cargo test
License
MIT (or your choice)