[HOWTO] Faire un widget ZLE qui modifie l'argument sous le curseur
Faire un widget ZLE qui modifie l'argument sous le curseur ========================================================== Cet exemple remplace l'argument sous le curseur (ou le précédent si le curseur est entre 2 arguments) (appelons-le "argument courant") par son chemin parent (son "dirname"). Première méthode (plus simple) ------------------------------ ................... dirname-previous-word () { autoload -U modify-current-argument modify-current-argument '${ARG:h}' } zle -N dirname-previous-word bindkey '^[q' dirname-previous-word ................... Nous définissons ici la fonction "dirname-previous-word" qui sera le widget, puis nous le déclarons comme widget ZLE avec "zle -N dirname-previous-word". Enfin, nous assignons ce widget au raccourci Alt-q. Dans le code du widget, nous utilisons la fonction "modify-current-argument" qui est très pratique, car le remplacement qu'elle fait est pénible autrement. La fonction "modify-current-argument" prend en paramètre une expression qui va être évaluée (passée dans un "eval") (il faudra donc certainement l'échapper), et remplace l'argument courant par le résultat de cette évaluation. L'expression peut utiliser l'ancienne valeur de l'argument courant, qui se trouve dans la variable "$ARG". Cependant, il faut échapper la référence à $ARG car cette variable n'est pas définie dans notre fonction mais dans la fonction "modify-current-argument" (là où elle sera évaluée). Dans ce cas précis, nous remplaçons l'argument courant ($ARG) par son chemin parent (${ARG:h}). Méthode un peu plus générique ----------------------------- Si nous voulons plus de liberté pour modifier l'argument courant, c'est à dire que la nouvelle valeur de l'argument ne peut pas "rentrer" dans une simple expression, nous pouvons procéder en 3 étapes : récupérer l'argument courant (grâce à un simple appel d'une autre fonction qui va nous faciliter la tâche), calculer la nouvelle valeur (on peut mettre le code qu'on veut), puis faire le remplacement (toujours avec la fonction modify-current-argument). ................... dirname-previous-word () { autoload -U split-shell-arguments autoload -U modify-current-argument local res split-shell-arguments ## pour se positionner sur l'argument précédent si on est entre 2 arguments ## CopierColler de /usr/share/zsh/functions/Zle/modify-current-argument (licence BSD) # Get the index of the word we want. if (( REPLY & 1 )); then # Odd position; need previous word. (( REPLY-- )) # Pretend position was just after the end of it. (( REPLY2 = ${#reply[REPLY]} + 1 )) fi ## Fin du CopierColler res=${reply[$REPLY]} res=${res:h} modify-current-argument '$res' } zle -N dirname-previous-word bindkey '^[q' dirname-previous-word ................... La fonction "split-shell-arguments" ne prend aucun paramètre. Par contre, elle écrit les variables reply, REPLY et REPLY2. La valeur de l'argument courant est accessible dans "${reply[$REPLY]}", nous pouvons faire tous les traitements que l'on veut dessus, aussi compliqués soient-ils (appels de commandes, boucles, etc.). Enfin, nous appelons "modify-current-argument" en passant en paramètre une référence à la variable qui contient le nouvel argument à remplacer. **Attention**, le passage par une variable, de plus échappée, est très important : si la nouvelle valeur de l'argument contenait ne serait-ce qu'un '$', ou même un guillemet, et que vous n'aviez pas procédé comme décrit (mis dans une variable et échappé), vous iriez au devant de sérieux ennuis.
participants (1)
-
emotn