制作一个sublime text 3宏来评估一行然后将光标移动到下一行

Making a sublime text 3 macro to evaluate a line and then move the cursor to the next line

我心爱的gedit R plugin is no longer maintained, and the forced downgrade solution上次更新ubuntu时突然停止工作了。写作已经有一段时间了,我正在探索 sublime text。我已经安装了 REPL 用于将代码发送到命令行,并且我正在尝试像我习惯的那样设置键绑定。

特别是,我试图让 CTRL+SHIFT+R 向控制台发送一行代码,运行s 它,然后将编辑器中的光标向下移动到下一行。这样我就可以多次按 CTRL+SHIFT+R 逐行 运行 一个脚本。 (这类似于 Rstudio 使用 CTRL+Enter 的行为)

谷歌搜索,我找到了这个(旧)solution。它不起作用,可能是因为它是为 sublime text 2 编写的。更多谷歌搜索,我想出了如何让它几乎起作用:

//This is a macro for evaluate and move down
[
 {"command": "repl_transfer_current", "args": {"scope": "lines"}}
// {"command": "move", "args": {"mode": "lines", "amount": 1}}
]

这是我添加到默认键盘映射的内容:

{ "keys": ["ctrl+shift+r"], "command": "run_macro_file", "args": {"file": "Packages/User/geditlike_lineeval.sublime-macro"}}

如上所示,sublime text 将我的代码行发送到终端并 运行 发送它。第二行本应向下发送光标,但它不起作用,当我取消注释时宏失败。

我似乎找不到很多关于 sublime text 命令的文档。 Here 是我能找到的最好的 move。我的语法错了吗?我怎样才能使这项工作?

奖励:我怎样才能使 sublime text 运行 成为行,然后跳到下一个 non-emptynon-commented 行。这似乎更难——我看到很多键绑定都涉及正则表达式等。

编辑 我的问题是我缺少 JSON 行之间的逗号。 github 页面上链接的代码确实有效,如果你在两行之间添加一个逗号。

您链接到的解决方案应该在 Sublime 2 和 3 中都有效(假设提供 repl_transfer_current 命令的插件对两者都有效),但由于宏格式不正确而无效。

[Edit] The move command provided natively by Sublime doesn't take the arguments your Macro is using. Presumably that's something that is also being provided by some package if this works for you. If so, you may need to adjust the sample code below accordingly. [/Edit]

就目前而言,问题是 Sublime 中的几乎(但不是全部)配置文件都是 JSON 格式(稍微放宽以允许评论),以及上面概述的宏代码和链接解决方案无效 JSON 因为其中的第一条和第二条命令没有用逗号分隔。

像下面这样的东西应该可以工作:

[
   {"command": "repl_transfer_current", "args": {"scope": "lines"}},
   {"command": "move", "args": {"mode": "lines", "amount": 1}}
]

我认为您在上面链接到的 Sublime 文档是针对 Sublime 2 的。一个很好的资源是 Unofficial Documentation, which also contains a list of commands(还有很多其他好东西)。

为了做这样的事情并让它继续向下移动直到到达第一个非空白、非注释行,您需要一个简单的插件

具体来说,它必须将光标向下移动(使用现有的 move 命令),然后检查当前行以查看它是否为空白或注释,如果是则再次移动。然后,您可以使用该命令代替宏中的 move 命令。


为了加分,这里有一个插件的例子,它可以做这样的事情。它比需要的更冗长,因此更具指导意义,并且可能需要额外的调整(R 不是我使用的语言之一 use/know),但它应该可以帮助您入门。

有关其工作原理的更多信息,您可以查看 API Reference 以查看可以在插件中使用的所有内部命令。

要使用它,从菜单中 select Tools > Developer > New Plugin...,然后用此处显示的插件代码替换显示的全部存根代码,并用 .py 保存它扩展名(名称不重要):

import sublime
import sublime_plugin
import re

# A regex that matches a line that's blank or contains a comment.
# Adjust as needed
_r_blank = re.compile("^\s*(#.*)?$")

class RAdvanceNextCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # Get the count of lines in the buffer so we know when to stop
        last_line = self.line_at(self.view.size())

        while True:
            # Move to the next line
            self.view.run_command("move", {"by": "lines", "forward": True})

            # Get the current cursor position in the file
            caret = self.view.sel()[0].begin()

            # Get the new current line number
            cur_line = self.line_at(caret)

            # Get the contents of the current line
            content = self.view.substr(self.view.line(caret))

            # If the current line is the last line, or the contents of
            # the current line does not match the regex, break out now.
            if cur_line == last_line or not _r_blank.match(content):
                break

        # Jump to the start of the line
        self.view.run_command("move_to", {"to": "bol"})

    # Convert a 0 based offset into the file into a 0 based line in
    # the file.
    def line_at(self, point):
        return self.view.rowcol(point)[0]

这实现了一个名为 r_advance_next 的新命令,它将光标向下移动到文件中,跳过全白的行 space 或包含行注释(假设我的正则表达式符合要求).

有了这个,您的宏将如下所示:

[
    {"command": "repl_transfer_current", "args": {"scope": "lines"}},
    {"command": "r_advance_next"}
]

此外,您可以使用如下所示的键绑定。由于您使用 Control+Enter 提到 RStudio,这就是我在这里使用的。此绑定应用了上下文,因此它仅在当前文件为 R 文件时适用,因此在不合适时不会触发。

{ "keys": ["ctrl+enter"], "command": "run_macro_file",
  "args": {"file": "Packages/User/geditlike_lineeval.sublime-macro"},
  "context": [
    { "key": "selector", "operator": "equal", "operand": "source.r"}
  ]
}

对于 BONUS 奖励标记,您可以直接从此处提供的插件命令中 运行 repl_transfer_current 命令,在这种情况下您不需要根本不需要使用宏,您只需将密钥直接绑定到插件中的命令即可。在这种情况下,您可能希望以不同的方式命名 class(例如 RTransferAndAdvanceCommand 或类似的名称),以便命令名称更有意义。