Come eseguire il completamento automatico della riga di comando di Python ma NON solo all'inizio di una stringa

StackOverflow https://stackoverflow.com/questions/209484

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).

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top