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

Posted

技术标签:

【中文标题】OS X 终端中 Python 解释器中的制表符完成【英文标题】:Tab-completion in Python interpreter in OS X Terminal 【发布时间】:2010-10-15 02:13:15 【问题描述】:

几个月前,我写了一篇blog post,详细介绍了如何在标准 Python 交互式解释器中实现制表符补全——我曾经认为只有 IPython 才有的功能。由于 IPython unicode 问题,我有时不得不切换到标准解释器,因此我发现它非常方便。

最近我在 OS X 上做了一些工作。令我不满的是,该脚本似乎不适用于 OS X 的终端应用程序。我希望你们中的一些有 OS X 经验的人能够帮助我解决它,以便它也可以在终端中工作。

我正在复制下面的代码

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

请注意,我对我的博客文章中的版本进行了轻微编辑,以便使用真正的选项卡初始化 IrlCompleter,这似乎是终端中 Tab 键输出的内容。

【问题讨论】:

【参考方案1】:

这应该可以在 Leopard 的 python 下工作:

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

而这个没有:

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

保存到 ~/.pythonrc.py 并在 .bash_profile 中执行

export PYTHONSTARTUP=$HOME/.pythonrc.py

【讨论】:

为我工作!现在,你可以让它和readline.set_completer()一起工作吗? 奇怪...你能告诉我你的 Python 版本是什么吗?我的是 darwin 上的 Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) [GCC 4.0.1 (Apple Inc. build 5465)] 是的,现在它可以工作了,它缺少 import rlcompleter,抱歉这么大惊小怪 ;-) 干杯。 如果你想将完成绑定到 esc,你可以使用 readline.parse_and_bind ("bind ^[ rl_complete") 。我已经使用双命令绑定了大写锁定。我现在完成时节省的那一点距离真是太棒了! (而且我用的是TextMate,它使用esc作为完整的键)。 我尝试了这个实现,但我遇到了一个问题,即“b”键在 Python 3 中停止工作,尽管它在 Python2 中运行良好。【参考方案2】:

这是一个完整的跨平台版本的 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")

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

【讨论】:

readline.parse_and_bind ("bind ^I rl_complete")readline.parse_and_bind("tab: complete") 似乎没有冲突,所以else 可以简化一点。【参考方案3】:

为了避免使用更多的 GPL 代码,Apple 没有包含真正的 readline。相反,它使用 BSD 许可的 libedit,它仅与大多数 readline 兼容。如果您想完成,请构建您自己的 Python(或使用 Fink 或 MacPorts)。

【讨论】:

Macports 中似乎没有带有 TabCompletion 的 Python:% 端口变体 python26 % 只提供 darwin、universal 和 ucs4 包。 -- 如何通过 MacPorts 安装带有 tab 补全功能的 Python? @Masi,制表符完成不是端口变体,它是您事后配置的东西。见docs.python.org/library/rlcompleter.html【参考方案4】:

这对我在 Linux bash 和 OS X 10.4 上都有效

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

【讨论】:

我注意到这适用于我在 Leopard (OS X 10.5) 上的 Python3.0 副本,我针对 readline 6 编译了它。它似乎不适用于我的 Python2 副本.5 随操作系统提供。 +1 因为我不知道这种简短的做事方式! 正如 Jarrett 所说,这不适用于包含 Python 2.5 的 OS X 10.5。 好吧,这太糟糕了。后来我也意识到这对“初始选项卡”问题没有帮助,这就是你的代码更复杂的原因。 @Van Gale:我应该在其中放置代码的文件的名称是什么?我知道模块用户可以使用.pythonrc,但我不确定它是否正确。【参考方案5】:

如果尝试了以上方法还是不行,那就尝试在shell中执行:

sudo easy_install readline

然后,创建 ~/.profile 文件,内容如下:

export PYTHONSTARTUP=$HOME/.pythonrc.py

还有一个 ~/.pythonrc.py 文件,内容如下:

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

感谢Steven Bamford 提供easy_install 提示,感谢Nicolas 提供文件内容。

【讨论】:

【参考方案6】:

将 libedit(Mac OS 半阅读线)与真实的文件区别开来的记录方法是: 如果 "libedit" 在 readline 中。doc: 通过#Mac案例 别的: 通过 # GNU readline 案例

【讨论】:

【参考方案7】:

在 FreeBSD 上遇到许多处理 Python(2 和 3)的问题后,我终于得到了一个适当的扩展,可以直接使用 libedit 作为 Python 的完成程序。

libedit/readline 的基本问题是 Python 的完成和输入严重倾向于 GNU readline... 遗憾的是,这实际上并不是一个特别好的接口。它需要 C 语言中的大量全局变量,并且在“实例”基础上不能很好地工作。

解决方案:

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

这是一个真正的独立 python 扩展,它使用实际的“libedit”接口直接链接到 libedit——而不是侧面的 readline 胶水。

我已经在 Ubuntu、FreeBSD、OpenBSD、NetBSD 和 MacOS 上对它进行了相当彻底的测试——结果发布在自述文件中。 c 代码非常干净,几乎没有平台相关位 - 与 Python 中的 readline.c 模块不同。

注意事项: 它适用于 Python3 > 3.2。 它不是其他脚本中“import readline”的直接替代品,但可以轻松调整这些脚本。 它可以与 readline.so 共存——有用于启用选择的 sitecustomize.py 文件的代码。 它可以使用发行版“libedit.so”、自定义构建的发行版或扩展本身内置的 libedit。

【讨论】:

以上是关于OS X 终端中 Python 解释器中的制表符完成的主要内容,如果未能解决你的问题,请参考以下文章

Mac OS X 终端中的 Vim:逐字移动光标

在 Mac OS X 上将代码粘贴到终端窗口中的 vim

用于 MobileConfig 文件的 OS X 终端中的 XML 解析

无法通过终端访问 OS X 中的 adb,“找不到命令”

如何使用 OS X 终端杀死所有同名进程

从 OS X 终端编译 Qt 示例的问题