つれづれなるままに

雑多にやります

VSCodeのスニペットについて

VS Code拡張機能開発の練習でC++スニペット拡張機能として作成して去年あたりに公開した。

marketplace.visualstudio.com

標準のC++拡張でもスニペットは入っているけど足りない部分を補う感じで作成しているつもり。

作成する中でスニペットの便利機能を調べたのでまとめてみる。

便利機能

もしも拡張機能でなく自分独自にスニペットを作成したいならこんな便利な機能があるよというのを何選か。

ファイル名やフォルダ名、現在の月日、乱数、UUID、選択範囲、クリップボードなどは変数で定義されている。

変数は初期値として使用したり正規表現で置換して使用することが可能です。

変数一覧→Snippets in Visual Studio Code

変数一覧に記載がありませんがタブストップの内容も変数となります。
変数名としてはタブストップのインデックスです(タブストップが$1なら変数名は1です)

変数を正規表現で置換する際に大文字、小文字などに変換可能。

正規表現の構文は以下の通り。

${変数/正規表現/フォーマット文字列/正規表現オプション}

正規表現で置換後のフォーマット文字列でマッチした内容を$1などで参照できる。
その$1${1:/upcase}などで大文字にしたり小文字にしたりすることが可能。

使えるオプションは以下の通り

  • /upcase 大文字に変更
  • /downcase 小文字に変更
  • /capitalize キャピタライズに変換(先頭のみ大文字)
  • /camelcase キャメルケースに変換(先頭は小文字で文字の区切りの頭だけ大文字)
  • /pascalcase パスカルケースに変換(先頭および区切りの頭だけ大文字)

※仕様が記載されていないので/capitalize/camelcase、/pascalcase`がどこを区切り文字と判断するか不明

同じインデックスのタブストップの内容は同期される。

複数の同じインデックスのタブストップの内容は最初の一つだけ設定すればOK。

//C++ include guards
//ファイル名を大文字に変換

//before
#ifndef ${1:${TM_FILENAME/(?:(\\w+)(\\.)?)/${1:/upcase}${2:+_}/gi}}
#define ${1:${TM_FILENAME/(?:(\\w+)(\\.)?)/${1:/upcase}${2:+_}/gi}}
$0
#endif // ${1:${TM_FILENAME/(?:(\\w+)(\\.)?)/${1:/upcase}${2:+_}/gi}}

//after
#ifndef ${1:${TM_FILENAME/(?:(\\w+)(\\.)?)/${1:/upcase}${2:+_}/gi}}
#define $1
$0
#endif // $1

ショートカットキーから呼び出せる。

Snippets in Visual Studio Code

//keybindings.json内に直接スニペットを記載する
{
  "key": "cmd+k 1",
  "command": "editor.action.insertSnippet",
  "when": "editorTextFocus",
  "args": {
    "snippet": "console.log($1)$0"
  }
}

//keybindings.jsonから登録したスニペットを呼び出す。
{
  "key": "cmd+k 1",
  "command": "editor.action.insertSnippet",
  "when": "editorTextFocus",
  "args": {
    "langId": "csharp",
    "name": "myFavSnippet"
  }
}

選択範囲を変換するスニペットの場合はこの方法か、コマンドパレットからスニペットを挿入を選択するしか方法がありません。

不満点

設定ファイルが存在しない。設定ファイルで変数とか定義できるともっと便利になるのにと思う。

追記

VSCodeの公式ページのスニペットの変数一覧でVer1.66で追加された変数CURSOR_INDEXCURSOR_NUMBERが2022/06/21段階でなぜかまだ追加されていない。

Snippets in Visual Studio Code
Visual Studio Code March 2022