]> git.quilime.com - cfg.git/commitdiff
cd-smart Readme
authorGabriel Dunne <gdunne@quilime.com>
Sat, 19 Sep 2026 20:05:54 +0000 (13:05 -0700)
committerGabriel Dunne <gdunne@quilime.com>
Sat, 19 Sep 2026 20:05:54 +0000 (13:05 -0700)
.zsh/cd-smart.README.md

index d931a6502b89a16732bb34d8353b2b083f6cf0b3..136b11ba233bd330088962eee0c23a6a95cc17fa 100644 (file)
@@ -1,35 +1,34 @@
 # cd-smart
 
 A `cd` that learns where you go. About 250 lines of zsh, one plain-text
-database, no external processes on the `cd` path, and no dependencies beyond
-zsh itself (fzf is used by `cdi` when present).
+database, no external processes, and no deps beyond zsh itself. (`fzf` is 
+optionally used is used by `cdi` when present).
 
 ## Install
 
 ```zsh
-# ~/.zshrc, after compinit
 source ~/.zsh/cd-smart.zsh
 ```
 
-Files live next to the script: `cd-smart.tsv` (learned directories) and
-`cd-smart.aliases` (shortcuts defined at the prompt).
+Data files are siblings to the script: `cd-smart.tsv` (learned directories) and
+`cd-smart.aliases` (shortcuts).
 
 ## Use
 
 ```zsh
 cd ~/Projects/notes   # ordinary cd; the directory is learned
-cd agents                       # jump to the best learned match for "agents"
-cd open ag                      # words must appear in order: .../Projects/notes
-cd ag<TAB>                      # normal completion plus learned matches and shortcuts
-cdi ag                          # pick from matches in fzf; ctrl-/ toggles a preview
-cdi                             # browse everything learned
+cd foo                # jump to the best learned match for "foo"
+cd proj no            # words must appear in order: .../Projects/notes
+cd pr<TAB>            # normal completion plus learned matches and shortcuts
+cdi pr                # pick from matches in fzf; ctrl-/ toggles a preview
+cdi                   # browse everything learned
 ```
 
-Precedence inside the wrapper, first match wins:
+"first match wins" precidence:
 
 1. No argument, or anything with options, slashes, or a leading `.` or `~`,
    goes straight to the builtin. `cd ..`, `cd -`, `cd ~/x` are untouched.
-2. A single word that exists as a directory here.
+2. A single word that exists as a directory in the pwd.
 3. A single word that is a shortcut.
 4. Two words that work as the builtin's `cd old new` substitution.
 5. The best-scored learned directory containing the words in order.
@@ -38,17 +37,17 @@ Precedence inside the wrapper, first match wins:
 ### Shortcuts
 
 ```zsh
-cdalias osa ~/Projects/notes   # "cd osa" always goes there
-cdalias dl                               # current directory becomes "dl"
-cdalias                                  # list
-cdunalias dl                             # remove
+cdalias notes ~/Projects/notes   # "cd notes" always goes there
+cdalias dl                       # current directory becomes "dl"
+cdalias                          # list
+cdunalias dl                     # remove
 ```
 
 Shortcuts can also be declared in `.zshrc` before sourcing, and those win over
 saved ones:
 
 ```zsh
-typeset -gA CDS_ALIASES=(osa ~/Projects/notes)
+typeset -gA CDS_ALIASES=(notes ~/Projects/notes)
 ```
 
 ### Maintenance
@@ -73,43 +72,47 @@ Set before sourcing.
 
 ## How ranking works
 
-Each learned directory has a score and a last-visit time. A visit adds 1 to
-the score. At lookup time a candidate's rank is its score plus a bonus for an
+This area is largely riffing on how `zoxide` does it, but in my own way. Each 
+learned directory has a SCORE and a LAST-VISIT time. A visit adds 1 to
+the SCORE. At lookup time a candidate's rank is its SCORE plus a bonus for an
 exact basename match (+100) or basename prefix (+50) on the last query word,
 plus a recency bonus (20 within an hour, 15 within a day, 10 within a week,
-5 within a month).
+5 within a month). This is arbitrary, but seems to work well for now. I've continue
+to tweak it.
 
 Growth is bounded by aging. When the sum of all scores exceeds `CDS_MAXAGE`,
-every score is multiplied by `0.9 × CDS_MAXAGE / total`, entries that fall
-below 1 are dropped, and directories that no longer exist are pruned. Places
-you keep returning to stay; one-off visits fade out.
+every score is multiplied by `0.9 * CDS_MAXAGE / total`, entries that fall
+below 1 are dropped, and directories that no longer exist are pruned. The idea 
+is that places you keep returning to will stay, but one-off visits will fade out.
 
 ## Tests
 
+I vibe coded some tests. I've barely looked at this, but it works. It runs in a 
+throwaway sandbox and never touches your real database.
+
 ```zsh
 zsh ~/.zsh/cd-smart.test.zsh
 ```
 
-Runs in a throwaway sandbox and never touches your real database.
-
 ## Compared with zoxide
 
-[zoxide](https://github.com/ajeetdsouza/zoxide) solves the same problem and
-is the obvious alternative. The ranking model here is deliberately close to
-its design. The differences are mostly about scope.
+It's not fair if I don't compare to [zoxide](https://github.com/ajeetdsouza/zoxide)
+because I solve the same "problem" and `z` is the obvious alternative. 
+The ranking model I've come up with is deliberately close to its design. 
+The differences are mostly about scope. Here's the various diffs:
 
 | | cd-smart | zoxide |
 |---|---|---|
 | Implementation | ~250 lines of zsh, one file | ~2,000 lines of Rust plus a shell template per shell |
-| Shells | zsh only | bash, zsh, fish, nushell, PowerShell, and others |
-| Database | plain TSV you can read and edit | binary, with file locking |
+| Shells | zsh only. (sorry, not sorry). | bash, zsh, fish, nushell, PowerShell, and others |
+| Database | plain TSV you can read and edit as a human | binary, with file locking |
 | Command | wraps `cd` itself | separate `z` and `zi`; `--cmd cd` can replace `cd` |
 | Real directories vs. guesses | an existing local directory always wins, then shortcuts, then learned matches | with `--cmd cd`, an existing path also wins; otherwise `z` always guesses |
 | Tab completion | learned matches and shortcuts appear inside normal `cd <TAB>` | completion on the `z` command only |
-| Shortcuts | built in (`cdalias`) | none; use shell aliases |
-| Where learning happens | only under `CDS_ROOTS` | everywhere, minus `_ZO_EXCLUDE_DIRS` |
+| Shortcuts | built in (`cdalias`) | none -- use shell aliases |
+| Where learning happens | Exclusive: only under `CDS_ROOTS`.  | Everywhere, minus `_ZO_EXCLUDE_DIRS` |
 | Multi-word queries | words in order anywhere in the path; last word gets basename bonuses | words in order; last word must match the last path component |
-| Recency | additive bonus by age bucket | multiplier by age bucket (4×, 2×, 0.5×, 0.25×) |
+| Recency | additive bonus by age | multiplier by age (4×, 2×, 0.5×, 0.25×) |
 | Aging | same scheme: scale by 0.9 × cap / total, drop below 1, prune dead paths | same, default cap 10,000 |
 | Concurrency | last writer wins if two shells `cd` at the same instant | locked writes |
 | External processes | none on `cd` or lookup | one binary launch per `cd` and per query |