Blame


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