2009-03-23 8 views
22

Vor einigen Monaten schrieb ich eine blog post Detaillierung, wie Tab-Vervollständigung in der Standard-Python Interactive Interpreter - eine Funktion, die ich dachte, nur in IPython verfügbar. Ich habe es sehr nützlich gefunden, da ich manchmal aufgrund von IPython-Unicode-Problemen zum Standard-Interpreter wechseln muss.Tab-Vervollständigung in Python-Interpreter in OS X Terminal

Kürzlich habe ich einige Arbeit in OS X gemacht. Zu meiner Unzufriedenheit, das Skript scheint nicht für OS X-Terminal-Anwendung zu arbeiten. Ich hoffe, dass einige von Ihnen mit Erfahrung in OS X mir dabei helfen können, Probleme damit zu beheben, damit es auch im Terminal funktionieren kann.

Ich reproduzieren Sie den Code unten

import atexit 
import os.path 

try: 
    import readline 
except ImportError: 
    pass 
else: 
    import rlcompleter 

    class IrlCompleter(rlcompleter.Completer): 
     """ 
     This class enables a "tab" insertion if there's no text for 
     completion. 

     The default "tab" is four spaces. You can initialize with '\t' as 
     the tab if you wish to use a genuine tab. 

     """ 

     def __init__(self, tab=' '): 
      self.tab = tab 
      rlcompleter.Completer.__init__(self) 


     def complete(self, text, state): 
      if text == '': 
       readline.insert_text(self.tab) 
       return None 
      else: 
       return rlcompleter.Completer.complete(self,text,state) 


    #you could change this line to bind another key instead tab. 
    readline.parse_and_bind('tab: complete') 
    readline.set_completer(IrlCompleter('\t').complete) 


# Restore our command-line history, and save it when Python exits. 
history_path = os.path.expanduser('~/.pyhistory') 
if os.path.isfile(history_path): 
    readline.read_history_file(history_path) 
atexit.register(lambda x=history_path: readline.write_history_file(x)) 

Bitte beachte, dass ich es leicht von der Version auf meinem Blog-Post bearbeitet haben, so dass die IrlCompleter mit einem echten Tab initialisiert, das, was zu sein scheint Ausgang ist durch die Tabulatortaste im Terminal.

Antwort

8

Um zu vermeiden, mehr GPL-Code zu verwenden, von Apple nicht eine echte Readline- umfassen. Stattdessen verwendet es die BSD-lizenzierte libedit, die nur größtenteils Readline-kompatibel ist. Erstellen Sie Ihr eigenes Python (oder verwenden Sie Fink oder MacPorts), wenn Sie abgeschlossen werden möchten.

+0

Ah, vielen Dank für die Erklärung, warum das nicht funktioniert. :-) – gotgenes

+0

Es scheint, dass es in Macports kein Python mit TabCompletion gibt:% port variants python26% gibt nur darwin, universal und ucs4 packages. - Wie können Sie Python mit Tab-Vervollständigung von MacPorts installieren? –

+0

@Masi, Registerkarte Vervollständigung ist keine Port-Variante, es ist etwas, das Sie nach der Tat konfigurieren. Siehe http://docs.python.org/library/rlcompleter.html – mpontillo

1

Das ist für mich funktioniert sowohl unter Linux bash und OS X 10,4

import readline 
import rlcompleter 
readline.parse_and_bind('tab: complete') 
+0

Ich habe bemerkt, das funktioniert in meiner Kopie von Python3.0 auf Leopard (OS X 10.5), die ich gegen Readline 6 kompiliert. Es scheint nicht mit mir arbeiten mit der Kopie von Python2.5, die mit ausgeliefert wurde das Betriebssystem. –

+0

+1 Weil ich über diesen kurzen Weg nichts wusste! –

+0

Wie Jarrett sagte, dies funktioniert nicht auf OS X 10.5 mit dem mitgelieferten Python 2.5. – gotgenes

56

Dies sollte unter Leopard Python arbeiten:

import rlcompleter 
import readline 
readline.parse_and_bind ("bind ^I rl_complete") 

Während dieses nicht:

