首页 > 解决方案 > 保留反向“拆分为行”命令的选择

问题描述

如果您选择几行文本并按 Ctrl-Shilf-L(或 Menu > Selection > Split into Lines),您将看到每行末尾都有多光标。

这是试图完成类似任务的插件,但现在光标应该位于行首。

这个插件可以工作,但我想稍微改进一下——它应该保留选择,就像默认的 Ctrl-Shift-L 行为一样。

import sublime_plugin

class SplitIntoLinesReverseCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.run_command("split_selection_into_lines")
        # Seems to be redundant:
        # self.view.run_command("expand_selection", {"to": "line"})
        self.view.run_command("move", {"by": "characters", "forward": False})
        # Already tried this:
        # self.view.run_command("move", {"by": "characters", "forward": False, "extend": True})

测试文本:

foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar
baz baz baz baz baz baz baz baz baz baz baz baz baz baz baz baz

标签: sublimetext3sublimetext2sublimetextsublime-text-plugin

解决方案


听起来你想要这样的东西:

import sublime_plugin

class SplitIntoLinesReverseCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.run_command("split_selection_into_lines")
        self.view.run_command("move", {"by": "characters", "forward": True})
        self.view.run_command("move_to", {"to": "bol", "extend": True})

这里的步骤是:

  1. 使用现有命令将选择拆分为行
    • 这会使光标在行尾选中每一行
  2. 将光标向前移动一个字符
    • 当有选定的文本时,将光标向前或向后移动一个字符会将插入符号移动到选择的那一端并删除选择;这会在行尾留下插入符号并删除选择。
  3. 将光标移动到行首,扩大选择范围
    • 这会将光标放在您希望它所在的位置并将选择放回原处。

还有其他方法可以通过直接操作选择来做同样的事情,但是在现有命令的基础上构建通常更容易和更快,就像这里所做的那样。


如果您启用了自动换行并且选择中的任何行都自动换行,上述解决方案将无法按预期工作。这是因为当换行时,用于跳转到行首和行尾的移动命令将跳到插入符号所在行的逻辑(视觉)结束,而不是行的物理开始和结束。

为了在自动换行的情况下工作,您需要考虑到这一点。同样,这可以通过手动修改选择来实现,但更简单的方法是在命令期间暂时关闭自动换行,以便移动按预期工作:

import sublime_plugin

class SplitIntoLinesReverseCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # Save the state of word wrap and ensure that it's turned off
        word_wrap = self.view.settings().get("word_wrap", None)
        self.view.settings().set("word_wrap", False)

        self.view.run_command("split_selection_into_lines")
        self.view.run_command("move", {"by": "characters", "forward": True})
        self.view.run_command("move_to", {"to": "bol", "extend": True})

        # Replace the setting as long as it existed.
        if word_wrap is not None:
            self.view.settings().set("word_wrap", word_wrap)

推荐阅读