Dans zsh (ainsi que bash), vous pouvez utiliser des extensions de mots d'historique pour désigner les arguments des commandes précédentes.
Cet exemple montre comment obtenir le 2e paramètre de la commande précédente dans l'historique avec !:#
expansion:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
J'oublie souvent exactement le paramètre # d'un argument particulier et la frappe !:#
n'est pas toujours aussi rapide quand je me souviens de quel argument il s'agit. Je suis sur le point meta-.
de remplacer le dernier argument, mais parfois ce n'est pas le dernier argument que je veux.
Je voudrais ajouter les arguments de la commande précédente comme suggestions pour terminer toute commande que je tape dans zsh.
J'ai pu comprendre comment créer une fonction shell qui peut créer un tableau d'arguments (0..N) à partir de la dernière commande et le lier à une commande particulière.
_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
}
# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo
Voici à quoi cela ressemble pour terminer juste foo où j'ai appuyé sur la touche de tabulation à <TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
Cela fonctionne très bien pour terminer la commande "foo", mais j'aimerais que ce soient des options sur n'importe quelle extension zsh que je fais. Je pense que cela a quelque chose à voir avec le completer zstyle, mais après quelques heures de piratage, j'ai réalisé que j'étais hors de ma profondeur.
Comment puis-je obtenir les arguments de ma commande précédente en tant que compléments suggérés pour toute commande dans zsh?
J'ai mon fichier compinstall zshrc complet partagé sur bitbucket si cela aide. Beaucoup d'entre eux proviennent de diverses sources et j'ai en partie piraté moi-même.
MISE À JOUR:
@La réponse de Julien Nicoulaud m'a rapproché, je la marque comme acceptée car elle m'a conduit là où je devais aller.
Avec ma configuration particulière, en utilisant le suggéré:
zstyle ':completion:*' completer _last_command_args _complete
Cela ne fonctionnait pas tout à fait pour moi car cela provoquait la complétion de l'onglet pour afficher uniquement la liste des arguments de la dernière commande (bien qu'elle se termine également avec les noms de fichiers, mais pas pour les afficher). Changer l'ordre a _complete _last_command_args
fait l'inverse. Il afficherait les noms de fichiers normaux, mais pas last_command_args
Je suppose que cela a quelque chose à voir avec le fonctionnement du completer. Je pense qu'il n'affiche que la sortie de la première méthode qui revient avec succès, mais j'ai du mal à analyser la source zsh pour comprendre pleinement ce qui se passe. J'ai pu modifier ma méthode pour inclure un appel à _complete
afin qu'il affiche à la fois les dernières commandes d'argument ainsi que les éléments de saisie semi-automatique standard. Pas tout à fait aussi séparé, mais fonctionne assez bien pour moi.
Voici la fonction complète que j'ai utilisée avec les autres trucs zstyle que j'ai:
# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
_complete
}
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1 # Because we didn't really complete anything
}
zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate
D'autres lignes zstyle que j'ai, pas nécessaires pour que cela fonctionne, mais pourraient affecter pourquoi cela fonctionne pour moi:
zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
Maintenant, si je suis dans un répertoire avec file1.txt
et file2.txt
, et ma dernière commande était echo foo bar baz
, j'obtiens ceci pour la saisie semi-automatique qui est exactement ce que je voulais:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
( insert-last-word
), j'aime bien copy-earlier-word
, qui passe d'un mot à l'autre de la ligne atteinte par insert-last-word
. Pour votre .zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word