VSCode 高级片段转换

VSCode Advanced Snippet Transform

我正在尝试创建一个根据文件路径创建 class 名称的片段。如果文件名为 index.js,我希望 class 名称采用文件夹名称。否则,使用文件名。

如果文件名为 index.js(它正确插入文件夹名称),我有一个转换(如下所示)当前正在运行。

我如何扩展这个(假设它甚至可能)也适用于第二种情况?

我确实从 VSCode documentation 中注意到,您可以使用一些基本的 if/else 格式,只有在存在捕获组时才会插入给定的文本。我已经能够让那些人使用一些简单的例子。但不确定是否可以以某种方式使用这些来完成我正在尝试做的事情。

当前片段:

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
        "class ${TM_FILEPATH/[\/\w$]+\/(?!index)|\/index.js//g} {}",
        "export default ${TM_FILEPATH/[\/\w$]+\/(?!index)|\/index.js//g};"
    ]
  },
}

@Wiktor 稍后会添加正确答案,但我想说说 vscode 的变量转换中的那些条件,因为太长而无法发表评论。

如果你能做这样的事情就太好了:

"${TM_FILEPATH/.*\(.+)\((index\.js)|(.*))/${3:?:}}/g}",

条件 if 组 3 不为空插入组 1(父目录)else 插入组 2(文件名) .但这不起作用,尽管正则表达式很好(尽管这里简化了 re: 路径分隔符和文件扩展名)。

不幸的是,虽然 "plain" 条件确实工作得很好:

${3:?There is an index.js file:There is not an index.js file}

似乎不支持在条件文本替换中使用正则表达式组。这似乎遵循语法 link(参见片段语法]1。查看有关条件的这一部分:

'${' int ':?' if ':' else '}' 

我会说不支持条件 if/else 部分中的捕获组。它似乎没有明确允许捕获组 - 仅 if/else 纯文本。

Wiktor 在评论中精通正则表达式,结合文档、Mark 的进一步见解以及一些额外的调整(正则表达式捕获组的方式 replaced/transformed,因为 VSCode转换限制),我终于能够组合出一个可行的解决方案。

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
      "class ${TM_FILEPATH/(.*[\/\\])([^\/\\]+)([\/\\]index\.[jt]s$)|(.*[\/\\])(.*)(\.[jt]s)//} {}",
      "export default ${TM_FILEPATH/(.*[\/\\])([^\/\\]+)([\/\\]index\.[jt]s$)|(.*[\/\\])(.*)(\.[jt]s)//};"
    ]
  }
}

我建议使用

${TM_FILEPATH/.*[\/\\]([^\/\\]+)[\/\\]index\.js$|.*[\/\\](.*)//}

如果您不想在输出中包含文件扩展名,请使用

${TM_FILEPATH/.*[\/\\]([^\/\\]+)[\/\\]index\.js$|.*[\/\\](.*?)(?:\.[^.]*)$//}

正则表达式 #1 可以工作 as shown here or regex #2 here, see its graph:

这里的重点是使用两个用 | 交替运算符分隔的替代方案,它们将匹配 整个 字符串,同时 捕获 您需要的部分,确保更具体(具有已知文件名)的替代方案排在第一位,而更通用的(将匹配 any 文件名,将排在最后。替换pattern 将是两个反向引用,</code>,因为在找到匹配后只有一个会实际包含一些文本。</p> <p><strong>正则表达式详细信息</strong></p> <p>请注意反斜杠加倍,因为模式作为字符串文字传递,并且 <code>/ 个字符必须转义,因为字符串文字包含 "stringified" 正则表达式文字。

  • .*[\/\]([^\/\]+)[\/\]index\.js$:
    • .* - 除换行字符外的任何 0+ 个字符,尽可能多
    • [\/\] - 一个 /\
    • ([^\/\]+) - 捕获第 1 组:除 /\ 之外的一个或多个 (+) 个字符([^...] 是否定字符 class)
    • [\/\] - 一个 /\
    • index\.js - index.js 子串
    • $ - 字符串结尾
  • | - 或
  • .*[\/\](.*):
    • .* - 除换行字符外的任何 0+ 个字符,尽可能多
    • [\/\] - 一个 /\
    • (.*) - 捕获第 2 组:除换行字符外的任何 0+ 个字符,尽可能多
    • (.*?)(?:\.[^.]*)?$ - 将尽可能少地捕获除换行符以外的任何 0 个或更多字符,然后尝试匹配 . 和 0+ 的可选序列non-dot 个字符到字符串末尾 ($)。

因此,完整的代码片段将如下所示

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
      "class ${TM_FILEPATH/.*[\/\\]([^\/\\]+)[\/\\]index\.js$|.*[\/\\](.*?)(?:\.[^.]*)$//} {}",
      "export default ${TM_FILEPATH/.*[\/\\]([^\/\\]+)[\/\\]index\.js$|.*[\/\\](.*?)(?:\.[^.]*)$//};"
    ]
  }
}

您可以随意调整。