1

我正在尝试使用绝地来完成 PyQt 应用程序中的 python 代码,使用QCompleterQStringListModel存储可能的完成。

这是一个简单的工作演示:

#!/usr/bin/env python3

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import jedi
import sys

class JediEdit(QLineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)

        self._model = QStringListModel()
        self._compl = QCompleter()
        self._compl.setModel(self._model)
        self.setCompleter(self._compl)
        self.textEdited.connect(self.update_model)

    def update_model(self, cur_text):
        script = jedi.Script(cur_text)
        compl = script.completions()
        strings = list(cur_text + c.complete for c in compl) 
        self._model.setStringList(strings)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    line = JediEdit()
    line.show()
    sys.exit(app.exec_())

如果您运行应用程序并编写没有完成任何内容的代码(例如foo =),则完成实际上会显示所有可能出现在该位置的标记。

所以,如果我运行并在字段中写一个空格,就会弹出很多东西,从abs__version__.

我想防止这种情况发生:是否可以查询jedi.Script以了解令牌是否正在完成或是否正在启动一个全新的令牌?

编辑:另一个小问题:假设我正在运行一个与绝地当前状态分离的解释器。我怎样才能提供局部和全局变量,jedi.Script以便它考虑这些,而不是它自己的完成?

4

1 回答 1

1

自动完成

Jedi 的自动补全将始终在一个地方显示所有可能的标记。这就是自动完成的重点。

如果您不想要这种行为,只需扫描最后几个字符以查找空格和某些其他字符,例如=or :,这将是一个非常简单的正则表达式命令。(您也可以尝试查看 Jedi 的内部结构并使用 Jedi 了解此上下文的方式。但是我不会告诉您,因为它不是公共 API,恕我直言,正则表达式调用就足够了。)

在未来,类似的事情可能是可能的。(见https://github.com/davidhalter/jedi/issues/253)。

现在我想了想,可能还有另一种方法可以尝试:您可以尝试使用Completion.nameand Completion.complete。后者只为您提供当前令牌之后可能出现的内容,而名称将是完整的。所以你可以比较,如果它们相等,你可能不想显示任何东西。玩得开心 API :-)

口译员

如果您正在运行解释器,则可以使用jedi.Interpreter将代码与实际的 Python 对象结合起来。它非常灵活。但请注意,当前的解释器(0.8.1)有很多错误。请使用Github (0.9.0) 的 master 分支。

于 2015-03-09T14:58:23.060 回答