Skip to content

Repository files navigation

i

A fuzzy, recursive cd replacement. Type a few letters, land several directories deep — not just the immediate children cd's own tab-completion gives you.

License: MIT Release Rust

curl -fsSL https://raw.githubusercontent.com/iwandejong/i/main/install.sh | sh

Usage

i              # cd $HOME, same as plain `cd`
i test         # cd to the best fuzzy match for "test" under $PWD
i ../project   # scoped one level up first, then fuzzy-searching "project"
i te<TAB>      # cyclable menu of the top matches, non-contiguous chars highlighted
i -2           # cd up 2 directories (../..)
  • Scoped to $PWD, not your whole home directory — and matches at any depth, not just immediate children.
  • Live navigation while typing: ../ rescopes to the parent (repeat for further up), ~/ jumps home, / jumps to filesystem root. Whatever follows the last / is the fuzzy query.
  • Ranked sensibly: an exact path match always wins outright; otherwise name matches beat full-path matches, and shallower results beat deeply-buried ones (cache dumps, app-support ephemera) when scores are close.
  • No daemon, no whole-disk cache — each root is walked live, per query.

There's no full-screen picker UI: the i binary just prints its best match(es) and exits, and the shell wrapper cds to whatever came back (or hands zsh a real completion menu for <TAB>). A fully-typed, unambiguous path resolves and cds there directly, no fuzzy noise mixed in.

Install

One-liner (no Rust required, macOS/Linux) — downloads the right prebuilt binary (macOS x86_64/arm64, Linux x86_64), installs it to ~/.local/bin, and wires up zsh or bash integration:

curl -fsSL https://raw.githubusercontent.com/iwandejong/i/main/install.sh | sh

Restart your shell (or source ~/.zshrc/~/.bashrc) and you're done.

One-liner (Windows, PowerShell) — same idea, installs to ~\.local\bin and wires up your $PROFILE:

irm https://raw.githubusercontent.com/iwandejong/i/main/install.ps1 | iex

Restart PowerShell (or . $PROFILE) and you're done.

Manual install, or building from source

Prebuilt binary — grab the tarball for your platform from the latest release. Each one bundles the i binary plus i.zsh/i.bash/i.ps1 (the shell wrappers):

tar xzf i-<target>.tar.gz
cp i-<target>/i ~/.local/bin/i   # i-<target>/i.zsh is what you'll `source` below

On Windows, install.ps1 (above) does this for you; by hand, put i.exe somewhere on your PATH and dot-source i.ps1 from your $PROFILE (see Shell integration below).

From source — requires Rust (stable, 1.75+):

git clone https://github.com/iwandejong/i.git && cd i
cargo build --release
cp target/release/i ~/.local/bin/i

Shell integration

The i binary only prints matching paths — it can't change your shell's directory itself. install.sh wires this up automatically on macOS/Linux; by hand:

# ~/.zshrc
source /path/to/i/shell/i.zsh

# ~/.bashrc
source /path/to/i/shell/i.bash
# $PROFILE
. /path/to/i/shell/i.ps1

Rename the i function in any wrapper to whatever you'd rather type — the binary can stay named i either way, since the wrappers call it explicitly (command i, or i.exe in PowerShell, where a same-named function would otherwise call itself). zsh, bash, and PowerShell all ship; bash and PowerShell get plain-list <TAB> completion (no menu-select or fuzzy-char highlighting — neither completion system supports that). fish isn't supported, but a port would be straightforward: function i; set d (command i $argv); and cd $d; end, minus completion.

Config

Optional JSON config, all fields optional (a partial file only overrides what it sets, the rest falls back to defaults). A lean starter file with just the scalar knobs (include_hidden, max_depth, max_entries) is created automatically on first run — excludes is deliberately left out of it so a future default change to that list still applies; add it yourself if you want to override it. Location follows the platform config dir + i/config.json, that's ~/Library/Application Support/i/config.json on macOS, ~/.config/i/config.json on Linux, %APPDATA%\i\config.json on Windows. Run i --config to print the full effective config (defaults merged with your overrides) and where the file lives. Shown below with defaults:

{
  "excludes": [".git", ".hg", ".svn", "node_modules", ".venv", "venv",
               "__pycache__", "target", ".cache", ".npm", ".cargo",
               ".rustup", ".Trash", "dist", "build", "proc", "sys", "dev",
               "Library"],
  "include_hidden": false,
  "max_depth": 5,
  "max_entries": 50000
}
  • excludes — directory names pruned entirely (never listed, never descended into), applied everywhere a walk can reach as you go ../.
  • include_hidden — set true to also walk into dot-directories.
  • max_depth / max_entries — safety caps so ~/ or / on a huge tree doesn't hang; you still get whatever it collected before hitting the cap.
How path navigation is parsed

See src/pathnav.rs (has unit tests) — each /-terminated segment is checked in order: .. pops the root up one level, ~ (only as the very first character) jumps to $HOME, a leading / jumps to filesystem root, and any other segment is consumed only if it's an exact, existing child directory — otherwise parsing stops and everything from there on is the fuzzy query. That's what lets ../test mean "go up one, then fuzzy-search test" without a query that merely contains a slash getting misparsed as navigation.

Project layout
src/
  main.rs     — CLI entry (clap), wires config + walker + search together
  config.rs   — loads i/config.json from the platform config dir, defaults
  pathnav.rs  — parses typed text into (resolved root, fuzzy query)
  walker.rs   — recursive directory walk with prune-list + safety caps
  search.rs   — fuzzy scoring, sorting, exact-match and depth preference
tests/
  walker_smoke.rs — confirms excludes prune subtrees, deep dirs still surface
shell/
  i.zsh       — the `i` wrapper function that actually cd's, plus completion
  i.bash      — bash equivalent (plain-list completion, no menu-select)
  i.ps1       — PowerShell equivalent (plain-list completion, no menu-select)
install.sh    — one-command installer for macOS/Linux (binary + shell integration)
install.ps1   — one-command installer for Windows (binary + PowerShell integration)
Known limitations
  • No frecency ranking (most-recently/often visited dirs) — pure fuzzy score today.
  • No .gitignore awareness — exclusion is the flat excludes list only.
  • Symlinked directories are skipped outright (avoids cycles).
  • No prebuilt Linux or Windows arm64 binary yet — build from source there.
  • zsh, bash, and PowerShell ship; fish ports are welcome contributions.

Contributing

See CONTRIBUTING.md.

License

MIT

About

Fuzzy, recursive cd replacement for the shell

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages