VSCodeでスニペットを作成する
VSCodeでよく使う文があるならスニペットを使用するのが便利です。
標準で用意されていたり拡張機能をインストールすることで使用できますが、
ユーザー独自でもスニペットを作成できるのでそれについての説明をしていきます。
スニペットファイルを用意する。
VSCode左下の歯車アイコンからユーザースニペットを選択し、スニペットを登録したい言語のjsonファイルを選択すると初期では以下のようなファイルが開かれます。
{
// Place your snippets for cpp here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
// "Print to console": {
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}
サンプルも記載あるのでサンプルのコメントを外して実際のファイルでどんなふうに動くか確認してみます。
{
"Print to console": {
"prefix": "log",
"body": [
"console.log('$1');",
"$2"
],
"description": "Log output to console"
}
}
コメントアウトして保存しjavascriptのファイルでlogと入力しtabキーを押せば以下のようになります。
console.log('');
また展開後のカーソルの位置はjsonファイルで記入した$1の位置に移動します。
文字入力後tabキーを押せば$2の位置に移動します。
スニペットが便利なのはテンプレート文を入力するだけでなく入力位置にカーソルが移動してくれたり、ファイル名や日付を変数を利用して入力したり、正規表現を利用して文字列を加工したりできることです。
構文
"スニペット名":{
"prefix": "短縮語", // 複数の場合は["a", "b"]のように入力
"body": "展開するコード", // 複数行に展開したい場合は["1行目", "2行目", "3行目"...]
"description": "説明文" // オプション。なくても構わない。
}
スニペット名は一意の名称を設定します。
サンプルと見比べてみればわかりやすいかもしれません。
スニペットや短縮語、説明文はとくに説明することはありません。
短縮語は複数登録することができるくらいです。
展開するコードについていろいろ機能があるので説明していきます。
基本的な展開
大体のスニペットは基本的な展開でこと足ります。
サンプルを少し改造して以下のようにしてみます。
"Print to console2": {
"prefix": "log2",
"body": [
"console.log('$1');",
"console.log('$2');",
"$0"
],
"description": "2回ログを表示する"
}
$1,$2はスニペット展開後のカーソルの位置です。
$1の位置で入力後、またtabを押せば次の$2に移動します。
$0は特別で一番最後の位置となります。
この$Nのことをタブストップといいます。
タブストップについて
タブストップについて機能がいろいろついています。
デフォルト値や選択肢、ファイル名などの変数、正規表現などです。
プレースホルダー
タブストップにはデフォルト値を設定することができます。
${N:デフォルト値}のように記載します。
"for loop":{
"prefix": "for2",
"body": [
"for(${1: size_t} ${2: index} = 0; $2 < ${3: size}; ++$2){",
" $0"
"}"
],
"description": "C++のforループ"
}
上記サンプルで$2が複数あることに気づいたでしょうか?
タブストップは同じ番号が複数あってもかまいません。
また最初の$2だけデフォルト値のindexを記載していますが、展開した場合残りの$2もデフォルト値のindexが入力されています。
//for2 -> tab
for( size_t index = 0; index < size; ++ index){
}
選択肢
タブストップは選択肢から選ぶ形にすることも可能です。
${N|option1,option2,...optionN|}のように記載します。
"tmplate class": {
"prefix": "tmpc",
"body": [
"template<${1|typename, class|} T>",
"class ${2:tmp_class}{",
" $0",
"};"
]
},

