简体   繁体   English

有没有办法在某些字符之间使用 select 代码

[英]Is there a way to select code between certain characters

TL DR TL 博士

Is there some extension, or other functionality, to select code above and below the cursor that is surrounded by some characters, eg %% or % ===== or anything else?在 cursor 上方和下方的 select 代码是否有一些扩展或其他功能,这些代码被一些字符包围,例如%%% =====或其他任何字符?

Why为什么

I am coding Matlab in VSCode, since the builtin Matlab editor lacks a lot of useful functionalities.我在 VSCode 中编码 Matlab,因为内置的 Matlab 编辑器缺少很多有用的功能。 However, One thing that I miss is the ability to run 'sections':但是,我想念的一件事是运行“部分”的能力:

%% section 1
x = 0:0.01:pi;
y = sin(y);
plot(x,y);

%% section 2
x = 0:0.01:pi;
y = cos(y);
plot(x,y);

%% section 3
x = 0:0.01:pi;
y = tan(y);
plot(x,y);

A section can be run using Ctrl + Enter .可以使用Ctrl + Enter运行一个部分。 Since I use Matlab on Windows, there is no support for running the Matlab interpreter from the terminal/cmd.由于我在 Windows 上使用 Matlab,因此不支持从终端/cmd 运行 Matlab 解释器。

So I created some AutoHotKey scripts that will copy selected code, open the Matlab window, paste it, and run.所以我创建了一些 AutoHotKey 脚本,它们将复制选定的代码,打开 Matlab window,粘贴它,然后运行。 This works fine, however, when I want to run a very large section, this means that I have to select this manually, and press my defined shortcut to call the AutoHotkey script.这很好用,但是,当我想运行一个非常大的部分时,这意味着我必须手动输入 select,然后按我定义的快捷方式来调用 AutoHotkey 脚本。 Hence above question.因此上面的问题。

So say I have the cursor at some line in section 2 , how can I select only the code in this section (including or excluding section 'headers', these are comments so does not matter).所以说我在section 2的某行有 cursor,我怎么能 select 只有本节中的代码(包括或不包括“标题”节,这些是评论所以没关系)。

I have made an extension Select By that allows the selection based on regular expressions relative to the cursor position. 我做了一个扩展选择方式 ,它允许基于相对光标位置的正则表达式的选择。 You can specify different expressions for forward and backward search and if you want to include the searched text in the selection. 您可以为前进和后退搜索指定不同的表达式,以及是否要在选择中包括搜索到的文本。

You can set up to 5 regex searches. 您最多可以设置5个正则表达式搜索。

The extension defines 5 commands that can be used in keyboard shortcuts 该扩展定义了5个可在键盘快捷方式中使用的命令

This can (of course) be done by writing a custom extension. (当然)这可以通过编写自定义扩展来完成。

Since this seems like useful functionality in general and an interesting exercise, I've added the required capability to my personal vscode-smcpeak extension. 由于这通常看起来是有用的功能,而且是有趣的练习,因此,我在个人vscode-smcpeak扩展中添加了所需的功能。

To use it: 要使用它:

  1. Install vscode-smcpeak . 安装vscode-smcpeak This has to be installed manually for now. 现在必须手动安装。 At time of writing, 0.0.7 is latest. 在撰写本文时,最新值为0.0.7。
  2. Install macros by ctf0 . 通过ctf0安装 This one can be installed from within VSCode. 可以从VSCode内安装这一程序。 Restart VSCode after installing it. 安装后重新启动VSCode。 (See below regarding the choice of "macros" extension.) (有关“宏”扩展名的选择,请参见下文。)
  3. Add to your settings.json (File → Preferences → Settings, then click the "Open Settings (JSON)" icon in the upper right): 添加到您的settings.json (文件→首选项→设置,然后单击右上角的“打开设置(JSON)”图标):
    // Custom macros for ctf0.macros extension
    "macros.list": {
        // https://stackoverflow.com/questions/57749780/is-there-a-way-to-select-code-between-certain-characters
        "selectPercentRegion": [
            {
                "command": "smcpeak.goToLineMatching",
                "args": {
                    "regex": "^%%",
                    "moveUp": true,
                    "select": false,
                    "allowZeroMove": true
                }
            },
            {
                "command": "smcpeak.goToLineMatching",
                "args": {
                    "regex": "^%%",
                    "moveUp": false,
                    "select": true,
                    "allowZeroMove": false
                }
            },
            "smcpeak.revealCurrentSelection"
        ]
    },
  1. Add to keybindings.json (File → Preferences → Keyboard Shortcuts, then click the "Open Keyboard Shortcuts (JSON)" icon in the upper right): 添加到keybindings.json (文件→首选项→键盘快捷键,然后单击右上角的“打开键盘快捷键(JSON)”图标):
    {
        "key": "ctrl+alt+m",   // or whatever
        "command": "macros.selectPercentRegion"
    },

