Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To "manage" in this context refers to maintaining a ranked database of your directory history so you can navigate without providing full or relative paths. The difference in practice:

With built-in `cd`:

Navigation is manual and location-dependent. To reach a deeply nested project, you must provide the exact path: `cd ~/src/work/clients/acme/frontend/src/components`

With sd:

Navigation is intent-based. Once `sd` has indexed a directory, you provide a fragment of the name: `sd comp`

How it works differently:

1. Passive Indexing: `sd` remembers all you cd actions (up to configurable limit, typically several 1000) and computes after each cd action a weighted score for each path you visit.

2. Intent Resolution: When you run `sd <string>`, it doesn't check your current working directory. It queries the database for the most "frecent" (frequent + recent) path matching that string and moves you there.

3. Ambiguity Handling: If "comp" matches multiple paths (e.g., `frontend/components` and `backend/components`), the power-law model I mentioned calculates which one is more relevant to your current "attention span" to resolve the tie.

The problem being solved is the cognitive load of remembering and typing long, nested file paths. It replaces a "search and find" task with a "recall" task.

so the core functionality is very similar to things like z/zoxide, but the ranking is using full visit history and detailed behaviour thus is different.



> To reach a deeply nested project, you must provide the exact path: `cd ~/src/work/clients/acme/frontend/src/components`

In key presses that is 'cd ~TABsTABwTABTABaTABfTABsTABcENTER', if it is an often used project, I likely have it in CDPATH, so it's 'c acmTABfTABsTABc' or if I am actively working 'CTRL-Rfro CTRL-R CTRL-R'.

To me it sounds like a solution looking for a problem. Why should I give up predictability when it won't really save keypresses. Not that keypresses are that expensive anyway.


That workflow is perfectly valid -- if you have a stable set of 5-10 projects, CDPATH and manual Tab-completion are hard to beat.

I built sd for a different scenario: when your 'active' set of locations to reach is large and/or shifts frequently. When managing dozens of repos, e.g., where sub-directories have identical names (e.g., client-a/src vs client-b/src), CDPATH becomes noisy and Tab-completion requires more prefix-typing.

Tools like zoxide (33k+ stars or so on github) or z have proven this is a widespread need. sd is my take on providing that functionality in a shell-native way using a qualitatively different ranking approach via utilization of full cd events history and a power-law "aging" model that I find more accurate for fast context-switching.

In my experience, this saves significant keypresses by allowing for shorthand matching. For example, I can reach .../client-a/src just by typing 'sd ent-a'. The algorithm disambiguates based on the ranking; if the top match is ever wrong (it rarely is for me), you can just do ^P <CR> (recall and re-run) to jump to the 2nd highest match.

But it’s definitely a matter of taste -- manual curation vs. an automated 'attention span' model.


Thanks for the explanation.

Do you really have hundreds of projects you work at at the same time?

> For example, I can reach .../client-a/src just by typing 'sd ent-a'. The algorithm disambiguates based on the ranking; if the top match is ever wrong (it rarely is for me), you can just do ^P <CR> (recall and re-run) to jump to the 2nd highest match.

CTRL-R can also do this, or does this tool also do partial matches, e.g. 'tas' matches '.../client-a/src' ?


To clarify the matching: sd uses AWK-based regex matching against the full logged pathname ($0 ~ pattern).

It does not use "fuzzy" sub-sequence matching (pooling 't', 'a', and 's' from different path segments). For .../client-a/src, you wouldn't use 'sd tas', but rather 'sd t-a' or 'sd a/src'.|

  'sd "cl.*src"'
would also be a valid jump.

Regarding CTRL-R:

* Filtering Noise: CTRL-R searches raw, chronological history. sd builds a scored directory stack from your history. You are querying a ranked index of destinations, not a linear tape of commands. This allows jumping to a directory visited 200 actions ago without scrolling through history with CTRL-R.

* Ranking Logic: CTRL-R is strictly chronological. sd uses a power-law "aging" model. If client-a is a daily driver and client-b was a one-off visit, sd correctly prioritizes client-a for a 'src' query, even if it wasn't the absolute last place visited.

* Spatial Cache: I don't work on 100 projects at once, but I do touch a "long tail" of ~100 distinct paths over several weeks/months (logs, build dirs, repos). sd acts as a cache for these nesting depths so I don't have to recall them.

Ultimately, you just provide a modestly specific pattern — 'sd t-a/s' or 'sd src' -- and the ranking handles the disambiguation.


I see. Sounds interesting, I guess it is just not for me.

How does it cope with the directory stack, what happens when I do a 'cd -' after using sd, where does it take me?

I mean fundamentally a filesystem is just a namespace and I can order it like the hell I want, it also supports different types of aliasing.


Sure, needs and tastes differ.

'cd -' behaves exactly as it always does. Functionality-wise, when you use the 'sd' wrapper (which shadows the builtin by default), it treats the standard cd behavior as a prioritized subset. If you provide a valid path -- 'cd path', 'cd ~-', 'cd -', or 'cd ..' -- it resolves that first and behaves as it always has. If you only used those commands, you would never even notice sd is there.

The power comes when you choose to use it: you are free to try 'cd src' and see if it moves you across the filesystem to the desired location based on your recent activity.

Regarding aliases: one can certainly manage navigation with symlinks and aliases. Historically, that was actually my incentive to write sd. I had dozens of symlinks and ~50 aliases like alias cdsrc='cd /path/to/deeply/buried/dir'. Maintaining that manual list became increasingly annoying. sd solved that by replacing manual curation with a sliding window weighted summation of my actual movements. In a sense, it essentially replaces manual aliases with pattern matching against the dynamically changing directory stack based on what I’m currently focused on.


I meant when I do:

    cd ...
    sd ...
    sd ...
    cd -
Does it undo the last sd or the last cd?

When I do a pushd, does sd change the odds, to the time I was in that directory? Does sd have a replacement for pushd?


To answer your specific questions on shell integration:

cd - behavior: It undoes the last directory change irrespective of whether you did it with builtin cd or via sd. If you do "sd project-a" and then "cd -", you go back to where you were before. The sd function is a "thin" wrapper that ultimately executes "command cd <pathname>", so it respects the shell's native $OLDPWD logic perfectly.

pushd and "odds": In its current implementation, sd only records a visit when you specifically use the sd command (or its cd alias) to move. If you use pushd or popd directly, sd isn't invoked and doesn't "see" that movement. This keeps manual stack operations entirely separate from the automated ranking. To be clear: the shell managed pushd/popd stack is distinct from the dynamic score-sorted directory stack maintained/utilized by sd. Personally I simply do not have any more use for the former so would argue that sd not seeing cd actions initiated by push/popd is not an issue for the tool.

pushd replacement: sd doesn't replace pushd/popd/dirs. Think of pushd as a manual bookmarking system and sd as a temporal index. They coexist: pushd is for explicit, manual stack management (presuming you still want/need it in addition to sd), while sd is for "get me to this project's source" jumps using shorthand.

The design goal is to be a "well-behaved citizen" of the shell. It doesn't break standard invariants; it just adds a shorthand layer that requires zero manual maintenance.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: