2009-03-23 12 views
22

Kilka miesięcy temu napisałem blog post opisujący, w jaki sposób osiągnąć zakończenie tabulatora w standardowym interpretatorze interaktywnym Python - funkcja, którą kiedyś uważałem za dostępną tylko w IPythonie. Zauważyłem, że jest to niezwykle przydatne, biorąc pod uwagę, że czasami muszę przełączyć się na standardowy interpreter z powodu problemów z unikodami IPython.Uzupełnianie tabulatorami w interpreterach języka Python w terminalu OS X

Ostatnio zrobiłem trochę pracy w OS X. Ku mojemu niezadowoleniu skrypt wydaje się nie działać dla aplikacji terminalowej OS X. Mam nadzieję, że niektórzy z was z doświadczeniem w OS X mogą mi pomóc w rozwiązywaniu problemów, aby mógł działać również w Terminalu.

Jestem odtwarzając poniższy kod

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

Zauważ, że mam lekko pod redakcją go z wersji na moim blogu tak, że IrlCompleter jest inicjowany z prawdziwej karcie, która wydaje się być to, co jest wyprowadzany przez klawisz Tab w Terminalu.

Odpowiedz

8

aby uniknąć konieczności użyć kodu GPL więcej, Apple nie obejmuje prawdziwe readline. Zamiast tego wykorzystuje licencję BSD libedit, która jest kompatybilna głównie z readline. Zbuduj swój własny Python (lub użyj Fink lub MacPorts), jeśli chcesz zakończyć.

+0

Ah, dzięki za wyjaśnienie, dlaczego to nie działa. :-) – gotgenes

+0

Wygląda na to, że w Macportach nie ma Pythona z TabCompletion:% wariantów portu python26% zawiera tylko pakiety darwin, universal i ucs4. - Jak zainstalować Pythona z uzupełnianiem kart przez MacPorts? –

+0

@Masi, uzupełnianie kart nie jest wariantem portu, jest to coś, co konfigurujesz po fakcie. Zobacz http://docs.python.org/library/rlcompleter.html – mpontillo

1

Działa to dla mnie zarówno bash Linux i OS X 10,4

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

Zauważyłem, że działa to w mojej kopii Python3.0 na systemie Leopard (OS X 10.5), który skompilowałem z readline 6. Nie działa to dla mnie z kopią Python2.5 dostarczoną z system operacyjny. –

+0

+1 Bo nie wiedziałem o tym krótkim sposobie robienia rzeczy! –

+0

Jak powiedział Jarrett, to nie działa na OS X 10.5 z dołączonym Pythonem 2.5. – gotgenes

56

To powinno działać pod Leopard python:

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

niniejsza nie robi:

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

zapisać go w ~/.pythonrc.py i wykonać w .bash_profile

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

działa dla mnie! Teraz możesz go uruchomić z 'readline.set_completer()'? –

+0

działa dla mnie 10.5 –

+0

dziwne ... czy możesz mi powiedzieć, jaka jest twoja wersja Pythona? mój jest Python 2.5.1 (r251: 54863, 6 lutego 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] na darwin – B0rG

11

Oto pełna wersja wieloplatformowego ładowania tabulatora dla Windows/OS X/Linux w jednym ujęciu:

#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") 

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

+0

'' readline.parse_and_bind ("bind^I rl_complete") '' i '' readline.parse_and_bind ("tab: complete") '' nie wydają się być w konflikcie, więc '' else'' można uprościć w dół kawałek. –

1

Jeśli po wypróbowaniu powyższych, to nadal nie działa, a następnie spróbuj wykonać w powłoce:

sudo easy_install readline 

Następnie utwórz ~/.profile plik z zawartością:

export PYTHONSTARTUP=$HOME/.pythonrc.py 

i ~ /.pythonrc.py plik z treścią:

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

Dzięki Steven Bamford dla easy_install cynk, i Nicolas za zawartość plików.

+0

To działa dla Yosemite, okrzyki. Andy – Garbit

0

Udokumentowanym sposobem na poinformowanie libedit (Mac-semi-readline) z prawdziwego jest: , jeśli "libedit" w readline.doc: wprost przypadek # Mac else: wprost # GNU readline przypadek

0

Po awarii w wielu kwestiach dotyczących Pythonie (2 i 3) na FreeBSD, ale w końcu dostał prawidłowe rozszerzenie do pracy przy użyciu libedit bezpośrednio jako wykonawca dla Python.

Podstawową kwestią związaną z libedit/readline jest to, że wypełnianie i wprowadzanie Pythona było mocno naciągane w kierunku GNU readline ... Niestety, w rzeczywistości nie jest to szczególnie dobry interfejs. Wymaga ogromnej liczby globali w C i nie działa dobrze na podstawie "instancji".

Rozwiązanie:

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

To jest prawdziwy osobny rozszerzenie Pythona, który łączy się bezpośrednio do libedit przy założeniu „libedit” interfejs - nie klej readline na boku.

Przetestowałem to całkiem dobrze na Ubuntu, FreeBSD, OpenBSD, NetBSD i MacOS - wyniki publikowane są w readme. Kod c jest bardzo czysty i nie ma praktycznie żadnych bitów zależnych od platformy - w przeciwieństwie do modułu readline.c w Pythonie.

Notatki: Działa na Pythonie3> 3.2. NIE jest zamiennikiem "import readline" w innych skryptach, ale te skrypty można łatwo dopasować. Może współistnieć z readline.so - istnieje kod pliku sitecustomize.py, który umożliwia wybór. Może wykorzystywać dystrybucję "libedit.so", niestandardową wbudowaną lub libedit wbudowaną w samo rozszerzenie.

Powiązane problemy