Aller rapidement dans un dossier

Dans cet article je vous présente une série de scripts que j'utilise au quotidien pour rapidement aller dans n'importe quel dossier situé dans mon dossier utilisateur ($HOME ou ~). Par exemple pour aller dans le dossier ~/Quand/Te/Reverrai/Je/Pays/Merveilleux/Où/Ceux/Qui/S/Aiment/Vivent/A/Deux je n'ai qu'à activer un raccourci clavier et, via dmenu, taper qua deux.

Vidéo illustrant l'utilisation de ces scripts
Exemple d'utilisation de ces scripts

Ces scripts fonctionnent sur Linux et peuvent facilement être adaptés pour des systèmes BSD ou MacOS au besoin.

Ces scripts ne sont pas dans mon dépôt de scripts car ils ne sont pas assez indépendants. Chaque script pris seul n'est pas utile et c'est à vous de adapter leurs liaisons selon vos besoins.

Pourquoi ne pas utiliser locate?

En étudiant ma solution vous vous direz sans doute que la commande locate pourrait être une meilleure alternative.

La commande locate est utilisée pour trouver des fichiers système et non des dossiers présents dans le dossier utilisateur. À moins de passer du temps à faire de la configuration, l'utilisation de locate ne permet pas de faire ce que nous voulons faire ici.

Afficher les dossiers

Mon script display-home-directories affiche tous les dossiers et sous-dossiers visibles présents dans le dossier utilisateur. Je veux aussi exclure des dossiers, pour cela je mets dans un fichier de configuration les expressions rationnelles correspondants aux chemins de dossiers à exclure.

display-home-directories
#!/bin/sh

# Affiche tous les dossiers visibles du dossier utilisateur qui devraient être
# listés. Enlève le préfixe $HOME des chemins.

# Le fichier de configuration contient les expressions rationnelles pour les
# chemins qui ne doivent pas être listés, une par ligne. Toutes les lignes
# commençant par un # sont ignorées.

# Exemple de configuration:
#
# # Exclut les dossiers "obj", "bin" et "node_modules" et leurs sous-dossiers.
# /(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" |  # Enlève le dossier utilisateur
    sed "s+^$HOME/++" |  # Enlève le préfixe "$HOME/" de chaque chemin
    sort)

if [ -f "$CONFIG_FILE" ]; then
    while IFS="" read -r regex; do
        # Passe les lignes vides et les commentaires (lignes commençant par #)
        if [ -z "$regex" ] || [ -z "${regex%%#*}" ]; then
            continue
        fi
        paths=$(echo "$paths" | grep --invert-match --extended-regexp "$regex")
    done < "$CONFIG_FILE"
fi

echo "$paths"

Dans mon fichier de configuration, situé à ~/.config/display-home-directories, j'exclus les dossiers générés automatiquement comme par exemple les dossiers node_modules, les dossiers bin et les dossiers obj. Ces expressions rationnelles sont données en exemple dans les commentaires du script. Je commence les expressions par un / pour que des dossiers se terminant par exemple par bin (Images/Rabbin ou Images/Ebin) ne soient pas exclus.

Dans certains dossiers, j'aime avoir la liste des dossiers du premier niveau mais pas ceux plus en profondeur. Exemple pour le dossier ~/Foo, j'ai dans mon fichier de configuration cette expression rationnelle.

^Foo/[^/]+/

Le dossier ~/Foo/Bar est affiché mais pas le dossier ~/Foo/Bar/Quux.

Mettre en cache

Plus il y a de dossiers, plus le script prendra du temps à s'exécuter. Le mieux est de créer une tâche cron pour mettre en cache les résultats. Pour cela, faire crontab -e dans un environnement shell pour éditer les tâches cron, ne pas oublier de mettre le chemin complet du script pour éviter des problèmes si jamais il n'est pas dans un des chemins de la variable PATH utilisée par cron.

*/10 * * * * $HOME/bin/display-home-directories > $HOME/.cache/display-home-directories

Ne pas oublier de créer le fichier cache avant de l'utiliser comme nous allons le faire tout de suite!

Aller dans un dossier

J'utilise dmenu pour sélectionner le dossier dans lequel je veux aller. dmenu est un petit utilitaire qui affiche un menu donné en entrée avec une barre de recherche qui permet de filtrer les résultats. J'utilise ce script nommé go-to-directory pour gérer la sélection du dossier et le saut vers ce dossier.

go-to-directory
#!/bin/sh

# cd dans le dossier choisi.
# Si une commande est donnée comme argument, utilise cette commande.

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

Dans le script, j'active l'option -i de dmenu pour faire des recherches sans me préoccuper de la casse.

J'utilise caja comme gestionnaire de fichiers. Dans mon sxhkdrc j'ai donc ces lignes pour ouvrir caja dans un dossier choisi:

sxhkdrc
super + j
    $HOME/bin/go-to-directory caja

Pour cd quand j'utilise une session shell, j'ai cet alias:

alias c='source go-to-directory'

Inconvénients

Utiliser dmenu a deux gros inconvénients.

Pour supprimer la nécessité d'avoir X, je pensais utiliser choice mais il a trop d'inconvénients (du peu que j'ai testé).

Quoiqu'il en soit les petits inconvénients listés ne sont rien comparés aux avantages qu'offre la solution décrite dans cet article. À force d'utiliser mes scripts, je me demande pourquoi il n'y a pas des alternatives à mes scripts par défaut dans d'autres systèmes!