(Note: VSCode will always complain that macros.selectPercentRegion is not a valid command. That's a limitation of the "macros" extension.) (注意:VSCode始终会抱怨macros.selectPercentRegion不是有效的命令。这是对“ macros”扩展名的限制。)

Then, with the cursor within a region delimited by the specified regexes, press the keybinding to activate the macro: 然后,将光标置于由指定正则表达式分隔的区域中,按键盘上的键以激活宏:

宏调用之前和之后的屏幕截图

Why use two extensions? 为什么要使用两个扩展名?

The accepted answer , by rioV8 uses a single extension to answer the OP's question. rioV8 接受的答案使用单个扩展名来回答OP的问题。 This looks like a good solution to me, and is simpler to use than mine, so I approve of that being the accepted answer. 这对我来说似乎是一个很好的解决方案,并且比我的使用起来更简单,因此我同意将其作为可接受的答案。

However, there is an advantage to my approach: it allows the behavior to be modified in settings.json . 但是,我的方法有一个优势:它允许在settings.json修改行为​​。 For example, the OP asked in a follow-up question about having the command additionally copy the text to the clipboard after selecting. 例如,OP在后续问题中询问有关让命令在选择后将文本另外复制到剪贴板的问题。 Using the macro-based solution, this is an easy modification to settings.json ; 使用基于宏的解决方案,这是对settings.json的简单修改; simply add: 只需添加:

            "editor.action.clipboardCopyAction"

to the end of the selectPercentRegion macro. selectPercentRegion宏的末尾。 (That is the command normally bound to Ctrl+C.) (这是通常绑定到Ctrl + C的命令。)

Thus, while my suggestion has more moving parts, I personally prefer this approach. 因此,尽管我的建议涉及更多方面,但我个人更喜欢这种方法。

Which macros extension to use? 使用哪个宏扩展?

As Mark noted in a comment, the most popular macros extension, geddski.macros , is unmaintained. 正如Mark在评论中指出的那样,最受欢迎的宏扩展名geddski.macros并未维护。 It furthermore has a rather serious bug in that the commands are not properly sequenced, leading to race conditions. 此外,它还有一个相当严重的错误 ,即命令的顺序不正确,导致出现竞争状况。 (I actually saw this once during my testing.) (实际上,我在测试过程中见过一次。)

There are two forks of geddski.macros on the marketplace , l7ssha.macrosRe and ctf0.macros . 市场上有geddski.macros的两个分支,即l7ssha.macrosRectf0.macros l7ssha.macrosRe only adds the "delay" ability , which is an awkward way to resolve the race conditions. l7ssha.macrosRe仅添加了“延迟”功能 ,这是解决竞赛条件的尴尬方式。 ctf0.macros, on the other hand, fully fixes the race condition (via a complete rewrite ). 另一方面,ctf0.macros完全修复了竞争条件(通过完全重写 )。

Therefore, I recommend ctf0.macros , and in fact have edited my answer to use it rather than the original geddski.macros extension. 因此,我建议使用ctf0.macros ,并且实际上已经编辑了答案以使用它,而不是原始的geddski.macros扩展名。

However, be aware: 但是,请注意:

  • ctf0.macros uses macros.list rather than macros in settings.json ctf0.macros使用macros.list而不是settings.json macros
  • ctf0.macros requires a restart of VSCode after installation to activate ctf0.macros需要在安装后重新启动VSCode才能激活

How it works 这个怎么运作

The additions are in vscode-smcpeak commit 6d5f5d4689 . 这些附加内容在vscode-smcpeak commit 6d5f5d4689中

My extension registers a new command, smcpeak.goToLineMatching , that searches up or down for a line containing a regex. 我的扩展程序注册了一个新命令smcpeak.goToLineMatching ,该命令向上或向下搜索包含正则表达式的行。 The logic is very simple, just a loop and regex test. 逻辑非常简单,只需进行循环和正则表达式测试即可。

It also registers smcpeak.revealCurrentSelection , needed because otherwise the selected text might be offscreen and nothing scrolls to it by default. 它还会注册smcpeak.revealCurrentSelection ,这是必需的,因为否则,所选文本可能会在屏幕外,并且默认情况下不会滚动到该文本。

The macro selectPercentRegion uses goToLineMatching to look upwards for one regex, setting the anchor (selection start) there, then uses it again to look down for another regex (although they are the same here), extending the selection to that point. selectPercentRegion使用goToLineMatching向上查找一个正则表达式,在那里设置锚点(选择开始),然后再次使用它向下查找另一个正则表达式(尽管此处相同),将选择范围扩展到该点。 Then it scrolls to ensure the selection is visible. 然后滚动以确保选择可见。

It should be straightforward to transplant this code to your own extension if you don't want the rest of the stuff that mine provides. 如果您不希望我提供的其余内容,则可以直接将此代码移植到您自己的扩展中。 (But mine does not bind any keys, so there should be no downside to having the extra stuff.) (但是我没有绑定任何密钥,因此拥有多余的东西应该没有不利的影响。)

Here is another way to do this, with an extension I wrote Find and Transform .这是执行此操作的另一种方法,使用我编写的扩展名Find and Transform

Make this keybinding in your keybindings.json (or it could be a setting too):在您的键绑定中进行此键绑定keybindings.json (或者它也可以是一个设置):

{
  "key": "alt+m",                   // whatever keybinding you want
  "command": "findInCurrentFile",
  "args": {
    "find": "^(%%[\\s\\S]+?)(?=^$)|(^%%[\\s\\S]+)",
    "run": [
      "$${",
        "const sections = vscode.window.activeTextEditor.selections;",
        "await vscode.commands.executeCommand('cursorUndo');",
        
        "const mySection = sections.find(section => section.contains(vscode.window.activeTextEditor.selection));",
        "if (mySection) {",
          "vscode.window.activeTextEditor.selections = [mySection];"
        "}",
        
      "}$$",
    ],

    "isRegex": true,
    "postCommands": "editor.action.clipboardCopyAction"
  }
}

The find regex finds and selects all %%.... sections.查找正则表达式查找并选择所有%%....部分。 But since you only want the section where your cursor started, some code is run to restore that original cursor and then find that section that contains the one current cursor. Then that section is selected.但是由于您只想要 cursor 开始的部分,因此run一些代码来恢复原始 cursor,然后找到包含当前 cursor 的部分。然后选择该部分。 And in the postCommand that selection is saved to the clipboard.并在postCommand中将选择保存到剪贴板。

That is using javascript and the vscode extension api within a keybinding or setting.那是在键绑定或设置中使用 javascript 和 vscode 扩展 api。

选择光标周围的文本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM