15

I'm trying to override the rfce snippet in VS code but I can't seem to be able to get the filename autofilled when there's a named file. Where the file is not saved(unnamed) it should just be NameOfComponent but if the file is saved(has a name), the snippet should name the component the same as the file name but without the extension. Here's what I have so far:

"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"
}
3
  • what is the use of a file you will not save, eventually it will have a filename, so save the file and then call the snippet Commented Jan 20, 2022 at 12:32
  • there is a long and descriptive page about snippets in the VSC docs Commented Jan 20, 2022 at 13:26
  • tlde: use $TM_FILENAME_BASE Commented Jul 6, 2024 at 14:33

2 Answers 2

28

If you want to make your snippet into a template for new files see https://stackoverflow.com/a/73043147/836330. Snippet template functionality is being built in to vscode.


Presumably you have found $TM_FILENAME_BASE from vscode snippet variables documentation as the variable you need to get the file name of the current file without its extension.

Ideally what you would like to do is a choice element (see Choice doc and something like this:

"const ${1|NameOfComponent},$TM_FILENAME_BASE|}...", // does not work

That won't work because according to the snippet grammar choice options can only be text:

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

So you would have to simulate a choice as close as possible. The following snippet does that in two ways:

"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 simply lists both ${1:NameOfComponent}${2:$TM_FILENAME_BASE} presents both "options" - each will be selected in turn, just delete the one you don't want when it is selected and tab to go on. This is pretty straightforward but does require you to use the whole construction ${1:NameOfComponent}${2:$TM_FILENAME_BASE} every time you want that value.

Option 2 wraps the whole thing in another tabstop:

${1:${2:NameOfComponent}${3:$TM_FILENAME_BASE}}} which is a little trickier but then the result is put into tabstop $1 and then that is all you need to refer to when you want the result (as in the last line of the snippet).

You just have to practice a little - there is an extra tab at the start to select NameOfComponent. To accept it just tab past it to select the fileName and delete that, or vice versa - delete NameOfComponent when it is selected and tab to select the fileName - if you want it just tab to go on to the next tabstop.

The result of that inital tabstop will be put into $1 which can then be used elsewhere without the need to go through the option selection stuff again.

Here is a demo using option 2:

choice snippet demo

Sign up to request clarification or add additional context in comments.

2 Comments

Good tip! One small issue: I think you have an extra } at the end of the {$1 ... } line (notice the generated snippet shows that extra } as well).
@JasonFrank Thanks, I updated the code - might be awhile before I update the gif though...
11

You can use TM_FILENAME_BASE - The filename of the current document without its extensions

Example for a react functional typed component:

  "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 "
}

See the demo Demo for the code snippet

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.