don’t let cd slow you down, cd wrappers: wcd, commacd
05 Apr 2011
Using a console interface to manage a computer has its disadvantages, some of them are specially visible when dealing with multiple files at the same time (moving/renaming/copying), typing long and crypted commands/options or moving around. On this entry I’ll talk about the last one.
The default cd
behaviour on bash to change directories is quite strict, it requires to write full/relative paths and doesn’t recognize fuzzy search or any more complicated way of finding directories, some people use many aliases to workaround these issues, others change its default shell or use third party tools, eg: fasd, bd, fzf, etc to create a semi automatic way of moving faster.
I prefer everything as minimalist and automatic as possible, so after reviewing lots of custom scripts, alternative shells and third party hacks, I think I’ve something good enough to write about and use on a daily basis.
All start by enabling semi hidden bash options for autocorrecting and autocompleting directories:
$ head ~/.bashrc # http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html if [ "${BASH_VERSINFO}" -ge "4" ]; then shopt -s autocd cdspell dirspell fi
Now, bash can autocomplete 1/2/3/foo in the following scenarios:
$ cd 1/2/3/foo $ cd 1/2/3/ofo $ 1/2/3/foo
Moving between important directories and parent directories can be optimized by adding some aliases:
$ head ~/.alias.common alias ..="cd .." alias ....="cd ../.." alias important.path="cd important/path"
Now it’s time for some major improvements. An important zsh cd related feature is called pattern recognition, e.g. $ cd s/m/pl will become super/master/plan, that’s sweet, unfortunately bash is unable to recognize such patterns by itself, however with some help it can do it even better.
$ sudo apt-get install wcd $ head ~/.alias.common alias cd='. wcd'
wcd is not a binary, it’s a wrapper script around wcd.exec
(available on the wcd
package):
Once installed and configured, $ cd s/m/pl will take us to super/master/plan no matter what the current is, wcd works by creating an index file with all available directories and looking at it to find the best approximation.
WARNING: Wcd will require to regenerate the index db every now and then, a cronjob with the following content can help:
0 23 * * * /usr/local/bin/update-cd
$ cat /usr/local/bin/update-cd #!/bin/sh #description: update wcd db if available #usage: update-cd if [ -f "$(command -v "wcd")" ] && [ -f "$(command -v "wcd.exec")" ]; then mkdir "${HOME}"/.wcd; wcd.exec -GN -j -xf "${HOME}"/.ban.wcd -S "${HOME}" [ -f "${HOME}"/.treedata.wcd ] && mv "${HOME}"/.treedata.wcd "${HOME}"/.wcd/ fi
Been able to move to any directory from anywhere is really helpful, however sometimes it’s desirable to move around parents and nearby directories efficiently, that’s where commacd get in. With commacd
several aliases (,
, ,,
and ,,,
) are defined which can be used on the following scenarios:
$ , /u/l/b #moving through multiple directories
=> cd /usr/local/bin
$ , d #moving through multiple directories with the same name
=> 1 Desktop
2 Downloads
: <type index of the directory to cd into>
~/code/projects/zion/src/module $ ,, #going up till a project directory is found (git/hg/svn based)
=> cd ~/code/projects/zion
~/code/projects/zion/src/module $ ,, pro #going into the first parent directory named pro*
=> cd ~/code/projects
~/code/projects/zion/src/module $ ,, zion matrix #subtituing the current path and going into the result
=> cd ~/code/projects/matrix/src/module
~/code/projects/zion/src/module $ ,,, matrix/tests #going into a sibling directory who has the same parent directory
=> cd ~/code/projects/matrix/tests/
As wcd, commacd
is a script who can be downloaded from:
Or to get my personal version:
Upon getting any of them, the script should be used as an alias (due to the nature of the cd
built-in), eg, ~/bashrc:
if [ -f "$(command -v "commacd")" ]; then . commacd alias ,=_commacd_forward alias ,,=_commacd_backward alias ,,,=_commacd_backward_forward fi
That’s it, now moving around should feel less archaic, happy cli browsing 😄