Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kematzy/9848f676b944c75ec4f91fe4abd9322c to your computer and use it in GitHub Desktop.
Save kematzy/9848f676b944c75ec4f91fe4abd9322c to your computer and use it in GitHub Desktop.
VS Code Snippets Placeholder Transformations Tutorial

VS Code Snippets Placeholder Transformations

This is a quick tutorial on how to create VS Code snippets that formats your snippet placeholder variables correctly.

Hopefully Google will show this in the search results so that others that are struggling in this area can be helped.



Understanding the problem

To generate the following example code from a VS Code snippet:

public function index()
{
    $users = User::all();

    return view('users.index', $users);
}

The VS Code snippet should be as follows:

"Example Snippet": {
  "prefix": "model-index",
  "body": [
    "public function index()",
    "{",
    "    \\$${1:modelname}s = ${1/(.*)/${1:/capitalize}/}::all();",
    "",
    "    return view('$1s.index', \\$$1s);",
    "}"
  ],
  "description": "Example Snippet"
}


Understanding the usage of the snippet

When you insert that snippet in to your VS Code document, the $1 placeholder will show the default placeholder contents modelname at all the snippet variable locations. ie:

public function index()
{
    $[modelname]s = [modelname]::all();

    return view('[modelname]s.index', $[modelname]s);
}

When you replace modelname with your class name (user) the snippet variables are updated accordingly.

When you press the tab key then the User is formatted.

That's important to understand. The formatting of a snippet placeholder transformation happens on the first tab after the placeholder variable was updated.



The key part of the snippet placeholder transformation

The key part of the above VS Code snippet is:

${1/(.*)/${1:/capitalize}/}


Understanding the ${1/(.*)/${1:/capitalize}/} part fully

The above key part snippet basically works like this:

<outer-snippet-variable>
  <variable-id>
  <regexp>
    <look-for>
    <replace-with>
      <new-snippet-variable>
        <variable-id>
        <placeholder>
      </new-snippet-variable>
    </replace-with>
  </regexp>
</outer-snippet-variable>
${
  1
  /
    (.*)
  /
    ${1:/capitalize}     #  1 refers to the first regexp capture ie: (.*)
  /
}


AVOID THE MAJOR GOTCHA: A more complex example

Transformations before your first placeholder variable, requires the first placeholder variable to be a higher number, such as ${3:modelname}, or else the snippet will not work.

The reason for this, is the embedded snippet in the transformation regular expression, ie: ${1:/capitalize} that is embedded in the ${3/(.*)/${1:/capitalize}/}

/**
 * Store a newly created resource in storage.
 *
 * @param \Illuminate\Http\Request $request
 * @param \App\Models\User $user
 * @return \Illuminate\Http\Response
 */
public function store(Request $request, User $user)
{
    $request->validate([",
        'name' => ['required', 'string', 'max:255'],",
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],",
    ]);",

    $user->create($request->all());  // NOTE: Security Risk: Mass Assignment of request data",

    return Redirect::route('users.index')->with('success', 'User successfully created');",
}

To generate the above code, the VS Code snippet should be as follows:

"Complex Example Snippet": {
  "prefix": "model-store",
  "body": [
  	"/**",
  	" * Store a newly created resource in storage.",
  	" *",
  	" * @param \\Illuminate\\Http\\Request \\$request",
  	" * @param  \\App\\Models\\\\${3/(.*)/${1:/capitalize}/} \\$${3:modelname}",
  	" * @return \\Illuminate\\Http\\Response",
  	" */",
    "public function store(Request \\$request, ${3/(.*)/${1:/capitalize}/} \\$$3)",
    "{",
    "  \\$request->validate([",
    "      'name' => ['required', 'string', 'max:255'],",
    "      'email' => ['required', 'string', 'email', 'max:255', 'unique:$3s'],",
    "  ]);",
    "",
    "  \\$$3->create(\\$request->all());  // NOTE: Security Risk: Mass Assignment",
    "",
    "  return Redirect::route('$3s.index')->with('success', '${3/(.*)/${1:/capitalize}/} successfully created');",
    "}"
  ],
  "description": "Complex Example Snippet"
}


Conclusion

I hope the above guide will enable you to create better VS Code snippets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment