sd -- a drop-in replacement for `cd'

Check-in [a7c6e1b635]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:minor adjustments to quickstart.md.
Timelines: family | ancestors | descendants | both | ksh
Files: files | file ages | folders
SHA1: a7c6e1b635ee05d29e5525a71d377f4acc4a6908
User & Date: vdh 2019-12-13 14:09:16
Context
2019-12-22 16:42
replace piping of `print' output into commands by `<<<' here strings whereever possible. some other minor edits. check-in: 78020ab235 user: vdh tags: ksh
2019-12-13 14:09
minor adjustments to quickstart.md. check-in: a7c6e1b635 user: vdh tags: ksh
2019-12-13 14:08
minor adjustments to quickstart.md. check-in: bd18da5f0b user: vdh tags: trunk
2019-12-12 16:18
de-novo generation of `man.md' from sd's manpage using the newly added script `mkman.sh'. check-in: 129a43945a user: vdh tags: ksh
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to www/quick.md.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

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 frequencies 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 the most frequently visited one
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







|














|

|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

### The directory stack ###

The directory stack used by **sd** for lookup of directories is changing
dynamically and is generated/updated as follows:

0. 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 frequency distribution of all
unique names. 

0. The resulting list constitutes the directory stack which is queried top-down
in order of decreasing frequency when looking for an entry matching the
pattern specified for a **cd** action.

0. After each successful **cd** action, the name of the new working directory

is appended to 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, especially, its order is sensitively
controlled by the chosen value of `$sdlines`. This 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 running
shell instance modifies the logfile (and it's own incarnation of the stack).
In order to "synchronize" the stack across different shells (usually in different

terminals) 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 `3/4*$sdmax = 6144`
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 `3/4*$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







|
|



|


|
>
|
|
|
|

|
|
|
|
|












|
|

>
|
|



|
|
|
|
|
|
|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

### The directory stack ###

The directory stack used by **sd** for lookup of directories is changing
dynamically and is generated/updated as follows:

0. 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. 

0. 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.

0. 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](man.md)), 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