【问题标题】:Making a sublime text 3 macro to evaluate a line and then move the cursor to the next line制作一个 sublime text 3 宏来评估一行,然后将光标移动到下一行
【发布时间】:2023-03-19 10:43:01
【问题描述】:

我心爱的gedit R pluginno longer maintained,而我上次更新ubuntu时一直使用的强制downgrade solution突然停止工作。文字已经挂在墙上有一段时间了,我正在探索崇高的文字。我已经安装了 REPL 用于将代码发送到命令行,并且我正在尝试像我习惯的那样设置键绑定。

特别是,我试图让 CTRL+SHIFT+R 向控制台发送一行代码,运行它,然后将编辑器中的光标向下移动到下一行。这样我可以多次按 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。我的语法错了吗?我怎样才能做到这一点?

BONUS:如何让 sublime text 运行该行,然后跳到下一个 non-emptynon-commented 行。这似乎更难——我看到很多键绑定都涉及正则表达式等。

编辑 我的问题是我错过了 JSON 行之间的逗号。如果您在两行之间添加逗号,则该 github 页面上链接的代码确实有效。

【问题讨论】:

    标签: json r macros sublimetext3 sublimerepl


    【解决方案1】:

    您链接到的解决方案应该在 Sublime 2 和 3 中都可以使用(假设提供 repl_transfer_current 命令的插件适用于两者),但由于宏格式不正确而无法正常工作。

    [编辑] Sublime 原生提供的move 命令不采用您的宏正在使用的参数。如果这对您有用,大概也是某些软件包提供的东西。如果是这样,您可能需要相应地调整下面的示例代码。 [/编辑]

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

    类似下面的东西应该可以工作:

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

    我认为您上面链接到的 Sublime 文档适用于 Sublime 2。一个很好的资源是 Unofficial Documentation,它还包含一个 list of commands(以及许多其他好东西)。

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

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


    对于加分,这里有一个插件的例子,它可以做这样的事情。它比它需要的更冗长,因此更具指导性,并且可能需要额外的调整(R 不是我使用/知道的语言之一),但它应该让你开始。

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

    要使用它,请从菜单中选择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 的新命令,该命令在文件中向下移动光标,跳过完全为空白或包含行注释的行(假设我的正则表达式符合标准)。

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

    [
        {"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 命令,在这种情况下,您根本不需要使用宏,您只需将密钥直接绑定到插件中的命令。在这种情况下,您可能希望以不同的方式命名该类(例如 RTransferAndAdvanceCommand 或类似名称),以便命令名称更有意义。

    【讨论】:

    • 是的,是逗号。第一次使用 JSON。鉴于 JSON 基本上没有作为一种语言的功能(根据我收集的内容),我如何编写一个涉及 whileregex 的小程序——似乎是我需要实现你建议的工具?
    • Sublime 中的插件是用 Python 编写的(只是配置的东西是 JSON,不包括一些与 TextMate 兼容的 XML 格式文件)。我可以提供一个简单的例子(目前不在电脑上)。
    • 示例插件和用法已添加到我的答案中。
    • 非常感谢。我一直想学习一些基本的python,所以调整你的代码来完成这项工作将是一个很好的练习。
    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2016-05-29
    • 2013-07-25
    相关资源
    最近更新 更多