import readline, rlcompleter 
readline.parse_and_bind("tab: complete") 

speichern es in ~/.pythonrc.py und führen in Bash_profile

export PYTHONSTARTUP=$HOME/.pythonrc.py 
+0

funktioniert für mich! Kann man es jetzt mit 'readline.set_completer()' arbeiten lassen? –

+0

funktioniert für mich auf 10.5 –

+0

seltsam ... können Sie mir sagen, was ist Ihre Python-Version? meins ist Python 2.5.1 (r251: 54863, 6. Februar 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. Build 5465)] auf Darwin – B0rG

11

Hier ist eine vollständige Cross-Plattform-Version der Lade Tab Completion für Windows/OS X/Linux in einem Schuss:

#Code UUID = '9301d536-860d-11de-81c8-0023dfaa9e40' 
import sys 
try: 
     import readline 
except ImportError: 
     try: 
       import pyreadline as readline 
     # throw open a browser if we fail both readline and pyreadline 
     except ImportError: 
       import webbrowser 
       webbrowser.open("http://ipython.scipy.org/moin/PyReadline/Intro#line-36") 
       # throw open a browser 
     #pass 
else: 
     import rlcompleter 
     if(sys.platform == 'darwin'): 
       readline.parse_and_bind ("bind ^I rl_complete") 
     else: 
       readline.parse_and_bind("tab: complete") 

Von http://www.farmckon.net/?p=181

+0

'' readline.parse_and_bind ("bind^I rl_complete") '' und '' readline.parse_and_bind ("tab: complete") '' scheinen nicht zu kollidieren, so dass das '' else'' vereinfacht werden kann a Bit. –

1

Wenn nach den oben versuchen, es immer noch nicht funktioniert, dann versuchen Sie in der Shell ausführen:

sudo easy_install readline 

Dann erstellen ~/.profile Datei mit dem Inhalt:

export PYTHONSTARTUP=$HOME/.pythonrc.py 

und ein ~ /.pythonrc.py Datei mit dem Inhalt:

try: 
    import readline 
except: 
    print ("Module readline is not available.") 
else: 
    import rlcompleter 
    readline.parse_and_bind("tab: complete") 

Dank Steven Bamford für die easy_install Spitze und Nicolas für den Dateiinhalt.

+0

Dies funktioniert für Yosemite, Prost. Andy – Garbit

0

Der dokumentierte Weg zu sagen, libedit (das Mac OS semi-readline) von der echten ist: wenn "libedit" in readline.doc: pass # Mac Fall sonst: pass # GNU readline- Fall

0

Nachdem in viele Fragen Absturz mit Python zu tun (2 und 3) auf FreeBSD, Ich habe endlich eine richtige Erweiterung mit libedit direkt zu arbeiten, wie der Vollender für Python.

Das grundlegende Problem mit libedit/readline ist, dass Pythons Vervollständigung und Eingabe stark in Richtung GNU readline verbogen wurde ... Leider ist dies eigentlich keine besonders gute Schnittstelle. Es benötigt eine riesige Anzahl von Globalen in C und funktioniert nicht gut auf einer "Instanz" -Basis.

Lösung:

https://github.com/mark-nicholson/python-editline

Dies ist eine wahre separate Python-Erweiterung, die den eigentlichen „libedit“ Schnittstelle direkt Links libedit mit - nicht die Readline- Klebern auf der Seite.

Ich habe es ziemlich gründlich auf Ubuntu, FreeBSD, OpenBSD, NetBSD und MacOS getestet - Ergebnisse sind in der Readme geschrieben. Der C-Code ist sehr sauber und hat praktisch keine plattformabhängigen Bits - im Gegensatz zum readline.c-Modul in Python.

Hinweise: Es funktioniert auf Python3> 3.2. Es ist kein Ersatz für "readline importieren" in anderen Skripten, aber diese Skripte können leicht angepasst werden. Es kann mit readline.so koexistieren - es gibt Code für eine sitecustomize.py-Datei, die die Auswahl ermöglicht. Es kann eine Distribution 'libedit.so' verwenden, eine benutzerdefinierte oder libedit, die in die Erweiterung selbst eingebaut ist.