Blame


1 5e8f809e 2020-06-27 op If you use the shell a lot, you may find this advice useful, in case
2 5e8f809e 2020-06-27 op you didn't already knew it. There's an environment variable called
3 5e8f809e 2020-06-27 op CDPATH, used by most shell I know and others cli tools, whose *raison
4 5e8f809e 2020-06-27 op d'être* is to simplify `cd`-ing around.
5 5e8f809e 2020-06-27 op
6 5e8f809e 2020-06-27 op As various environmental variables in UNIX, its value is a list of
7 5e8f809e 2020-06-27 op directories separated by colons, just like PATH. For instance, this
8 5e8f809e 2020-06-27 op is what I currently have in my `~/.kshrc`:
9 5e8f809e 2020-06-27 op
10 5e8f809e 2020-06-27 op ```sh
11 5e8f809e 2020-06-27 op export CDPATH=.:$HOME/w:/usr/ports
12 5e8f809e 2020-06-27 op ```
13 5e8f809e 2020-06-27 op
14 5e8f809e 2020-06-27 op With that in place, no matter where my current working directory is, I
15 5e8f809e 2020-06-27 op can `cd games/godot` to jump to `/usr/ports/games/godot`!
16 5e8f809e 2020-06-27 op
17 5e8f809e 2020-06-27 op A note of warning: `.` (the dot aka your current working directory)
18 5e8f809e 2020-06-27 op should be present in your `$CDPATH`, otherwise you won't be able to
19 5e8f809e 2020-06-27 op `cd` into directories not found in your `$CDPATH` (you can use `cd
20 5e8f809e 2020-06-27 op ./$somedir`, but isn't probably what you want).
21 5e8f809e 2020-06-27 op
22 5e8f809e 2020-06-27 op ## Programs that I know respect `$CDPATH`
23 5e8f809e 2020-06-27 op
24 5e8f809e 2020-06-27 op Since the entry would be too short otherwise, here's some programs
25 5e8f809e 2020-06-27 op that I know respect `$CDPATH`, and how they behave.
26 5e8f809e 2020-06-27 op
27 5e8f809e 2020-06-27 op ### ksh (OpenBSD pdksh)
28 5e8f809e 2020-06-27 op
29 5e8f809e 2020-06-27 op Just as I showed you up there. When you `cd` into a directory inside
30 5e8f809e 2020-06-27 op your `$CDPATH` it will print your new current working directory:
31 5e8f809e 2020-06-27 op
32 a3ab6f61 2020-09-22 op ```sh
33 a3ab6f61 2020-09-22 op $ cd games/godot
34 a3ab6f61 2020-09-22 op /usr/ports/games/godot
35 a3ab6f61 2020-09-22 op ```
36 5e8f809e 2020-06-27 op
37 5e8f809e 2020-06-27 op It will not, however, autocomplete.
38 5e8f809e 2020-06-27 op
39 5e8f809e 2020-06-27 op ### bash
40 5e8f809e 2020-06-27 op
41 50ba6f2f 2020-06-27 op It will behave just like ksh.
42 5e8f809e 2020-06-27 op
43 5e8f809e 2020-06-27 op ### zsh
44 5e8f809e 2020-06-27 op
45 5e8f809e 2020-06-27 op `zsh` respects `$CDPATH`. It does not seem to do completions tho :(
46 5e8f809e 2020-06-27 op
47 5e8f809e 2020-06-27 op ### rc
48 5e8f809e 2020-06-27 op
49 5e8f809e 2020-06-27 op 9ports rc does not seem to inherit `$CDPATH`, but you can set it
50 5e8f809e 2020-06-27 op (unsurprisingly) with
51 5e8f809e 2020-06-27 op
52 a3ab6f61 2020-09-22 op ```rc
53 a3ab6f61 2020-09-22 op cdpath=(. /usr/ports)
54 a3ab6f61 2020-09-22 op ```
55 5e8f809e 2020-06-27 op
56 5e8f809e 2020-06-27 op in your `~/lib/profile`. Other versions of `rc` (I'm talking about the
57 5e8f809e 2020-06-27 op one you get with the `rc` package on FreeBSD) do inherit it, so double
58 5e8f809e 2020-06-27 op check!
59 5e8f809e 2020-06-27 op
60 5e8f809e 2020-06-27 op Additionally, `rc` prints the `pwd` only if you're `cd`-ing into
61 5e8f809e 2020-06-27 op something that's not within `.` (the current directory). So:
62 5e8f809e 2020-06-27 op
63 a3ab6f61 2020-09-22 op ```rc
64 a3ab6f61 2020-09-22 op % pwd
65 a3ab6f61 2020-09-22 op /home/op
66 a3ab6f61 2020-09-22 op % echo $cdpath
67 a3ab6f61 2020-09-22 op . /usr/ports
68 a3ab6f61 2020-09-22 op % cd bin # won't print /home/op/bin
69 a3ab6f61 2020-09-22 op % cd games
70 a3ab6f61 2020-09-22 op /usr/ports/games
71 a3ab6f61 2020-09-22 op %
72 a3ab6f61 2020-09-22 op ```
73 5e8f809e 2020-06-27 op
74 5e8f809e 2020-06-27 op ### csh & tcsh
75 5e8f809e 2020-06-27 op
76 a3ab6f61 2020-09-22 op ```csh
77 a3ab6f61 2020-09-22 op set cdpath = (. /usr/ports)
78 a3ab6f61 2020-09-22 op ```
79 5e8f809e 2020-06-27 op
80 5e8f809e 2020-06-27 op for the rest, behaves exactly like `rc`. I don't really use csh, nor
81 5e8f809e 2020-06-27 op tcsh, so I can't make further comments.
82 5e8f809e 2020-06-27 op
83 5e8f809e 2020-06-27 op ### fish
84 5e8f809e 2020-06-27 op
85 5e8f809e 2020-06-27 op I've installed fish just for this post. It does respect `$CDPATH`
86 5e8f809e 2020-06-27 op and, unlike other shells, is also able to do proper autocompletion
87 5e8f809e 2020-06-27 op out-of-the-box.
88 5e8f809e 2020-06-27 op
89 5e8f809e 2020-06-27 op ### vi (nvi)
90 5e8f809e 2020-06-27 op
91 50ba6f2f 2020-06-27 op `vi` will inherit your `$CDPATH` (but make sure you're `export`ing
92 50ba6f2f 2020-06-27 op it!). You can also `:set cdpath=…` if you wish. You cannot edit a
93 50ba6f2f 2020-06-27 op file like `:e games/godot/Makefile` and assume vi will open
94 5e8f809e 2020-06-27 op `/usr/ports/games/godot/Makefile` though, you need first to `:cd
95 5e8f809e 2020-06-27 op games/godot` and then `:e Makefile`!
96 5e8f809e 2020-06-27 op
97 5e8f809e 2020-06-27 op ### bonus: emacs
98 5e8f809e 2020-06-27 op
99 5e8f809e 2020-06-27 op Emacs vanilla `M-x cd` respects your `$CDPATH`, you just have to
100 5e8f809e 2020-06-27 op delete the default text in the minibuffer. It also does proper
101 5e8f809e 2020-06-27 op autocompletion! Additionally, `eshell` respects `$CDPATH` too! Not
102 5e8f809e 2020-06-27 op all emacs packages will, unfortunately. For instance, `ivy` doesn't
103 5e8f809e 2020-06-27 op seem to care about it.
104 5e8f809e 2020-06-27 op
105 5e8f809e 2020-06-27 op On the other hand, with emacs you have other ways to quickly jump
106 5e8f809e 2020-06-27 op around. Other than bookmarks (that I don't use), you have packages
107 5e8f809e 2020-06-27 op like `projectile` that lets you jump between "projects" easily.