URL: https://linuxfr.org/users/perdu/journaux/faire-de-la-magie-avec-son-inputrc Title: Faire de la magie avec son .inputrc Authors: Perdu Date: 2015年03月24日T11:37:23+01:00 License: CC By-SA Tags: inputrc, bash, readline, ligne et commande Score: 81 Bonjour nal et naleux, Faites-vous partie de ces barbus définissant des dizaines et des dizaines d'alias dans leur .bashrc, afin d'_enlarge your productivity_ au maximum ? Mais savez-vous qu'il existe un fichier encore pluss trop bien, permettant de faire virevolter votre productivité à un niveau inégalé : le .inputrc ? Celui-ci permet de définir des raccourcis claviers qui seront disponibles dans tous les clients utilisant [readline](http://fr.wikipedia.org/wiki/GNU_Readline) (donc bash, mais pas zsh... Raison principale pour laquelle je ne suis toujours pas passé à zsh !) En premier lieu, les utilisateurs de vi seront heureux de savoir que readline contient un mode vi qui permet d'utiliser des commandes à la vi. Pour l'activer, ajouter ceci au fichier : ```bash set editing-mode vi set keymap vi-command ``` Pour la liste des raccourcis, cf. [ici](http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-sheet/) Vous pouvez aussi régler vos raccourcis clavier qui ne seraient pas reconnus par bash, notamment les flèches, qui peuvent avoir plusieurs variantes : « [1;5C », « [5C » ou encore « \e[C ». Pour savoir ce que les différentes combinaisons de touche renvoient, lancez par exemple un « sleep 10 » puis voyez quels représentations sont affichées. Pour les utiliser dans votre .inputrc, remplacez « \^[ » par « \e ». Ainsi, si par exemple les déplacement en CTRL-flèches posent problème, ajoutez ceci : ```bash # mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving "\e[1;5C": forward-word "\e[1;5D": backward-word "\e[5C": forward-word "\e[5D": backward-word "\e\e[C": forward-word "\e\e[D": backward-word ``` Un autre truc pratique : pour chercher directement dans votre historique les commandes commençant par la commande en cours avec CTRL+flèche haut ou bas, ajoutez : ```bash "\e[1;5A": history-search-backward "\e[1;5B": history-search-forward ``` Bref, passons les astuces triviales que vous trouverez un peu partout sur Internet ou en lisant le _man bash_, et voyons voir ce qu'on peut définir d'un peu plus intéressant. En premier lieu, il est intéressant de noter qu'on peut définir à peu près n'importe quelle séquence de touche sur un raccourci clavier. Ainsi, si je définis ceci : ```bash "\ej": "jobs\n" ``` taper M-j m'affichera automatiquement les processus en arrière-plan. Notez bien le retour chariot, qui m'évite d'appuyer sur entrée. On ne dirait pas comme ça, mais ce raccourci est indispensable : l'essayer, c'est l'adopter ! On peut affiner encore un peu l'utilité du raccourci en le rendant fonctionnel également en cours d'écriture de commande : ```bash "\ej": "\C-a\C-kjobs\n" ``` Cela rajoute une séquence de touches (C-a C-k) qui coupe toute la ligne. Vous pouvez rajouter un C-y à la fin pour recoller la ligne, mais notez que ça collera de vieilles données si vous faites cela sur une ligne vide. Attention, notez que définir un raccourci n'efface pas forcément le précédent, ce qui donne parfois des résultats bizarres (les deux commandes peuvent être exécutées). Vérifiez donc que le raccourci n'est pas déjà attribué, par exemple sur [la page wikipédia anglais de bash](http://en.wikipedia.org/wiki/Bash_%28Unix_shell%29#Keyboard_shortcuts) (oui, tout l'alphabet est déjà utilisé avec CTRL). Avant d'aller encore plus loin, voilà en vrac d'autres raccourcis très utiles : ```bash # Ajouter "| less" à la fin de la ligne "\el": "\C-e | less" # Remplacer le premier mot de la commande par less "\eL": "\C-a\eDless\C-e" # Remplacer le premier mot de la commande par ls "\eK": "\C-a\eDls\C-e" # Ajouter "sudo" au début de la ligne "\es": "\C-asudo \C-e" # Afficher un processus précis (place le curseur entre les quotes) # Attention : écrase M-p "\ep": '\C-a\C-kps aux | grep -i ""\C-b' # grep "\eG": '\C-a\C-kgrep -ri "" .\C-b\C-b\C-b' "\eg": '\C-a\C-kgrep -r "" .\C-b\C-b\C-b' # find (avec copie du résultat dans le clipboard, nécessite le paquet xclip) "\eF": '\C-a\C-kfind . -iname "**" | tee>(tr -d \'\\n\' | xclip)\C-a\ef\ef\C-f\C-f\C-f' # Ouvrir le man correspondant à la commande en cours # (remplace "commande args" par "man commande") "\em": '\C-aman \ef\C-k' # Copier une seconde fois le premier argument de la commande # (Ne fonctionne que pour des commandes simples) # Pratique lorsqu'on écrit "mv nom_de\ -\ fichier_\[\ complexe\] nom_de\ -\ fichier_\[\ complexe\].txt" "\er": '\C-a\ef\C-k\C-y\C-y' ``` Bon, voilà, on a défini plein de commandes utiles. Mais peut-on aller plus loin ? Eh bien, réjouis-toi cher journal, car c'est ce que nous allons faire ! Bash a une fonction assez exotique que, je parie, vous n'utilisez pas tous les jours : M-C-e. Celle-ci effectue une expansion de la ligne de commande en cours : alias, sous-commandes et historique. Par exemple, si ma commande est : ```bash $ ls $(cat fichier_a_regarder) ``` et que fichier_a_regarder contient « toto », alors la commande devient : ```bash $ ls toto ``` Vous vous demandez à quoi cela va nous servir ? Et bien, à exécuter des commandes pour nous aider à écrire notre ligne de commande, pardi ! Par exemple, si on fait : ```bash "\ea": ' \\\'$(ls | dmenu)\\\'\e\C-e' ``` Cela va nous ouvrir un dmenu listant les fichiers du dossier en cours. On choisit l'un d'eux, et ça colle son nom dans la commande en cours. Pratique quand on a un dossier rempli de fichiers aux noms tordus et similaires ! Terminons par mon raccourci favori : ```bash "\e:": '\\\'$(ls -t -1 -d * | head -n 1)\\\' \e\C-e' ``` Qu'est-ce que ça fait ? Eh bien, ça va chercher le fichier ou dossier le plus récent du dossier en cours et nous le colle dans la ligne de commande en cours. *Très* pratique quand on passe son temps à enregistrer des fichiers et à oublier leur nom 10 secondes plus tard. Notez tout de même que l'expansion remplace toutes les commandes de la ligne de commande : faites donc attention à ce que vous faites, pour ne pas exécuter de commande par erreur. Notez aussi que ça remplace les alias par leur valeur, ce qui peut être ennuyeux. Allez, en bonus, si on se déplaçait dans l'arborescence à coup de flèches, à la ranger ? Pour ce faire, plaçons ces lignes dans le .inputrc : ```bash "\e[1;3D": '\C-a\C-kcd_left\n' "\e[1;3C": '\C-a\C-kcd_right\n' "\e[1;3A": '\C-a\C-kcd_up\n' "\e[1;3B": '\C-a\C-kcd_down\n' ``` Puis définissons les alias associés dans le .bashrc : ```bash alias cd_left='cd .. && ls' alias cd_right='cd "$(first_folder)" 2>/dev/null && ls' alias cd_up='cd "$(prev_folder)" 2>/dev/null && ls' alias cd_down='cd "$(next_folder)" 2>/dev/null && ls' ``` Et les fonctions associées (que je ne détaille pas, je laisse les trolls critiquer la piètre qualité de mon code) : ```bash prev_folder() { prev_dirs=$(ls -1 --group-directories-first ..) IFS=$'\n' dirs=($(ls -1 --group-directories-first ..)) pos_dir=$(echo "$prev_dirs" | grep -n "^$(basename "$(pwd)")$" | perl -pe 's/^(\d+).*/1円/') pos_prev_dir=$(( $pos_dir - 2 )) prev_dir=../${dirs["$pos_prev_dir"]} if [ -d "$prev_dir" ] then echo "$prev_dir" else echo "/dev/null" fi } next_folder() { prev_dirs=$(ls -1 --group-directories-first ..) IFS=$'\n' dirs=($(ls -1 --group-directories-first ..)) pos_dir=$(echo "$prev_dirs" | grep -n "^$(basename "$(pwd)")$" | perl -pe 's/^(\d+).*/1円/') # array start at 0, but grep starts numerotating at 1 # Hence, there is no need to add 1 next_dir=../${dirs["$pos_dir"]} if [ -d "$next_dir" -a "$next_dir" != "../" ] then echo "../${dirs["$pos_dir"]}" else echo "/dev/null" fi } first_folder() { first_dir=$(ls -1 --group-directories-first . | grep -m 1 "") if [ -d "$first_dir" ] then # without ./, the folder will put printed because of CDPATH echo "./$first_dir" else echo "/dev/null" fi } ``` Et finalement, empêchons ces commandes de polluer notre historique : ```bash export HISTIGNORE="cd_*" ``` Et voilà, ça marche ! J'espère que ce journal vous donnera plein d'idées géniales que vous posterez en commentaire et qui iront compléter mon .inputrc !

AltStyle によって変換されたページ (->オリジナル) /