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 解释器中的制表符完成的主要内容,如果未能解决你的问题,请参考以下文章