简体   繁体   English

OS X 终端中 Python 解释器中的制表符完成

[英]Tab-completion in Python interpreter in OS X Terminal

Several months ago, I wrote a blog post detailing how to achieve tab-completion in the standard Python interactive interpreter--a feature I once thought only available in IPython.几个月前,我写了一篇博文,详细介绍了如何在标准的 Python 交互式解释器中实现制表符补全——我曾经认为这个功能只能在 IPython 中使用。 I've found it tremendously handy given that I sometimes have to switch to the standard interpreter due to IPython unicode issues.由于 IPython unicode 问题,我有时不得不切换到标准解释器,我发现它非常方便。

Recently I've done some work in OS X. To my discontent, the script doesn't seem to work for OS X's Terminal application.最近我在 OS X 上做了一些工作。令我不满的是,该脚本似乎不适用于 OS X 的终端应用程序。 I'm hoping some of you with experience in OS X might be able to help me trouble-shoot it so it can work in Terminal, as well.我希望你们中的一些有 OS X 经验的人能够帮助我解决它,以便它也可以在终端中工作。

I am reproducing the code below我正在复制下面的代码

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

Note that I have slightly edited it from the version on my blog post so that the IrlCompleter is initialized with a true tab, which seems to be what is output by the Tab key in Terminal.请注意,我已经从我的博客文章中的版本稍微编辑了它,以便使用真正的选项卡初始化IrlCompleter ,这似乎是终端中 Tab 键的 output。

This should work under Leopard's python:这应该在 Leopard 的 python 下工作:

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

Whereas this one does not:而这个没有:

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

Save it in ~/.pythonrc.py and execute in.bash_profile将其保存在 ~/.pythonrc.py 并执行 in.bash_profile

export PYTHONSTARTUP=$HOME/.pythonrc.py

here is a full cross platform version of loading tab completion for Windows/OS X/Linux in one shot:这是一个完整的跨平台版本的 Windows/OS X/Linux 一次性加载选项卡完成:

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

From http://www.farmckon.net/?p=181来自http://www.farmckon.net/?p=181

To avoid having to use more GPL code, Apple doesn't include a real readline.为了避免使用更多的 GPL 代码,Apple 没有包含真正的 readline。 Instead it uses the BSD-licensed libedit , which is only mostly-readline-compatible.相反,它使用 BSD 许可的libedit ,它只与大多数 readline 兼容。 Build your own Python (or use Fink or MacPorts) if you want completion.如果您想完成,请构建您自己的 Python(或使用 Fink 或 MacPorts)。

If after trying the above, it still doesn't work, then try to execute in the shell:如果尝试了以上方法还是不行,那么尝试在shell中执行:

sudo easy_install readline

Then, create ~/.profile file with the content:然后,使用以下内容创建~/.profile文件:

export PYTHONSTARTUP=$HOME/.pythonrc.py

and a ~/.pythonrc.py file with the content:和一个包含以下内容的~/.pythonrc.py文件:

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

Thanks to Steven Bamford for the easy_install tip, and Nicolas for the file content.感谢Steven Bamford提供的 easy_install 提示,以及Nicolas提供的文件内容。

This works for me on both Linux bash and OS X 10.4这在 Linux bash 和 OS X 10.4 上都适用于我

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

The documented way to tell libedit (the Mac OS semi-readline) from the real one is: if "libedit" in readline.将 libedit(Mac OS 半阅读线)与真实的文件区分开来的记录方法是:如果 readline 中的“libedit”。 doc : pass # Mac case else: pass # GNU readline case doc : pass # Mac case else: pass # GNU readline case

After crashing into many issues dealing with Python (2 and 3) on FreeBSD, I finally got a proper extension to work using libedit directly as the completer for Python.在处理 FreeBSD 上的 Python(2 和 3)的许多问题之后,我终于得到了一个适当的扩展,可以直接使用 libedit 作为 Python 的完成者。

The basic issue with libedit/readline is that Python's completion and input was heavily bent towards GNU readline... Sadly, this is actually not a particularly good interface. libedit/readline 的基本问题是 Python 的完成和输入严重倾向于 GNU readline... 遗憾的是,这实际上不是一个特别好的接口。 It requires a giant number of globals in C and does not work well on an "instance" basis.它需要 C 中的大量全局变量,并且在“实例”基础上不能很好地工作。

Solution:解决方案:

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

This is a true separate python extension which directly links to libedit using the actual "libedit" interface -- not the readline glue on the side.这是一个真正独立的 python 扩展,它使用实际的“libedit”接口直接链接到 libedit——而不是侧面的 readline 胶水。

I have tested it pretty thoroughly on Ubuntu, FreeBSD, OpenBSD, NetBSD and MacOS -- results are posted in the readme.我已经在 Ubuntu、FreeBSD、OpenBSD、NetBSD 和 MacOS 上对其进行了相当彻底的测试——结果发布在自述文件中。 The c-code is very clean and has virtually no platform dependent bits -- unlike the readline.c module in Python. c 代码非常干净,几乎没有平台相关位 - 与 Python 中的 readline.c 模块不同。

Notes: It works on Python3 > 3.2.注意:它适用于 Python3 > 3.2。 It is NOT a drop-in replacement for 'import readline' in other scripts, but those scripts can be adjusted easily.它不是其他脚本中“import readline”的直接替代品,但可以轻松调整这些脚本。 It can co-exist with readline.so -- there is code for a sitecustomize.py file which enables the selection.它可以与 readline.so 共存——有用于启用选择的 sitecustomize.py 文件的代码。 It can use a distribution 'libedit.so', a custom built one or libedit built into the extension itself.它可以使用发行版“libedit.so”、自定义构建的发行版或扩展本身内置的 libedit。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM