Tabulation-complétion dans l'interpréteur Python dans le Terminal OS X

Il y a plusieurs mois, j'ai écrit un article de blog détaillant comment réaliser l'achèvement des onglets dans l'interpréteur interactif Python standard-une fonctionnalité que je pensais seulement disponible dans IPython. Je l'ai trouvé extrêmement pratique étant donné que je dois parfois passer à l'interpréteur standard en raison de problèmes IPython unicode.

Récemment, j'ai fait du travail dans OS X. À mon mécontentement, le script ne semble pas fonctionner pour L'application Terminal D'OS X. J'espère que certains d'entre vous avec l'expérience dans OS X pourrait être en mesure de m'aider à le dépanner afin qu'il puisse fonctionner dans le Terminal, aussi bien.

Je reproduit le code ci-dessous

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

Notez que je l'ai légèrement modifié à partir de la version sur mon blog afin que le IrlCompleter soit initialisé avec un vrai onglet, ce qui semble être ce qui est sorti par la touche Tab dans le Terminal.

22
demandé sur gotgenes 2009-03-24 00:48:29

7 réponses

Pour éviter d'avoir à utiliser plus de code GPL, Apple n'inclut pas de readline réel. Au lieu de cela, il utilise la licence BSD libedit , qui est principalement compatible avec readline. Construisez votre propre Python (ou utilisez Fink ou MacPorts) si vous voulez terminer.

8
répondu vasi 2009-03-26 11:47:57

Cela devrait fonctionner sous Python de Leopard:

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

Alors que celui-ci ne le fait pas:

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

Enregistrez-le dans ~/.pythonrc.py et exécutez-vous .bash_profile

export PYTHONSTARTUP=$HOME/.pythonrc.py
56
répondu B0rG 2009-06-14 08:52:51

Voici une version multi-plateforme complète de l'achèvement de l'onglet de chargement Pour Windows / OS X / Linux en un seul coup:

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

À Partir de http://www.farmckon.net/?p=181

11
répondu FarMcKon 2009-08-11 01:52:21

Cela fonctionne pour moi sur Linux bash et OS X 10.4

import readline
import rlcompleter
readline.parse_and_bind('tab: complete')
1
répondu Van Gale 2009-03-23 23:11:58

Si après avoir essayé ce qui précède, cela ne fonctionne toujours pas, essayez de l'exécuter dans le shell:

sudo easy_install readline

Ensuite, créez ~/.profil fichier avec le contenu:

export PYTHONSTARTUP=$HOME/.pythonrc.py

Et a ~/.pythonrc.py fichier avec le contenu:

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

Merci à Steven Bamford pour l'astuce easy_install, et Nicolas pour le contenu du fichier.

1
répondu Gilad Beeri 2014-05-28 10:17:56

La façon documentée de dire libedit (la semi-readline de Mac OS) à partir de la vraie est: si "libedit" dans readline.doc: passez # cas Mac autre: passez # GNU readline case

0
répondu Paul Koning 2016-05-16 19:25:27

Après avoir rencontré de nombreux problèmes concernant Python (2 et 3) sur FreeBSD, j'ai finalement obtenu une extension appropriée pour travailler en utilisant libedit directement comme completer pour Python.

Le problème de base avec libedit / readline est que l'achèvement et l'entrée de Python étaient fortement orientés vers GNU readline... Malheureusement, ce n'est en fait pas une interface particulièrement bonne. Il nécessite un nombre géant de globals en C et ne fonctionne pas bien sur une " instance" base.

Solution:

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

C'est une véritable extension Python séparée qui se lie directement à libedit en utilisant l'interface "libedit" réelle-pas la colle readline sur le côté.

Je l'ai testé assez soigneusement sur Ubuntu, FreeBSD, OpenBSD, NetBSD et MacOS-les résultats sont affichés dans le fichier readme. Le code c est très propre et n'a pratiquement pas de bits dépendants de la plate-forme-contrairement à la ligne de lecture.c module dans Python.

Notes: Cela fonctionne sur python3 > 3.2. Ce n'est pas un remplacement drop-in pour 'import readline' dans d'Autres scripts, mais ces scripts peuvent être ajustés facilement. Il peut coexister avec readline.so - il y a un code pour un sitecustomize.py fichier qui permet la sélection. Il peut utiliser une distribution 'libedit.so', un construit sur mesure ou libedit intégré dans l'extension elle-même.

0
répondu mjn 2017-06-01 16:35:13