Frage Wie mache ich ein Python, Kommandozeilenprogramm automatische Vervollständigung beliebiger Dinge NICHT Interpreter


Mir ist bewusst, wie man die automatische Vervollständigung von Python-Objekten im Python-Interpreter (unter Unix) einrichtet.

  • Google zeigt viele Treffer für Erklärungen dazu.
  • Leider gibt es so viele Hinweise darauf, dass es schwierig ist zu finden, was ich tun muss, was etwas anders ist.

Ich muss wissen, wie man in einem Befehlszeilenprogramm, das in Python geschrieben ist, Tabulator / Auto-Vervollständigung beliebiger Elemente aktiviert.

Mein spezifischer Anwendungsfall ist ein Befehlszeilen-Python-Programm, das E-Mails senden muss. Ich möchte in der Lage sein, E-Mail-Adressen automatisch zu vervollständigen (ich habe die Adressen auf der Festplatte), wenn der Benutzer einen Teil davon eingibt (und optional die TAB-Taste drückt).

Ich brauche es nicht auf Windows oder Mac, nur Linux.


76
2017-10-09 14:55


Ursprung


Antworten:


Benutze Pythons readline Bindungen. Beispielsweise,

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)

Das offizielle Moduldokumente sind nicht viel detaillierter, siehe die readline Dokumente Für mehr Information.


49
2017-10-09 15:01



Folge dem cmd Dokumentation und dir wird es gut gehen

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

Ausgabe für Registerkarte -> Registerkarte -> Senden -> Registerkarte -> Registerkarte -> f -> Registerkarte

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

52
2017-10-09 15:08



Da Sie in Ihrer Frage "NICHT-Interpreter" sagen, denke ich, dass Sie keine Antworten wünschen, die python readline und ähnliches beinhalten. (bearbeitenIm Nachhinein ist das natürlich nicht der Fall. Hör mal. Ich denke diese Info ist trotzdem interessant, also werde ich es hier lassen.


27
2017-10-13 09:59



Ich bin überrascht, dass niemand argcomplete erwähnt hat, hier ist ein Beispiel aus der Dokumentation:

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

19
2018-05-30 16:59



Hier ist eine voll funktionsfähige Version des Codes, die von Ephemient sehr bereitgestellt wurde Hier (Danke).

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

11
2017-10-16 19:26



# ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

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

7
2017-10-24 00:48