Come fare in modo che un programma Python, da riga di comando, completi automaticamente le cose arbitrarie NON interprete

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

Domanda

Sono a conoscenza di come impostare il completamento automatico degli oggetti Python nell'interprete Python (su unix).

  • Google mostra molti risultati per spiegazioni su come farlo.
  • Sfortunatamente, ci sono così tanti riferimenti che è difficile trovare quello che devo fare, che è leggermente diverso.

Devo sapere come abilitare il tab / completamento automatico di elementi arbitrari in un programma da riga di comando scritto in Python.

Il mio caso d'uso specifico è un programma Python a riga di comando che deve inviare e-mail. Voglio essere in grado di completare automaticamente gli indirizzi e-mail (ho gli indirizzi sul disco) quando l'utente digita parte di esso (e facoltativamente preme il tasto TAB).

Non ne ho bisogno per funzionare su Windows o Mac, solo Linux.

È stato utile?

Soluzione

Usa i collegamenti readline di Python. Ad esempio,

import readline

def completer(text, state):
    options = [i for i in commands if i.startswith(text)]
    if state < len(options):
        return options[state]
    else:
        return None

readline.parse_and_bind("tab: complete")
readline.set_completer(completer)

I documenti del modulo ufficiali non sono molto più dettagliati, vedi < a href = "http://tiswww.case.edu/php/chet/readline/readline.html#SEC44" rel = "noreferrer"> readline docs per maggiori informazioni.

Altri suggerimenti

Segui la documentazione cmd e andrà tutto bene

import cmd

addresses = [
    'here@blubb.com',
    'foo@bar.com',
    'whatever@wherever.org',
]

class MyCmd(cmd.Cmd):
    def do_send(self, line):
        pass

    def complete_send(self, text, line, start_index, end_index):
        if text:
            return [
                address for address in addresses
                if address.startswith(text)
            ]
        else:
            return addresses


if __name__ == '__main__':
    my_cmd = MyCmd()
    my_cmd.cmdloop()

Output per tab - > tab - > invia - > tab - > tab - > f - > scheda

(Cmd)
help  send
(Cmd) send
foo@bar.com            here@blubb.com         whatever@wherever.org
(Cmd) send foo@bar.com
(Cmd)

Dato che dici " NON interprete " nella tua domanda, immagino che tu non voglia risposte che coinvolgono Python Readline e simili. ( modifica : con il senno di poi, ovviamente non è questo il caso. Ciao ronzio. Penso che queste informazioni siano comunque interessanti, quindi le lascerò qui. )

Penso che potresti essere dopo questo .

Si tratta di aggiungere il completamento a livello di shell a comandi arbitrari, estendendo il completamento del tab di bash.

In poche parole, creerai un file contenente una funzione shell che genererà possibili completamenti, lo salverai in /etc/bash_completion.d/ e lo registrerai con il comando completa . Ecco uno snippet dalla pagina collegata:

_foo() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--help --verbose --version"

    if [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _foo foo

In questo caso, digitando foo - [TAB] verranno forniti i valori nella variabile opts , ovvero --help , --verbose e --version . Per i tuoi scopi, vorrai essenzialmente personalizzare i valori inseriti in opts .

Dai un'occhiata all'esempio nella pagina collegata, è tutto abbastanza semplice.

Sono sorpreso che nessuno abbia menzionato incompleto, ecco un esempio dai documenti:

from argcomplete.completers import ChoicesCompleter

parser.add_argument("--protocol", choices=('http', 'https', 'ssh', 'rsync', 'wss'))
parser.add_argument("--proto").completer=ChoicesCompleter(('http', 'https', 'ssh', 'rsync', 'wss'))

Ecco una versione completamente funzionante del codice che è stata molto fornita da effimero qui (grazie).

import readline

addrs = ['angela@domain.com', 'michael@domain.com', 'david@test.com']

def completer(text, state):
    options = [x for x in addrs if x.startswith(text)]
    try:
        return options[state]
    except IndexError:
        return None

readline.set_completer(completer)
readline.parse_and_bind("tab: complete")

while 1:
    a = raw_input("> ")
    print "You entered", a
# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

# ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc

Puoi provare a utilizzare Python Prompt Toolkit , una libreria per la costruzione applicazioni interattive da riga di comando in Python.

La libreria semplifica l'aggiunta della funzionalità di completamento automatico interattivo, consentendo all'utente di utilizzare il tasto Tab per scorrere visivamente le scelte disponibili. La libreria è multipiattaforma (Linux, OS X, FreeBSD, OpenBSD, Windows). Esempio:

 pgcli - Python Prompt Toolkit

(Fonte immagine: pcgli )

Le risposte postate funzionano bene ma ho aperto una libreria di completamento automatico che ho scritto al lavoro. Lo usiamo da un po 'di tempo in produzione ed è veloce, stabile e facile da usare. Ha anche una modalità demo in modo da poter testare rapidamente ciò che otterresti mentre digiti le parole.

Per installarlo, esegui semplicemente: pip install completamento automatico

Ecco un esempio:

>>> from fast_autocomplete import AutoComplete
>>> words = {'book': {}, 'burrito': {}, 'pizza': {}, 'pasta':{}}
>>> autocomplete = AutoComplete(words=words)
>>> autocomplete.search(word='b', max_cost=3, size=3)
[['book'], ['burrito']]
>>> autocomplete.search(word='bu', max_cost=3, size=3)
[['burrito']]
>>> autocomplete.search(word='barrito', max_cost=3, size=3)  # mis-spelling
[['burrito']]

Pagamento: https://github.com/wearefair/fast-autocomplete per il codice sorgente.

Ed ecco una spiegazione di come funziona: http://zepworks.com/ messaggi / you-completamento automatico-me /

Si occupa di errori di ortografia e facoltativamente di ordinamento in base al peso della parola. (diciamo che burrito è più importante di book , quindi dai a burrito un "count" più alto e comparirà prima di libro nei risultati.

Words è un dizionario e ogni parola può avere un contesto. Ad esempio il "conteggio", come visualizzare la parola, qualche altro contesto attorno alla parola, ecc. In questo esempio le parole non avevano alcun contesto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top