如何在覆盖 VS Code 代码片段时获取文件名

10

我正在尝试覆盖VS code中的rfce代码段,但似乎无法在有命名文件时获得自动填充的文件名。如果文件未保存(未命名),则应为NameOfComponent,但如果文件已保存(具有名称),则代码段应将组件命名为与文件名相同但无扩展名的名称。以下是我迄今为止的代码:

"React Component": {
  "prefix": "rfce",
  "body": [
    "import React, { useState, useEffect } from \"react\";",
    "",
    "const ${1:NameOfComponent} = () => {",
    "  return (",
    "    <>",
    "       ${2:<div>Hello World</div>}",
    "    </>",
    "  );",
    "};",
    "",
    "export default ${1:NameOfComponent};"
  ],
  "description": "React Component"
}

一个不保存的文件有什么用呢?最终它都会有一个文件名,所以先保存文件,然后再调用片段。 - rioV8
VSC文档中有一篇长而详细的页面介绍了代码片段。 - rioV8
2个回答

21
如果您想将代码片段转换为新文件的模板,请参见https://dev59.com/DlUL5IYBdhLWcg3wSmYo#73043147。 vscode正在构建代码片段模板功能。
假设您已经在 vscode代码片段变量文档 中找到了$TM_FILENAME_BASE,该变量是您需要获取当前文件名称(不包括扩展名)的变量。

理想情况下,您可以使用一个 choice 元素(请参见Choice doc),类似于以下内容:

"const ${1|ComponentName, $TM_FILENAME_BASE|}...", // 不起作用

这样不行,因为根据代码片段语法,choice 选项只能是 text

choice ::= '${' int '|' text (',' text)* '|}'

因此,您必须尽可能模拟一个 choice。以下代码片段有两种方法实现了这一点:

"React Component": {
  "prefix": "rfce",
  "body": [
    "import React, { useState, useEffect } from \"react\";",
    "",

    // "const ${1:NameOfComponent}${2:$TM_FILENAME_BASE} = () => {",      // option 1 works

    "const ${1:${2:NameOfComponent}${3:$TM_FILENAME_BASE}} = () => {",  // option 2 works
    
    "  return (",
    "    <>",
    "       ${4:<div>Hello World</div>}",
    "    </>",
    "  );",
    "};",
    "",
    "export default $1;"  // uses option 2
  ],
  "description": "React Component"
}

Option 1列出了这两个选项:${1:NameOfComponent}${2:$TM_FILENAME_BASE}。它们将依次被选中,您只需在选择其中一个时删除您不想要的那个并使用tab继续即可。这很简单,但需要每次都使用整个表达式${1:NameOfComponent}${2:$TM_FILENAME_BASE}来获取该值。

Option 2将整个表达式包含在另一个tabstop中:

${1:${2:NameOfComponent}${3:$TM_FILENAME_BASE}}}。这有点棘手,但结果会放入tabstop$1中,此后您只需在需要该结果时引用它(比如代码片段的最后一行)。

您只需要多练习一下-在开始时会多按一个tab以选择NameOfComponent。只需通过tab向右移动以选择文件名并将其删除,或者反之-当选择NameOfComponent时将其删除,然后tab选择文件名-如果要使用文件名,只需tab转到下一个tabstop即可。

初始tabstop的结果将放入$1中,此后可以在其他地方使用它,而无需再次进行选项选择。

以下是使用选项2的演示:

choice snippet demo


好的提示!一个小问题:我认为在{$1 ... }行的末尾有一个额外的}(请注意生成的片段也显示了这个额外的})。 - Jason Frank
@JasonFrank 谢谢,我已经更新了代码 - 但可能要等一段时间才能更新 gif... - Mark

6

您可以使用TM_FILENAME_BASE - 当前文档的文件名(不包括扩展名)

以下是一个React函数式组件的示例:

  "create react functional component": {
"prefix": "trafce",
"body": [
  "import { FC } from \"react\"",
  "\n",
  "interface Props {\n\n}",
  "\n",
  "const $TM_FILENAME_BASE:FC<Props> = ({}) => {",
  "   return (",
  "       <div> ${1:$TM_FILENAME_BASE} </div>",
  "   )",
  "}",
  "\n",
  "export default $TM_FILENAME_BASE"
],
"description": "Create a react-typed functional component "
}

请查看演示 代码片段演示

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接