Conclusão da guia na interface da linha de comando python - como pegar eventos da guia
-
20-09-2019 - |
Pergunta
Estou escrevendo um pouco de CLI em Python (como uma extensão do Mercurial) e gostaria de apoiar a conclusão do Tab. Especificamente, gostaria de pegar guias no prompt e mostrar uma lista de opções correspondentes (assim como o Bash).
Exemplo: insira o nome da seção:
ext*TAB*
extensions
extras
O problema é que não tenho certeza de como pegar os eventos da guia. Estou usando o ui.prompt()
API do Mercurial, que está apenas ligando raw_input()
sob o capô.
Até onde sei, raw_input()
Retorna apenas em 'Enter' e, se um usuário entrar em uma guia, a sequência retornada simplesmente inclui um "\t"
.
Solução
Para isso, você usa o readline
módulo.
Código mais simples que posso pensar:
import readline
COMMANDS = ['extra', 'extension', 'stuff', 'errors',
'email', 'foobar', 'foo']
def complete(text, state):
for cmd in COMMANDS:
if cmd.startswith(text):
if not state:
return cmd
else:
state -= 1
readline.parse_and_bind("tab: complete")
readline.set_completer(complete)
raw_input('Enter section name: ')
Exemplo de uso:
Enter section name: <tab>
email errors extension extra foo foobar stuff
Enter section name: e<tab>
email errors extension extra
Enter section name: ext<tab>
extension extra
Além da conclusão, readline
fornece a você:
- Edição de linha
- Configuração de encadernação (emacs e modos VI incluídos)
- História (seta para recordar valores anteriores)
- Pesquisa de história, economia e carregamento
Outras dicas
Um excelente exemplo de como fazer a conclusão da TAB em cooperação com Leia a linha é fornecido na biblioteca padrão como o rlCompleter Módulo-você não pode usá-lo como está (ele é concluído com base em nomes atualmente definidos no Python principal e embutido), mas mostra como realizar a tarefa geral e como conectá-lo a readline
.
Você quase certamente deveria estar usando o Módulo CMD, que já implementa a conclusão da guia e assim por diante, e provavelmente outras partes do que você está tentando fazer, usando o módulo ReadLine e assim por diante. Não faz sentido reinventar a roda.