展開例
変数
ファイル名や現在の日付を入力したい場合変数を使用することも可能です。
$変数名のように記載します。
変数名一覧は以下のようになります。
-
TM_SELECTED_TEXT現在選択しているテキスト -
TM_CURRENT_LINE現在の行の内容 -
TM_CURRENT_WORD現在のカーソル位置の単語(もしくは空白) -
TM_LINE_INDEX最初の行を0行目としたときの現在の行番号 -
TM_LINE_NUMBER最初の行を1行目としたときの現在の行番号 -
TM_FILENAME現在のドキュメントのファイル名 -
TM_FILENAME_BASE現在のドキュメントのファイル名(拡張子なし) -
TM_DIRECTORY現在のドキュメントのディレクトリ -
TM_FILEPATH現在のドキュメントのフルのファイルパス -
RELATIVE_FILEPATH現在のドキュメントの相対(開いているワークスペースやフォルダに対する)ファイルパス -
CLIPBOARDクリップボードの内容 -
WORKSPACE_NAME開いているワークスペースまたはフォルダーの名前 -
WORKSPACE_FOLDER開いているワークスペースまたはフォルダーのパス -
CURRENT_YEAR現在の年 -
CURRENT_YEAR_SHORT現在の年の下2桁 -
CURRENT_MONTH2桁の月 (例 '02') -
CURRENT_MONTH_NAME月の正式名称(例:'July') -
CURRENT_MONTH_NAME_SHORT月の略称(例:'Jul')。 -
CURRENT_DATE2桁の日付(例:'08') -
CURRENT_DAY_NAME曜日名 (例: 'Monday') -
CURRENT_DAY_NAME_SHORT曜日の略称(例:'Mon') -
CURRENT_HOUR24時間表示での現在時刻 -
CURRENT_MINUTE現在の分を2桁で表示 -
CURRENT_SECOND現在の秒を2桁で表示 -
CURRENT_SECONDS_UNIXUnixエポックからの秒数 -
RANDOM10進数6桁の乱数 -
RANDOM_HEX16進数6桁の乱数 -
UUIDバージョン4のUUID -
BLOCK_COMMENT_START出力例:C++の場合/*またはHTMLの場合<!-- -
BLOCK_COMMENT_END出力例:C++の場合*/またはHTMLの場合--> -
LINE_COMMENT出力例:C++の場合// -
1~9タブストップ$1~$9の内容 -
CURSOR_INDEXマルチカーソルの最初の選択を0とした番号 -
CURSOR_NUMBERマルチカーソルの最初の選択を1とした番号
"day":{
"prefix": "day",
"body": "$CURRENT_YEAR/$CURRENT_MONTH/$CURRENT_DATE-$CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND",
"description": "YYYY/MM/DD-HH:MM:SS"
}
2022/03/13-16:57:11
正規表現
変数に対して正規表現で加工することが可能です。
${変数/正規表現/置換/正規表現オプション}
"#name": {
"prefix": "#name",
"body": "${TM_FILENAME/(?:(\\w+)(\\.)?)/${1:/upcase}${2:+_}/gi}"
}
HEADER_SAMPLE_HPP
header.sample.hppのファイルで上記スニペットを展開した場合
正規表現及び正規表現オプションはjavascriptの正規表現を確認してください。
スニペット独自の機能として置換後の$1...などに大文字化などのオプションがあります。
上記サンプルで${1: /upcase}としている部分の/upcaseがオプションです。
置換項目のオプション一覧
-
/upcase大文字にする -
/downcase小文字にする -
/capitalize文字の先頭を大文字にする -
/camelcaseキャメルケースにする -
/pascalcaseパスカルケースにする -
+ string正規表現でキャプチャした部分が空白でなければstring -
? A: B正規表現でキャプチャした部分が空白でなければA,空白ならB -
- string正規表現でキャプチャした部分が空白であればstring -
string正規表現でキャプチャした部分が空白であればstring
キャピタライズなどについて
/capitalizeの変換は最初の一文字しか変換しません・・・キャピタライズとは・・・?
/camelcase,/pascalcaseは空白や記号などを削除はしてくれますが最初の文字以外、大文字を小文字にすることはないようです。
一旦/downcaseで全て小文字にしてからキャメル/パスカルケースにした方が思った通りの変換するかも
複数の変換をかけないのでスニペットは長く見づらくなりますが・・・
ショートカットキーなど
変数一覧に現在の選択範囲があったのを覚えていますか?
選択範囲に対してスニペットを適用する場合は短縮名を入力では対応できません。
コマンドパレットから選択
選択範囲に対してスニペットを適用する方法は2通りあり一つはコマンドパレットからスニペットの挿入を選ぶ方法です。
Ctrl+Shift+P→スニペットの挿入→該当のスニペットを選択
ショートカットキーによる適用
もうひとつはショートカットキーに割り当ててしまう方法です。
こちらは先程のjsonファイルとは異なるjsonファイルに記載します。
ファイル→ユーザー設定→キーボードショートカット→右上のキーボードショートカットを開くのアイコンをクリック

すると以下のようなjsonファイルが開くきます。
// 既定値を上書きするには、このファイル内にキー バインドを挿入します
[]
そこにショートカットキーとして追加していきます。
[{
"key": "cmd+k 1",
"command": "editor.action.insertSnippet",
"when": "editorTextFocus",
"args": {
"snippet": "`$TM_SELECTED_TEXT`"
}
}]
すでに言語のjsonファイルでスニペットを登録しており、それを呼び出すだけの場合以下のようにします。
[{
"key": "cmd+k 1",
"command": "editor.action.insertSnippet",
"when": "editorTextFocus",
"args": {
"langId": "cpp",
"name": "tmplate class"
}
}]
cpp.jsonで定義されたtemplate classという名前のスニペットをショートカットキーcmd+k、1で挿入します。
ワークスペースのみで使用するスニペットの場合
現在のプロジェクトだけ使用したいスニペットとかもあるでしょう。
そんな場合は以下のようにフォルダ名の新しいスニペットファイルを選択して適当な名前で保存します。

ファイル→ユーザー設定→ユーザースニペット

ファイル名は何でも構いません
sampleという名前で作成するとフォルダの直下に.vscodeフォルダが作成されそこにsample.code-snippetsというファイルができます。

内容はほとんど同じですがjsonファイルのサンプルにscopeという項目が増えています。
scopeはスニペットを適用する言語を指定します。
{
// Place your Sample ワークスペース snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
// Placeholders with the same ids are connected.
// Example:
// "Print to console": {
// "scope": "javascript,typescript",
// "prefix": "log",
// "body": [
// "console.log('$1');",
// "$2"
// ],
// "description": "Log output to console"
// }
}
コメントアウトして保存すればjavascript及びtypescriptのファイルでlog→tabで展開されます。
ちなみにscopeを設定しない場合はワークスペース内のすべてのファイルでスニペットを使用できます。
ファイルテンプレート
スニペットのプロパティにisFileTemplateという項目が追加されていました。
このプロパティをtrueに設定するとそのスニペットがファイルテンプレートとなり、
コマンドパレットのファイルをスニペットで満たすから選択することが出来ます。
既存の何か書いているファイルでこのスニペットを呼び出した場合、書いている項目は全部消えます。
ファイルテンプレートのスニペットにprefixを設定するとうっかり呼び出してしまう可能性があるので設定しない方がいいでしょう。
その他
説明がまとまってない情報に関してはスクラップに投稿しています。
整理できれば記事にしたい
Discussion