Finalización de la pestaña personalizada en python argparse
bash command-line-interface (2)
¿Cómo obtener la finalización de la pestaña de shell cooperando con argparse
en un script de Python?
#!/usr/bin/env python
import argparse
def main(**args):
pass
if __name__ == ''__main__'':
parser = argparse.ArgumentParser()
parser.add_argument(''positional'', choices=[''spam'', ''eggs''])
parser.add_argument(''--optional'', choices=[''foo1'', ''foo2'', ''bar''])
args = parser.parse_args()
main(**vars(args))
Con un indicador ejecutable establecido en el archivo .py, los resultados esperados deberían ser algo como:
$ ./example.py sp<tab>
-> completes to "./example.py spam"
$ ./example.py --op<tab>
-> completes to "./example.py --optional"
$ ./example.py --optional b<tab>
-> completes to "./example.py --optional bar"
$ ./example.py --optional f<tab>
-> completes to "./example.py --optional foo"
and, additionally, prints "foo1 foo2" choices on stdout on a new line
Echa un vistazo a argcomplete por Andrey Kislyuk.
Instalalo con:
pip install argcomplete
Importe el módulo y agregue una línea en su fuente antes de llamar a parser.parse_args()
:
#!/usr/bin/env python
import argparse as ap
import argcomplete
def main(**args):
pass
if __name__ == ''__main__'':
parser = ap.ArgumentParser()
parser.add_argument(''positional'', choices=[''spam'', ''eggs''])
parser.add_argument(''--optional'', choices=[''foo1'', ''foo2'', ''bar''])
argcomplete.autocomplete(parser)
args = parser.parse_args()
main(**vars(args))
y para asegurarse de que bash sepa acerca de este script, use
eval "$(register-python-argcomplete your_script)"
debe poner esa línea en su ~/.bashrc
o seguir los documentos de argcomplete y activar la finalización ''global''.
Después de que su finalización funciona según lo solicitado.
La forma en que funciona es que la línea eval crea una función _python_argcomlete
que se registra usando complete
. (Ejecute register-python-argcomplete your_script
para ver lo que se evalúa en bash). La función autocompletar busca las variables de entorno establecidas por el mecanismo de finalización de bash para ver si necesita actuar. Si actúa, sale del programa. Si no actúa, esta es una llamada normal al programa, esa función no hace nada y el flujo normal del programa continúa.
Para que la función de autocompletar funcione, necesita una función bash para generar las opciones posibles, y luego debe ejecutar el complete -F <function_name> <program_name>
La mejor manera de hacer esto es hacer que el programa genere la función de finalización basada en su propio algoritmo de análisis para evitar la duplicación. Sin embargo, a simple vista de argparse, no pude encontrar una forma de acceder a su estructura interna, pero le sugiero que la busque.
Aquí está una función de bash que hará para el programa anterior:
function _example_auto() {
local cur=${COMP_WORDS[COMP_CWORD]}
local prev=${COMP_WORDS[COMP_CWORD-1]}
case "$prev" in
--optional )
COMPREPLY=( $(compgen -W "foo1 foo2 bar" -- $cur) )
return 0
;;
*)
COMPREPLY=( $(compgen -W "--optional spam eggs" -- $cur) )
return 0
;;
esac
}