显示评估选定内容的输出 - Sublime Text Python REPL
我在使用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 个回答
[更新]
下面的代码已经不再使用了。如果想要最新、效果更好的版本,请访问这个插件的链接: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编辑器中将一行传递到控制台
创建插件
这个插件需要你在同一个窗口中打开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"}
这样就应该可以工作了!
总结
记住,你需要:
- 把sublimeREPL放在同一个窗口中,但要在一个单独的组里(可以参考第一个链接快速使用
pydev
插件来做到这一点)。 - 创建
'repl_view_and_execute'
插件并绑定它。
如果有人知道如何制作一个更优雅的版本,可以在活动窗口和REPL视图之间切换(就像在另一个窗口中一样),我非常欢迎建议。我尝试过sublimerepl.py
,但没弄明白如何使用所有的active_window()
等命令。