Quickly go to a directory
In this article I show you a set of scripts I use daily to quickly go to any directory inside my home directory ($HOME
ou ~
). For example to go to the directory ~/Quand/Te/Reverrai/Je/Pays/Merveilleux/Où/Ceux/Qui/S/Aiment/Vivent/A/Deux
, I just have to activate a shortcut and, using dmenu, type qua deux
.

These scripts work on Linux and can easily be translated into BSD or MacOS systems if needed.
These scripts are not in my scripts repository because there are not independent enough. Each script is not useful by itself and you need to adapt how they link yourself.
Why not use locate
?
By studying my solution you may think that the command locate
is a better alternative.
The command locate
is used to find system directories and not directories which are inside the home directory. Without spending a lot of time of configuration, using locate
cannot achieve what we are trying to do here.
Displaying the directories
My script display-home-directories
displays all the visible directories and subdirectories present in the home directory. I also want to exclude some directories, for that I put in a configuration file regular expressions corresponding to the paths to exclude.
#!/bin/sh
# Displays all the visible directories in the home directory that should be
# listed. Remove the $HOME prefix in the paths.
# The configuration file contains regular expressions for the paths that should
# not be listed, one by line. Lines starting with a # are ignored.
# Configuration example:
#
# # Exclude "obj", "bin" and "node_modules" directories and their
# # sub-directories.
# /(obj|bin|node_modules)$
# /(obj|bin|node_modules)/
CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/display-home-directories"
paths=$(find $HOME -type d -not -path '*/\.*' -print |
sed "1d" | # Remove the home directory
sed "s+^$HOME/++" | # Remove the $HOME prefix in each path
sort)
if [ -f "$CONFIG_FILE" ]; then
while IFS="" read -r regex; do
# Skip empty lines and comments (lines starting by #)
if [ -z "$regex" ] || [ -z "${regex%%#*}" ]; then
continue
fi
paths=$(echo "$paths" | grep --invert-match --extended-regexp "$regex")
done < "$CONFIG_FILE"
fi
echo "$paths"
In my configuration file, at ~/.config/display-home-directories
, I exclude automatically generated directories like node_modules
, bin
and obj
directories. The regular expressions are in the example in the script comments. I start the regular expressions by a /
so directories ending, for example, by a bin
(Images/Rabbin
or Images/Ebin
) are not excluded.
For some directories, I like to list the first level subdirectories but not their subdirectories. For example for the ~/Foo
directory, I put in my configuration file this regular expression.
^Foo/[^/]+/
The ~/Foo/Bar
directory is displayed by not the ~/Foo/Bar/Quux
directory.
Caching
The script execution time increase with the number of directories present. The best thing to do is to create a cron task to cache the results. To do that, do crontab -e
in a shell environment to edit the cron tasks, do not forget to put the full path of the script in order to avoid problems if it is not in the path listed in the PATH
variable used by cron.
*/10 * * * * $HOME/bin/display-home-directories > $HOME/.cache/display-home-directories
Do not forget to create the cache file before using it as we will do right now!
Going to a directory
I use dmenu to select the directory I want to go to. dmenu is a small software displaying a given menu with a search bar used to filter the results. My script go-to-directory
manages the directory selection and goes to this directory.
#!/bin/sh
# cd into the chosen directory.
# If a command is given as an argument, use this command.
CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/display-home-directories"
choice=$(cat $CACHE_FILE | dmenu -l 20 -i)
if [ -n "$choice" ]; then
if [ "$#" -eq 0 ]; then
cd "$HOME/$choice"
else
"$1" "$HOME/$choice"
fi
fi
In this script, I activate the -i
option of dmenu so searches are case-insensitive.
I use sxhkd as keyboard shortcuts manager and caja as file manager. In my sxhkdrc
I have these line to open caja in a chosen directory:
super + j
$HOME/bin/go-to-directory caja
To cd
when I use a shell session, I have this alias:
alias c='source go-to-directory'
Drawbacks
Using dmenu has two big drawbacks.
- It is necessary to have a graphical interface like X.
- It is not possible to use an input method framework like fctix to search. If in my
Music
directory I have aポルノグラフィティ
(Porno Graffitti) directory, I cannot directly search for it but I must search formusic
then scroll line by line to find this directory.
To remove the need of having X, I thought about using choice but there are too much drawbacks (from the short period of time I tested it).
- It does not give the possibility to put accentuated characters like
é
. - It does not give the possibility to ignore case.
- It searches exactly what is given. If I search for
Mus Sup Lo
, it will not give me backMusic/The Supermen Lovers
as a result.
Even if there are some minor listed drawbacks, this is nothing compared to the convenience given by the solution described in this article. Now that I am used of using my scripts, I wonder why there are no alternatives to my scripts set by default in other systems!