2009-03-23 9 views
22

Hace varios meses, escribí un blog post que detalla cómo lograr la finalización de tabulación en el intérprete interactivo estándar de Python, una función que una vez pensé que solo estaba disponible en IPython. Lo encontré tremendamente útil dado que a veces tengo que cambiar al intérprete estándar debido a problemas de unicode de IPython.Finalización de tabulación en el intérprete de Python en el terminal OS X

Recientemente he hecho algunos trabajos en OS X. Para mi descontento, la secuencia de comandos no parece funcionar para la aplicación de terminal de OS X. Espero que algunos de ustedes con experiencia en OS X puedan ayudarme a solucionar problemas para que también funcione en Terminal.

reproduzco el siguiente código

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

Tenga en cuenta que he editado un poco desde la versión en mi blog para que el IrlCompleter se inicializa con un cierto pestaña, que parece ser lo que se emite por la tecla Tab en Terminal.

Respuesta

8

Para evitar tener que utilizar un código más GPL, Apple no incluye un readline real. En su lugar, utiliza el libedit licenciado por BSD, que es solo compatible en su mayoría con readline. Cree su propia Python (o use Fink o MacPorts) si desea completarla.

+0

Ah, gracias por explicar por qué esto no funciona. :-) – gotgenes

+0

Parece que no hay Python con TabCompletion en Macports:% variantes de puerto python26% solo da paquetes darwin, universal y ucs4. - ¿Cómo se puede instalar Python con la finalización de pestañas con MacPorts? –

+0

@Masi, la finalización de pestañas no es una variante de puerto, es algo que se configura después de los hechos. ¡Vea http://docs.python.org/library/rlcompleter.html – mpontillo

1

Esto funciona para mí en tanto bash de Linux y OS X 10,4

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

Me he dado cuenta de que esto funciona en mi copia de Python3.0 en Leopard (OS X 10.5), que compilé contra readline 6. Parece que no funciona para mí con la copia de Python2.5 que se envía con el sistema operativo. –

+0

+1 ¡Porque no sabía de esta manera tan corta de hacer las cosas! –

+0

Como dijo Jarrett, esto no funciona en OS X 10.5 con el Python 2.5 incluido. – gotgenes

56

Esto debería funcionar bajo el pitón del leopardo:

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

mientras que éste no lo hace:

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

Guardar en ~/.pythonrc.py y ejecutar en .bash_profile

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

¡funciona para mí! Ahora, ¿puede hacer que funcione con 'readline.set_completer()'? –

+0

funciona para mí en 10.5 –

+0

extraño ... ¿puedes decirme cuál es tu versión de Python? el mío es Python 2.5.1 (r251: 54863, 6 de febrero de 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. compilación 5465)] en darwin – B0rG

11

aquí hay una versión completa de plataforma cruzada de completar la pestaña de carga para Windows/OS X/Linux en una sola toma:

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

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

+0

'' readline.parse_and_bind ("bind^I rl_complete") '' y '' readline.parse_and_bind ("tab: complete") '' no parecen entrar en conflicto, por lo que el '' else'' se puede simplificar poco. –

1

Si después de probar lo anterior, aún así no funciona, a continuación, tratar de ejecutar en el shell:

sudo easy_install readline 

A continuación, cree ~/.profile archivo con el contenido:

export PYTHONSTARTUP=$HOME/.pythonrc.py 

y una ~ /.pythonrc.py archivo con el contenido:

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

Gracias a Steven Bamford por la punta, y easy_install Nicolas para el contenido del archivo.

+0

Esto funciona para Yosemite, ¡salud! Andy – Garbit

0

La manera documentada de decirle a libedit (la semilnea de lectura de Mac OS) del real es: si "libedit" en readline.doc: pase el caso # Mac otra cosa: pase caso readline # GNU

0

después de chocar contra muchos temas relacionados con Python (2 y 3) en FreeBSD, finalmente consiguió una extensión adecuada para trabajar utilizando libedit directamente como el completo para Python.

El problema básico con libedit/readline es que la finalización y la entrada de Python se inclinaron fuertemente hacia la línea de lectura de GNU ... Lamentablemente, esta no es una interfaz particularmente buena. Requiere una gran cantidad de elementos globales en C y no funciona bien en "instancia".

Solución:

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

Esta es una verdadera extensión pitón separado que vincula directamente a libedit utilizando el "libedit" interfaz real - no el pegamento readline en el lado.

Lo he probado muy bien en Ubuntu, FreeBSD, OpenBSD, NetBSD y MacOS - los resultados se publican en el archivo léame. El código c es muy limpio y prácticamente no tiene bits dependientes de la plataforma, a diferencia del módulo readline.c en Python.

Notas: Funciona en Python3> 3.2. NO es un reemplazo inmediato para 'read readline' en otros scripts, pero esos scripts se pueden ajustar fácilmente. Puede coexistir con readline.so: hay un código para un archivo sitecustomize.py que habilita la selección. Puede usar una distribución 'libedit.so', una compilación personalizada o libedit integrada en la propia extensión.

Cuestiones relacionadas