如何启用Python REPL自动完成并仍允许新行缩进

16

我目前在~/.pythonrc中使用以下内容以在Python REPL中启用自动补全:

# Autocompletion
import rlcompleter, readline
readline.parse_and_bind('tab:complete')

然而,当我从新行的开头(例如,在 for 循环的内部)tab 时,我得到了一个建议列表,而不是一个 tab

理想情况下,我希望只在非空白字符后面获取建议。

这在 ~/.pythonrc 中实现起来是否直截了当?


这个 HN 评论中有一些代码,可以在当前行只包含空格时禁用自动完成。 - Tgr
1个回答

34

您应该使用IPython。它具有标签自动完成和for循环或函数定义的自动缩进功能。例如:

# Ipython prompt
In [1]: def stuff(x):
   ...:     |
#           ^ cursor automatically moves to this position

安装它,您可以使用pip

pip install ipython

如果您没有安装pip,您可以按照此页面上的说明进行操作。在Python >= 3.4中,默认安装了pip
如果您使用的是Windows系统,此页面包含IPython(以及许多其他可能难以安装的Python库)的安装程序。

然而,如果由于任何原因您无法安装ipython,Brandon Invergo创建了一个python启动脚本,其中包含多个Python解释器的功能,其中之一是自动缩进。他已经按照GPL v3发布了该脚本,并在此处发布了源代码。

我复制了处理自动缩进的代码如下。我不得不在第11行添加indent = ''才能使其在我的Python 3.4解释器上正常工作。

import readline

def rl_autoindent():
    """Auto-indent upon typing a new line according to the contents of the
    previous line.  This function will be used as Readline's
    pre-input-hook.

    """
    hist_len = readline.get_current_history_length()
    last_input = readline.get_history_item(hist_len)
    indent = ''
    try:
        last_indent_index = last_input.rindex("    ")
    except:
        last_indent = 0
    else:
        last_indent = int(last_indent_index / 4) + 1
    if len(last_input.strip()) > 1:
        if last_input.count("(") > last_input.count(")"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count(")") > last_input.count("("):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input.count("[") > last_input.count("]"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count("]") > last_input.count("["):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input.count("{") > last_input.count("}"):
            indent = ''.join(["    " for n in range(last_indent + 2)])
        elif last_input.count("}") > last_input.count("{"):
            indent = ''.join(["    " for n in range(last_indent - 1)])
        elif last_input[-1] == ":":
            indent = ''.join(["    " for n in range(last_indent + 1)])
        else:
            indent = ''.join(["    " for n in range(last_indent)])
    readline.insert_text(indent)

readline.set_pre_input_hook(rl_autoindent)

4
这是一种可能性,我经常使用它,但并不总是在你所使用的每个平台/服务器上安装IPython。我(以及原帖作者)想知道是否可以调整标准Python解释器提示符,在空行开头插入一个制表符。 - MattDMo
@MattDMo 我已经编辑了我的答案,添加了在标准Python解释器上执行此操作的方法。 - parchment
1
我发现现在需要安装IPython之外的pyreadline才能使制表符自动完成功能正常工作。 - Tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接