2010-08-19 4 views
22

Estoy tratando de escribir una pequeña aplicación de iniciador de comandos, y me gustaría usar las terminaciones de pestañas de bash en mi propio sistema de finalización. He podido obtener una lista de terminaciones para comandos generales usando compgen -abck.
Sin embargo, también me gustaría obtener terminaciones para comandos específicos: por ejemplo, la entrada git p debe mostrar compleción para los comandos de git.Accediendo a terminaciones de bash para comandos específicos programáticamente

¿Hay alguna manera de que pueda usar compgen para hacer esto? Si no, ¿hay otras formas en que pueda obtener una lista de terminaciones programáticamente?

[EDITAR: Para aclarar, no estoy tratando de proporcionar finalización de bash - mi aplicación es un iniciador de comandos GUI. Simplemente me gustaría usar las terminaciones existentes de bash en mi propia aplicación.]

Respuesta

12

que no se sabe muy bien cómo funciona, pero el awesome window manager utiliza el siguiente código Lua para obtener acceso a consecuencia de la finalización bash:

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

  1. Via complete -p encontramos complete -o bashdefault -o default -o nospace -F _git git. Recordamos "_git" para más tarde.
  2. La longitud de "git l" es 5, por lo que establecemos COMP_COUNT = 6. Estamos completando el primer argumento para "git", entonces COMP_CWORD = 1.

Todos juntos podemos usar el siguiente script:

__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 

salida: "log"

+0

Parece que el código hace exactamente lo que quiero hacer con mi aplicación. Tendré que portarlo a Bash regular, pero sigue siendo muy útil. ¡Muchas gracias! –

+0

Hice algunas pruebas y esto es lo que se ejecuta para completar "git l":/usr/bin/env bash -c 'fuente/etc/bash_completion; __print_completions() {for ((i = 0; i <$ {# COMPREPLY [*]}; i ++)); hacer eco $ {COMPREPLY [i]}; hecho }; COMP_WORDS = (git l); COMP_LINE = "git l"; COMP_COUNT = 6; COMP_CWORD = 1; _git; __print_completions ' –

+0

"_git" se encuentra a través de "complete -p" que imprime "complete -o bashdefault -o default -o nospace -F _git git". Entonces, si la primera palabra es "git", llame a "_git". COMP_COUNT es la longitud de la cadena hasta ahora más uno. COMP_CWORD es la palabra para completar (la primera es el índice 0). –

2

Compruebe en el directorio /etc/bash_completion.d/. Aquí es donde permanecen los diferentes scripts de finalización de comandos.

+0

que han tenido una hurgar en '/ etc/bash_completion.d /', pero no tienen sin embargo, resolvió una forma fácil de obtener las terminaciones contenidas dentro de una forma muy sencilla. (Estoy usando Python para acceder a las terminaciones, haciendo las cosas un poco más complicadas). Esperaba que pudiera haber una forma más simple de acceder a terminaciones específicas de comandos. –

4

Eche un vistazo a la Administración Debian An introduction to bash completion - es bastante fácil de entender - por cierto, también tiene un part two.

+1

Esto parece una guía decente para escribir funciones que * proporcionan * conjuntos de finalización para los comandos.Sin embargo, el OP está buscando una forma de * invocar * esa funcionalidad programáticamente, de la misma manera que bash sí mismo cuando el usuario pulsa la tecla 'TAB'. – intuited

+2

PS: normalmente no rechazaría algo como esto, ya que proporciona información útil, pero en ese momento era de 4 puntos y la respuesta real a la pregunta era 1. Esperamos que de esta manera las personas tengan menos probabilidades de gastar tiempo leyendo la página vinculada buscando una respuesta que no está allí. – intuited

0

Aquí un ejemplo sencillo pero trabajando 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 

Con este tipo de código, obtendrá COMMANDn completado cuando se escribe "foo c" + tab y paramN completa cuando escribe "foo comando1 p "+ tab

Puede calcular la lista de finalización desde la ayuda del comando.

MY2C

0

I hackeado este script hace un tiempo que le da bastante exacto Man-page Bash Completion Sé que otras personas han hecho cosas similares con análisis --help opción de salida.

+0

Excelente script, pero no es exactamente lo que estoy tratando de lograr. De todos modos, gracias por vincularlo. –

Cuestiones relacionadas