首页 > 解决方案 > vscode中的未命名/超薄片段

问题描述

我正在使用 vscode 编辑乳胶(使用乳胶工作室插件),我最近开始创建自己的片段并且非常喜欢该功能。但是,我发现创建“小”片段的语法有点重,这些片段只是缩写频繁的单词序列。特别是,我发现必须为每个片段命名一个“名称”很麻烦。

是否有“苗条”片段/别名的机制,例如将一个文件作为输入,其中每个片段都是一行——第一个单词是缩写,其余的是缩写?

标签: visual-studio-codelatexcode-snippets

解决方案


你有几个选择。一种是编写一个可以做到这一点的扩展——我将展示像一个可以工作的扩展一样工作的代码——它看起来很复杂,但使用起来非常简单。

其次,您可以使用Hyper Snips扩展来接近,您的片段文件(比如latex.hsnips)可能像这样:

snippet dategreeting "Gives you the current date!"
Hello from your hsnip on ``rv = new Date().toDateString()``!
endsnippet

snippet // "Fraction simple" A
\frac{$1}{$2}$0
endsnippet

snippet stte A
some text to expand
endsnippet

"" 中的描述不是必需的,我在最后一个片段中删除了它。该A标志将立即插入您的替换文本,没有它您将Tab插入替换文本。正如此处的示例所示,您可以根据需要在代码段中使用 javascript。

gif 不太清楚,这里是一个使用 Hyper Snips 进行自动扩展的演示:

简单的片段演示 1


或者,下载扩展宏命令。它允许您在设置中的宏中使用 vscode 扩展命令。此宏将进入您的settings.json文件:

"macros": {

  "slimSnippetsInsertion" : [
    { 
      "javascript": [

        "const editor = vscode.window.activeTextEditor;",
        "const document = editor.document;",
        "const we = new vscode.WorkspaceEdit();",
      
        "const cursorPosition = editor.selection.active;",   // use whether an actual selection or not, returns a Position
        "let keyWordRange = document.getWordRangeAtPosition(cursorPosition);",  // returns a Range of start/end Positions or undefined
        "if (keyWordRange === undefined) {",
          "await window.showInformationMessage(`cursor must be in or immediately after word to be replaced`);",
          "return;",
        "}",

        "let wordAtCursor = document.getText(keyWordRange);",  // this is the key word to find in slimSnippets.txt

        "const thisWorkspace = vscode.workspace.workspaceFolders[0].uri.toString();",
                // file:///c:/Users/Mark/OneDrive/Test Bed

        "const snippetFileContent = await vscode.workspace.fs.readFile(vscode.Uri.parse(`${thisWorkspace}/.vscode/slimSnippets.txt`));",

        "const snippets = snippetFileContent.toString();",

                    // ignore leading spaces/tabs before keys
                    // using a named capturing group for the replacement text
        "const regex = new RegExp(`\\r?(?<=\\n|^)[\\t ]*(?<key>${wordAtCursor})[\\t ]+?(?<replacementText>.*?)(?=\\r?\\n|$)`);",

        "let found = snippets.match(regex);",  // returns null if no matches

        // matched a key but only spaces as replacement text, so do nothing and exit
        "if (found && found.groups.replacementText.trimStart().length === 0) {",
          "await window.showInformationMessage(`replacement text is only spaces, not replacing`);",
          "return;",
        "}",

        "if (found) {",                      // found at least a matching key
          "if (found.groups.replacementText) {",  // found non-space replacement text

            // replace `\n` and `\t` with unicode values for newline and tab
            "let replace = found.groups.replacementText.replace(/\\\\n/g, '\\u000A').replace(/\\\\t/g, '\\u0009');",
            "let snippet = new vscode.SnippetString(replace)",

            "if (editor.selections.length === 1) editor.insertSnippet(snippet, keyWordRange);",  // if zero or one selection"
                 // if multiple selections, uses first key and replacement text"
            "else editor.insertSnippet(snippet);",
          "}",
          "else await window.showInformationMessage(`matching key found but with no replacement text in slimSnippets.txt`);",
        "}",
        "else await window.showInformationMessage(`no matching key found in slimSnippets.txt`);",
    ]
}

您可以看到我在哪里读取simpleSnippets.txt位于.vscode工作区文件夹中的文件 - 但只要您更改命令中的路径信息,您就可以更改位置:vscode.workspace.fs.readFile上面。

slimSnippets.txt文件只是一个简单的文本文件,其中每行中的第一个单词是 the key,而该行的其余部分是替换。

howdy1 $1 first $2 sentence with tabstops
howdy1 this won't be used, duplicate key above

howdy2 second sentence with variable $TM_FILENAME

key3    videos 111111    // one space necessary between key and replacement text
                     //     it will be removed, others retained
key1 222222

stte some text to expand
mt2e more text to expand


  [replacement text can have placeholders, tabstops and choices just like regular snippets]

  [join multiple-lines snippets into one string with newlines as below]
  [some text\nsome more text] [\t can be used for tabs]

 key5 line 1\n\tline 2\n\t\tline 3

键是单个单词,如果没有替换文本(或者文件中键后只有空格),则不会发生任何事情 - 不会替换键。

实际插入的文本可以是纯文本,也可以使用 vscode 的代码片段格式——参见上面的示例文本文件。

带有片段的宏演示

光标必须紧跟在单词之后或单词中,并且可以选择或不选择该单词。它必须是正则表达式意义上的单词 - 不是在它之前或之后与单词相邻的连续文本 - 只是一个独立的单词,它可以在行中的任何位置。

如果您有重复的键,将使用第一个键。键/替换行之间可以有空行空格。

你不会得到钥匙的智能感知。我可能会在这方面工作。

最后,您将需要一个键绑定来触发此宏(在 中keybindings.json):

{
  "key": "ctrl+;",             // whatever keybinding you wish
  "command": "macros.slimSnippetsInsertion"
},

推荐阅读