Preliminary Remarks
We presume you are using either ksh or a mostly ksh compatible shell (i.e. bash or zsh). sd can be used with tcsh, too, but there are some minor restrictions and somewhat reduced performance.
After successful installation (see Initial Setup),
the file sd.ksh
has to be sourced from within a running shell.
For routine use, the standard way to achieve this is to include the line
. sd.ksh
verbatim (including the leading ". ") in your resource file (e.g. .kshrc
or .bashrc
). sd.ksh
defines some shell functions whose names all start
with the string "sd". Relevant for interactive usage are only two of them,
namely
sd
sdirs (aliased to "dirs")
where sd is responsible for executing the desired cd command while
(s)dirs acts as interface to the other functions. Presuming there is no
shell function cd defined at the time sd.ksh
is sourced, such a function
is automatically defined as
function cd {
sd "$@"
}
so that sd can be used transparently instead of cd. Altogether, usually you only use the commands cd and dirs to interact with sd.
Usage
If a valid path to a directory is specified as argument to sd (or to the
cd
function as defined above) it acts just as the builtin cd command
(including the cases where the argument is omitted or equal to -
).
If the argument is not a valid path, it is interpreted as a regular expression pattern and matched against a stack of directory names of previously visited directories ordered by "frecencies" of visit. The first match found (if any) is then used for the cd action. By definition this is most probably correct (simply because that directory was recently visited most frequently of all the directories matching the pattern) but is obviously not always what you want. In this case the most direct strategy is to use a more specific pattern.
Full regular expressions can be used but usually they are not necessary. If they are used, take care to use adequate quoting. The most useful patterns are either just substrings of the desired directory name (e.g. its basename or a trailing part of the full path name). In order to enforce a match at the end of the stack entries use something like
cd basename$
Instead of making the pattern directly match the directory you are interested in, it's sometimes easier to issue
dirs pattern
where pattern
is a usually non-unique match for the respective directory.
This command will display a list of all "hits" of the specified pattern
together with a rank index. This rank in turn can then be used to go to the
desired directory:
cd =rank_index
With zsh
you have to escape the equality sign: cd \=rank_index
.
Issuing dirs
without an argument displays the complete content of the
currently available directory stack. Detailed usage information can be
obtained by issuing
dirs -m
Technicalities
The directory stack
The directory stack used by sd for lookup of directories is changing dynamically and is generated/updated as follows:
At startup the stack is initialized from the trailing
$sdlines
(default: 512) lines/directory names in the logfile of previously visited directories (default logfile:~/.sd/dirv
) by computing a "frecency" distribution of all unique names.The resulting list constitutes the directory stack which is queried top-down in order of decreasing "frecency" when looking for an entry matching the pattern specified for a cd action.
After each successful cd action, the name of the new working directory is appended to the list of the cd history loaded initially from the logfile and the stack is regenerated from the (now slightly changed)
$sdlines
trailing entries. Naturally, if a certain directory is visited sufficiently often, over time it will move up the directory stack.
Obviously, the stack content and order is influenced by the chosen
values of $sdpower
(see sdirs -e), and $sdlines
. The
latter value indirectly defines the effective time window inspected by
sd: by default the last 512 cd's are tracked which, at moderately
heavy use, does correspond to about 1-2 weeks of work.
Increasing the value of $sdlines
extents the effective time window and thus
includes more distinct directory names in the stack. However, the stack
ordering does no longer change as rapidly. Rather, for large values of
$sdlines
it approaches a nearly static sorting order. The bottom
line: there is to be made a choice between including a sufficiently large
number of directories in the stack and a stack that adjusts its sorting order
rapidly to a change of focus of the ongoing work (accompanied by frequent
visits to a different group of directories).
A further point to realize is the following: the directory stack is maintained
in a shell variable ($sdlist
). The stack is thus internal to the
respective shell process. Especially, it does not change if another
shell instance modifies it's own incarnation of the stack and/or the logfile.
In order to "synchronize" the stack across different shells (usually in different
terminals) logfile update an be enforced via dirs -w
and stack
regeneration can be enforced via dirs -f
(it might be easier to just
open another terminal, though).
The logfile
The logfile size is limited to $sdmax
entries/lines (default: 8192).
If this limit is reached, the file is pruned to the 9/10*$sdmax
trailing/most recent entries. Thus, the accessible history fluctuates
between these two figures. This approach ensures that pruning occurs
only vary rarely (every few months, probably) and that the minimum time
window is that of the last 9/10*$sdmax
cd actions (many months,
maybe over a year). dirs -i
reports the time of the last pruning.
Handling of non-matching patterns
Whether a
cd pattern
command fails, i.e. whether pattern
does not match any entry in the current directory
stack, partly depends on the chosen value of $sdlines
(which might be modified in
the corresponding resource file or increased interactively via "dirs -l num
").
As an attempt to improve handling of such initially failing cd actions, sd implements the following strategy (also covering the case of "stale" entries, i.e. entries pointing to a directory that has been deleted in the meantime):
If
cd pattern
fails, first try to find another matching entry further down on the stack.If this fails too, temporarily increase
$sdlines
to the total number of entries in the logfile (usually several 1000).Recreate the stack (which then contains all directories found in the logfile) and try again to find a matching entry (again, skipping over stale entries).
Reset
$sdlines
and recreate the stack.
In this way the chance of complete failure is distinctly reduced but it is of
course not guaranteed that the top-most "hit" on the extended stack is the
desired one. For this reason, a list of all hits on the extended stack
is displayed, too, in order to enable the user to refine the search pattern
if need be. To avoid this output define this shell variable:
sdsilent=1
.