显示评估选定内容的输出 - Sublime Text Python REPL

2 投票
1 回答
1631 浏览
提问于 2025-04-18 03:00

我在使用Sublime Text 3,并且我的操作系统是OSX Mavericks。我正在使用Sublime REPL这个插件,并且我调整了这个插件的设置,让它可以显示传输的文本,也就是设置了“show_transferred_text” : true。

当我打开一个Python REPL窗口时,我可以通过按Ctrl + , , s把编辑器里的代码发送到这个窗口去执行。这听起来不错,但有个问题就是,除非我在代码里加上print命令,否则我看不到任何输出。例如,如果我写了以下代码:

x = 2.5

type(x)

然后用Ctrl +, , s把它发送去执行,我能看到这些命令被显示出来,但我却看不到type(x)的输出。要是我把这些命令复制粘贴到Mac的终端里的Python解释器中,就能看到输出了。

请问有没有办法在Sublime Text里实现这个功能呢?

1 个回答

5

[更新]

下面的代码已经不再使用了。如果想要最新、效果更好的版本,请访问这个插件的链接:https://gist.github.com/dantonnoriega/46c40275a93bab74cff6

欢迎大家进行分叉和点赞。我会在代码更新时把变化添加到这个链接中。不过,为了保持最新,建议关注这个仓库:https://github.com/dantonnoriega/sublime_text_plugins/blob/master/python_blocks_for_repl.py

***************

我想要实现相同的功能。我找到的解决方案是把以下几个帖子结合起来的结果:

https://stackoverflow.com/a/14091739/3987905

在sublime text 2中可以链式调用键绑定命令吗?

如何在sublime text 2编辑器中将一行传递到控制台

创建插件

这个插件需要你在同一个窗口中打开REPL,但要作为一个单独的组。我是通过上面第一个链接学会的。为了发送你想要的文本并执行它,我借鉴了上面第二个链接的思路,写了以下插件(工具 -> 新建插件...)

class ReplViewAndExecute(sublime_plugin.TextCommand):
    def run(self, edit):
        v = self.view
        ex_id = v.scope_name(0).split(" ")[0].split(".", 1)[1]
        lines = v.lines(self.view.sel()[0]) # get the region, ordered
        last_point = v.line(self.view.sel()[0]).b # get last point (must use v.line)
        last_line = v.line(last_point) # get region of last line

        for line in lines:
            self.view.sel().clear() # clear selection
            self.view.sel().add(line) # add the first region/line
            text = v.substr(line)
            print('%s' % text) # prints in console (ctrl+`)

            if not line.empty() and text[0] != '#': # ignore empty lines or comments
                v.window().run_command('focus_group', {"group": 1}) # focus REPL
                v.window().active_view().run_command("insert",
                    {"characters": text})
                v.window().run_command('repl_enter')

        # if the last line was empty, hit return
        # else, move the cursor down. check if empty, hit return once more
        if last_line.empty():
            self.view.sel().clear()
            self.view.sel().add(last_line)
            v.window().run_command('focus_group', {"group": 1}) # focus REPL
            v.window().run_command('repl_enter')
            v.window().run_command('focus_group', {"group": 0})
            v.window().run_command('move', {
                "by": "lines",
                "forward": True,
                "extend": False
            })
        else:
            v.window().run_command('focus_group', {"group": 0})
            v.window().run_command('move', {
                "by": "lines",
                "forward": True,
                "extend": False
            })
            if self.empty_space():
                v.window().run_command('focus_group', {"group": 1}) # focus REPL
                v.window().run_command('repl_enter')

        # move through empty space
        while self.empty_space() and self.eof():
            v.window().run_command('focus_group', {"group": 0})
            v.window().run_command('move', {
                "by": "lines",
                "forward": True,
                "extend": False
            })
    def eof(self):
        v = self.view
        s = v.sel()
        return True if v.line(s[0]).b < v.size() else False

    def empty_space(self):
        v = self.view
        s = v.sel()
        return True if v.line(s[0]).empty() else False

上面的代码会把选中的行发送到REPL,聚焦到REPL所在的组,执行REPL(也就是按下“回车”),然后再回到代码窗口。

这个插件现在会自动把光标移动到下一行,这样你可以快速评估代码。如果下一行是空的,插件会自动继续按“回车”,直到遇到非空行。对我来说,这一点非常重要,因为如果我选中一个Python函数块,我还得切换到REPL并按“回车”才能完成函数的执行。这个循环部分解决了这个问题。

使用插件

要运行这个插件,我在我的用户键绑定中添加了以下内容(这是我从上面第三个链接学到的)...

    //REPL send and evaluate
    { "keys": ["super+enter"], "command": "repl_view_and_execute"}

这样就应该可以工作了!

总结

记住,你需要:

  1. 把sublimeREPL放在同一个窗口中,但要在一个单独的组里(可以参考第一个链接快速使用pydev插件来做到这一点)。
  2. 创建'repl_view_and_execute'插件并绑定它。

如果有人知道如何制作一个更优雅的版本,可以在活动窗口和REPL视图之间切换(就像在另一个窗口中一样),我非常欢迎建议。我尝试过sublimerepl.py,但没弄明白如何使用所有的active_window()等命令。

撰写回答