Come eseguire il completamento automatico della riga di comando di Python ma NON solo all'inizio di una stringa
-
03-07-2019 - |
Domanda
Python, attraverso i suoi collegamenti readline consente un ottimo completamento automatico della riga di comando (come descritto in qui ).
Ma il completamento sembra funzionare solo all'inizio delle stringhe. Se vuoi abbinare la metà o la fine di una stringa readline non funziona.
Vorrei completare automaticamente le stringhe, in un programma Python da riga di comando abbinando ciò che scrivo con una qualsiasi delle stringhe in un elenco di stringhe disponibili.
- Un buon esempio del tipo di completamento automatico che vorrei avere è il tipo che si verifica in GMail quando si digita nel campo A. Se digiti il ??cognome di uno dei tuoi contatti, verrà visualizzato anche se hai digitato il suo nome.
- Potrebbe essere necessario un certo uso delle frecce su e giù o qualche altro metodo per selezionare tra le stringhe abbinate (e non nel caso di readline) e questo va bene nel mio caso.
- Il mio caso d'uso particolare è un programma da riga di comando che invia e-mail.
- Esempi specifici di codice sarebbero molto utili.
L'uso di emulatori di terminale come maledizioni andrebbe bene. Deve funzionare solo su Linux, non su Mac o Windows.
Ecco un esempio: Supponiamo che io abbia le seguenti tre stringhe in un elenco
['Paul Eden <paul@domain.com>',
'Eden Jones <ejones@domain.com>',
'Somebody Else <somebody@domain.com>']
Vorrei un codice che completasse automaticamente i primi due elementi nell'elenco dopo aver digitato 'Eden' e quindi mi permettesse di sceglierne uno (tutto attraverso la riga di comando usando la tastiera).
Soluzione
Non sono sicuro di aver capito il problema. È possibile utilizzare readline.clear_history e readline.add_history per impostare le stringhe completabili desiderate, quindi control-r per cercare backword nella cronologia (proprio come se si fosse a un prompt della shell). Ad esempio:
#!/usr/bin/env python
import readline
readline.clear_history()
readline.add_history('foo')
readline.add_history('bar')
while 1:
print raw_input('> ')
In alternativa, puoi scrivere la tua versione completa e associare la chiave appropriata ad essa. Questa versione utilizza la cache nel caso in cui l'elenco delle partite sia enorme:
#!/usr/bin/env python
import readline
values = ['Paul Eden <paul@domain.com>',
'Eden Jones <ejones@domain.com>',
'Somebody Else <somebody@domain.com>']
completions = {}
def completer(text, state):
try:
matches = completions[text]
except KeyError:
matches = [value for value in values
if text.upper() in value.upper()]
completions[text] = matches
try:
return matches[state]
except IndexError:
return None
readline.set_completer(completer)
readline.parse_and_bind('tab: menu-complete')
while 1:
a = raw_input('> ')
print 'said:', a