2010-08-19 6 views
22

J'essaie d'écrire une petite application de lancement de commande, et j'aimerais utiliser les complétions de tabulation de bash dans mon propre système de complétion. J'ai été en mesure d'obtenir une liste de complétions pour les commandes générales en utilisant compgen -abck.
Cependant, je voudrais également obtenir des complétions pour des commandes spécifiques: par exemple, l'entrée git p devrait afficher l'achèvement pour les commandes de git.Accès aux commandes de bash pour des commandes spécifiques par programme

Est-ce que je peux utiliser compgen pour cela? Sinon, y a-t-il d'autres façons d'obtenir une liste de complétions par programme?

[EDIT: Pour clarifier, je n'essaie pas fournir achèvement à bash - mon application est un lanceur de commande GUI. Je voudrais simplement utiliser les compléments existants de bash dans ma propre application.]

Répondre

12

Je ne sais pas vraiment comment cela fonctionne, mais le awesome window manager utilise le code Lua suivant pour avoir accès au résultat de l'achèvement bash:

https://github.com/awesomeWM/awesome/blob/master/lib/awful/completion.lua#L119

  1. Via complete -p nous trouvons complete -o bashdefault -o default -o nospace -F _git git. Nous nous souvenons de "_git" pour plus tard.
  2. La longueur de "git l" est 5, nous avons donc défini COMP_COUNT = 6. Nous terminons le premier argument à "git", donc COMP_CWORD = 1.

Tous ensemble nous utilisons le script suivant:

__print_completions() { 
    printf '%s\n' "${COMPREPLY[@]}" 
} 

# load bash-completion functions 
source /etc/bash_completion 

# load git's completion function 
_completion_loader git 

COMP_WORDS=(git l) 
COMP_LINE='git l' 
COMP_POINT=6 
COMP_CWORD=1 
_git 
__print_completions 

Sortie: "log"

+0

Le code semble faire à peu près exactement ce que je veux faire avec mon application. Je vais devoir le porter sur Bash, mais c'est toujours très utile. Merci beaucoup! –

+0

J'ai fait quelques tests et c'est ce qui est exécuté pour terminer "git l":/usr/bin/env bash -c 'source/etc/bash_completion; __print_completions() {pour ((i = 0; i <$ {# COMPREPLY [*]}; i ++)); fais echo $ {COMPREPLY [i]}; terminé }; COMP_WORDS = (git l); COMP_LINE = "git l"; COMP_COUNT = 6; COMP_CWORD = 1; _git; __print_completions ' –

+0

"_git" est trouvé via "complete -p" qui affiche "complete -o bashdefault -o par défaut -o nospace -F _git git". Donc, si le premier mot est "git", appelez "_git". COMP_COUNT est la longueur de la chaîne jusqu'à présent plus un. COMP_CWORD est le mot à compléter (le premier est l'index 0). –

2

Vérifiez dans le répertoire /etc/bash_completion.d/. C'est là que les différents scripts d'achèvement de commande restent.

+0

J'ai eu un coup de coude autour dans/etc/bash_completion.d/', mais pas encore élaboré un moyen facile d'obtenir les complétions contenues à l'intérieur encore très facilement. (J'utilise Python pour accéder aux complétions, ce qui complique un peu les choses.) J'espérais qu'il y aurait un moyen plus simple d'accéder à des compléments spécifiques à la commande. –

4

Jetez un oeil à l'administration Debian An introduction to bash completion - c'est assez facile à comprendre - en passant, il a aussi un part two.

+1

Cela semble être un guide décent pour écrire des fonctions qui * fournissent * des ensembles d'achèvement pour les commandes.Cependant, le PO cherche un moyen de * invoquer * cette fonctionnalité par programme, de la même manière que bash lui-même le fait quand l'utilisateur frappe la touche 'TAB'. – intuited

+2

PS: habituellement, je ne voudrais pas downvote quelque chose comme ça, car il fournit des informations utiles, mais à l'époque, il était à 4 points et la réponse à la question était à 1. Espérons que les gens seront moins susceptibles de dépenser temps à lire à travers la page liée à la recherche d'une réponse qui n'est pas là. – intuited

0

Voici un exemple simple mais travaillant en bash:

function foo_completion() 
{ 
    local currentWord=${COMP_WORDS[COMP_CWORD]} 
    local completionList="" 

    case "${COMP_CWORD}" in 
     "1") 
      completionList="command1 command2 command3"; 
      ;; 
     "2") 
      completionList="param1 param2 param3"; 
      ;; 
    esac 

    COMPREPLY=($(compgen -W "${completionList}" -- ${currentWord})) 
} 

complete -F foo_completion foo 

Avec ce genre de code, vous aurez commandN terminé lorsque vous tapez "foo c" + tab et paramN REMPLI lorsque vous tapez « foo command1 p "+ onglet

Vous pouvez calculer la liste de complétion à partir de l'aide de la commande.

MY2C

0

Je piraté jusqu'à ce script un certain temps ce qui vous donne assez précis Man-page Bash Completion je sais que d'autres personnes ont fait des choses similaires avec l'analyse syntaxique --help sortie option.

+0

Excellent script, mais pas tout à fait ce que j'essaie d'atteindre. Merci quand même pour le lien. –

Questions connexes