VS Codeのエージェントモードを拡張するには、を試してください!

Visual Studio Code のスニペット

コード スニペットは、ループや条件文などの繰り返しのコード パターンを簡単に入力できるようにするテンプレートです。

Visual Studio Code では、IntelliSense (⌃Space (Windows、Linux では Ctrl+Space)) に他の候補と混じってスニペットが表示されるほか、専用のスニペット ピッカー (コマンド パレットの [スニペットの挿入]) にも表示されます。また、タブ補完もサポートされています。"editor.tabCompletion": "on" を有効にし、スニペット プレフィックス (トリガー テキスト) を入力して Tab キーを押すと、スニペットが挿入されます。

スニペットの構文は TextMate スニペット構文 に従いますが、「補間されたシェル コード」と \u の使用はサポートされていません。

ajax snippet

組み込みスニペット

VS Code には、JavaScript、TypeScript、Markdown、PHP などの多数の言語用の組み込みスニペットがあります。

builtin javascript snippet

コマンド パレットで [スニペットの挿入] コマンドを実行すると、現在のファイルの言語で利用可能なスニペットのリストを表示できます。ただし、このリストには、ユーザーが定義したスニペットや、インストールした拡張機能によって提供されるスニペットも含まれることに注意してください。

マーケットプレースからスニペットをインストールする

多くの拡張機能 は、VS Code Marketplace でスニペットを含んでいます。拡張機能ビュー (⇧⌘X (Windows、Linux では Ctrl+Shift+X)) で @category:"snippets" フィルターを使用して、スニペットを含む拡張機能を検索できます。

Searching for extensions with snippets

使用したい拡張機能を見つけたら、それをインストールし、VS Code を再起動すると、新しいスニペットが利用可能になります。

独自のスニペットを作成する

拡張機能なしで独自のスニペットを簡単に定義できます。独自のスニペットを作成または編集するには、[ファイル] > [基本設定] の下にある [スニペットの構成] を選択し、スニペットを表示する言語 (利用可能な 言語識別子 で) を選択するか、すべての言語で表示する場合は [新規グローバル スニペット ファイル] オプションを選択します。VS Code は、基になるスニペット ファイルの作成と更新を管理します。

snippet dropdown

スニペット ファイルは JSON で記述され、C スタイルのコメントをサポートし、無制限の数のスニペットを定義できます。スニペットは、動的な動作のためにほとんどの TextMate 構文をサポートし、挿入コンテキストに基づいて空白をインテリジェントにフォーマットし、簡単な複数行編集を可能にします。

以下は、JavaScript の for ループ スニペットの例です。

// in file 'Code/User/snippets/javascript.json'
{
  "For Loop": {
    "prefix": ["for", "for-const"],
    "body": ["for (const ${2:element} of ${1:array}) {", "\t$0", "}"],
    "description": "A for loop."
  }
}

上記の例では

  • 「For Loop」はスニペット名です。description が提供されていない場合、IntelliSense を介して表示されます。
  • prefix は、IntelliSense にスニペットを表示する 1 つ以上のトリガーワードを定義します。プレフィックスに対して部分文字列マッチングが実行されるため、この場合、「fc」は「for-const」と一致する可能性があります。
  • body は 1 行以上のコンテンツであり、挿入時に複数行として結合されます。改行と埋め込まれたタブは、スニペットが挿入されるコンテキストに従ってフォーマットされます。
  • description は、IntelliSense によって表示されるスニペットのオプションの説明です。

さらに、上記の例の body には、3 つのプレースホルダー (トラバーサルの順にリスト) があります: ${1:array}${2:element}、および $0Tab キーですばやく次のプレースホルダーにジャンプでき、その時点でプレースホルダーを編集したり、次のプレースホルダーにジャンプしたりできます。コロン : の後の文字列 (ある場合) は既定のテキストであり、たとえば ${2:element}element です。プレースホルダーのトラバーサル順序は、1 から始まる番号の昇順です。0 は常に最後に表示されるオプションの特殊なケースであり、指定された位置にカーソルがある状態でスニペット モードを終了します。

ファイルテンプレートスニペット

スニペットがファイルのコンテンツを埋めたり置き換えたりすることを目的としている場合、スニペットの定義に isFileTemplate 属性を追加できます。ファイルテンプレートスニペットは、新規または既存のファイルで [スニペット: スニペットからファイルを生成] コマンドを実行したときにドロップダウンに表示されます。

スニペットのスコープ

スニペットは、関連するスニペットのみが提案されるようにスコープ設定されます。スニペットは、次のいずれかの方法でスコープ設定できます。

  1. スニペットがスコープ設定される 言語 (すべての場合あり)
  2. スニペットがスコープ設定される プロジェクト (すべての場合あり)

言語スニペットのスコープ

すべてのスニペットは、次のいずれかに定義されているかどうかに基づいて、1 つ、複数、またはすべての (「グローバル」) 言語にスコープ設定されます。

  1. 言語 スニペット ファイル
  2. グローバル スニペット ファイル

単一言語のユーザー定義スニペットは、特定の言語のスニペット ファイル (たとえば javascript.json) で定義されます。これは [スニペット: スニペットの構成] を介して言語識別子でアクセスできます。スニペットは、定義されている言語を編集している場合にのみアクセスできます。

複数言語およびグローバルなユーザー定義スニペットはすべて、「グローバル」スニペット ファイル (ファイル サフィックスが .code-snippets の JSON) で定義されており、これも [スニペット: スニペットの構成] を介してアクセスできます。グローバル スニペット ファイルでは、スニペット定義に 1 つ以上の 言語識別子 を取る追加の scope プロパティを持つことができ、これによりスニペットは指定された言語でのみ利用可能になります。scope プロパティが指定されていない場合、グローバル スニペットは すべて の言語で利用可能です。

ほとんどのユーザー定義スニペットは単一の言語にスコープ設定されており、そのため言語固有のスニペット ファイルで定義されています。

プロジェクト スニペットのスコープ

プロジェクトにスコープ設定されたグローバル スニペット ファイル (ファイル サフィックスが .code-snippets の JSON) を持つこともできます。プロジェクト フォルダーのスニペットは、[スニペット: スニペットの構成] ドロップダウン メニューの [新しいスニペット ファイルを作成: ''] オプションで作成され、プロジェクトのルートの .vscode フォルダーに配置されます。プロジェクト スニペット ファイルは、そのプロジェクトで作業しているすべてのユーザーとスニペットを共有するのに役立ちます。プロジェクト フォルダーのスニペットはグローバル スニペットに似ており、scope プロパティを介して特定の言語にスコープ設定できます。

スニペットの構文

スニペットの body は、カーソルや挿入されるテキストを制御するために特殊な構造を使用できます。以下に、サポートされる機能とその構文を示します。

タブストップ

タブストップを使用すると、エディターのカーソルをスニペット内で移動させることができます。$1$2 を使用してカーソルの位置を指定します。数字はタブストップが訪問される順序であり、$0 は最終的なカーソルの位置を示します。同じタブストップが複数回出現する場合、それらはリンクされ、同期して更新されます。

プレースホルダー

プレースホルダーは、${1:foo} のように値を持つタブストップです。プレースホルダーのテキストは挿入され、簡単に変更できるように選択されます。プレースホルダーは、${1:another ${2:placeholder}} のようにネストできます。

選択

プレースホルダーは値として選択肢を持つことができます。構文は、パイプ文字で囲まれたコンマ区切りの値の列挙であり、例えば ${1|one,two,three|} のようになります。スニペットが挿入され、プレースホルダーが選択されると、選択肢がユーザーに値のいずれかを選択するよう促します。

変数

$name または ${name:default} を使用すると、変数の値を挿入できます。変数が設定されていない場合、その デフォルト または空の文字列が挿入されます。変数が不明 (つまり、その名前が定義されていない) な場合、変数の名前が挿入され、プレースホルダーに変換されます。

以下の変数を使用できます

  • 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 開いているワークスペースまたはフォルダーのパス
  • CURSOR_INDEX 0から始まるカーソル番号
  • CURSOR_NUMBER 1から始まるカーソル番号

現在の日付と時刻を挿入する場合

  • CURRENT_YEAR 現在の年
  • CURRENT_YEAR_SHORT 現在の年の下2桁
  • CURRENT_MONTH 月 (2桁、例: '02')
  • CURRENT_MONTH_NAME 月のフルネーム (例: 'July')
  • CURRENT_MONTH_NAME_SHORT 月の短い名前 (例: 'Jul')
  • CURRENT_DATE 日付 (2桁、例: '08')
  • CURRENT_DAY_NAME 曜日の名前 (例: 'Monday')
  • CURRENT_DAY_NAME_SHORT 曜日の短い名前 (例: 'Mon')
  • CURRENT_HOUR 現在の時 (24時間形式)
  • CURRENT_MINUTE 現在の分 (2桁)
  • CURRENT_SECOND 現在の秒 (2桁)
  • CURRENT_SECONDS_UNIX Unix エポックからの秒数
  • CURRENT_TIMEZONE_OFFSET 現在の UTC タイムゾーン オフセット (+HH:MM または -HH:MM 形式、例: -07:00)。

ランダムな値を挿入する場合

  • RANDOM 6桁のランダムな10進数
  • RANDOM_HEX 6桁のランダムな16進数
  • UUID バージョン4 UUID

現在の言語を考慮して、行コメントまたはブロックコメントを挿入する場合

  • BLOCK_COMMENT_START 出力例: PHPでは /*、HTMLでは <!--
  • BLOCK_COMMENT_END 出力例: PHPでは */、HTMLでは -->
  • LINE_COMMENT 出力例: PHPでは //

以下のスニペットは、JavaScript ファイルに /* Hello World */ を挿入し、HTML ファイルに <!-- Hello World --> を挿入します。

{
  "hello": {
    "scope": "javascript,html",
    "prefix": "hello",
    "body": "$BLOCK_COMMENT_START Hello World $BLOCK_COMMENT_END"
  }
}

変数変換

変換を使用すると、変数の値を挿入する前に変更できます。変換の定義は、次の3つの部分で構成されます。

  1. 変数の値と照合される正規表現、または変数を解決できない場合の空の文字列。
  2. 正規表現から一致するグループを参照できる「フォーマット文字列」。フォーマット文字列は、条件付き挿入と単純な変更を可能にします。
  3. 正規表現に渡されるオプション。

以下の例では、現在のファイルの拡張子なしの名前を挿入します。つまり、foo.txt から foo が作成されます。

${TM_FILENAME/(.*)\\..+$/$1/}
  |           |         |  |
  |           |         |  |-> no options
  |           |         |
  |           |         |-> references the contents of the first
  |           |             capture group
  |           |
  |           |-> regex to capture everything before
  |               the final `.suffix`
  |
  |-> resolves to the filename

プレースホルダー変換

変数変換と同様に、プレースホルダーの変換では、次のタブストップに移動するときにプレースホルダーに挿入されるテキストを変更できます。挿入されたテキストは正規表現と照合され、オプションに応じて、一致するものまたはすべての一致が指定された置換フォーマットテキストに置き換えられます。プレースホルダーのすべての出現箇所は、最初のプレースホルダーの値を使用して独自の変換を個別に定義できます。プレースホルダー変換のフォーマットは、変数変換と同じです。

変換例

例は、スニペットの本体内で表示されるように二重引用符で囲まれて示されており、特定の文字を二重にエスケープする必要があることを示しています。ファイル名 example-123.456-TEST.js のサンプル変換とその結果の出力。

出力 説明
"${TM_FILENAME/[\\.]/_/}" example-123_456-TEST.js 最初の ._ に置き換える
"${TM_FILENAME/[\\.-]/_/g}" example_123_456_TEST_js . または -_ に置き換える
"${TM_FILENAME/(.*)/${1:/upcase}/}" EXAMPLE-123.456-TEST.JS すべて大文字に変更する
"${TM_FILENAME/[^0-9a-z]//gi}" example123456TESTjs 英数字以外の文字を削除する

文法

以下は、スニペットの EBNF (拡張バッカス・ナウア記法) です。\ (バックスラッシュ) を使用すると、$}\ をエスケープできます。選択要素内では、バックスラッシュはコンマとパイプ文字もエスケープします。エスケープする必要がある文字のみをエスケープできるため、これらの構造内で $ をエスケープすべきではなく、選択構造内で $ または } をエスケープすべきではありません。

any         ::= tabstop | placeholder | choice | variable | text
tabstop     ::= '$' int
                | '${' int '}'
                | '${' int  transform '}'
placeholder ::= '${' int ':' any '}'
choice      ::= '${' int '|' text (',' text)* '|}'
variable    ::= '$' var | '${' var '}'
                | '${' var ':' any '}'
                | '${' var transform '}'
transform   ::= '/' regex '/' (format | text)+ '/' options
format      ::= '$' int | '${' int '}'
                | '${' int ':' '/upcase' | '/downcase' | '/capitalize' | '/camelcase' | '/pascalcase' '}'
                | '${' int ':+' if '}'
                | '${' int ':?' if ':' else '}'
                | '${' int ':-' else '}' | '${' int ':' else '}'
regex       ::= JavaScript Regular Expression value (ctor-string)
options     ::= JavaScript Regular Expression option (ctor-options)
var         ::= [_a-zA-Z] [_a-zA-Z0-9]*
int         ::= [0-9]+
text        ::= .*
if          ::= text
else        ::= text

TextMate スニペットを使用する

VS Code で既存の TextMate スニペット (.tmSnippets) を使用することもできます。詳細については、拡張機能 API セクションの TextMate スニペットの使用 トピックを参照してください。

スニペットにキーボード ショートカットを割り当てる

特定のスニペットを挿入するためのカスタム キーボード ショートカットを作成できます。すべてのキーボード ショートカットを定義する keybindings.json ([設定: キーボード ショートカット ファイルを開く]) を開き、追加の引数として "snippet" を渡すキーボード ショートカットを追加します。

{
  "key": "cmd+k 1",
  "command": "editor.action.insertSnippet",
  "when": "editorTextFocus",
  "args": {
    "snippet": "console.log($1)$0"
  }
}

このキーボード ショートカットは [スニペットの挿入] コマンドを呼び出しますが、スニペットを選択するようプロンプトを表示する代わりに、指定されたスニペットを挿入します。カスタム キーバインディング は、通常どおりキーボード ショートカット、コマンド ID、およびオプションの when 句コンテキスト を指定して定義します。

また、snippet 引数の値を使用してスニペットをインラインで定義する代わりに、langId および name 引数を使用して既存のスニペットを参照できます。langId 引数は、name で示されるスニペットが挿入される言語を選択します。たとえば、以下のサンプルは csharp ファイルで利用可能な myFavSnippet を選択します。

{
  "key": "cmd+k 1",
  "command": "editor.action.insertSnippet",
  "when": "editorTextFocus",
  "args": {
    "langId": "csharp",
    "name": "myFavSnippet"
  }
}

次のステップ

  • コマンド ライン - VS Code には、ファイルのオープンや比較、拡張機能のインストールを行うための豊富なコマンドライン インターフェースがあります。
  • 拡張機能 API - VS Code を拡張する他の方法について学習します。
  • スニペット ガイド - VS Code で使用するためにスニペットをパッケージ化できます。

よくある質問

.tmSnippet ファイルから既存の TextMate スニペットを使用したい場合はどうすればよいですか?

TextMate スニペット ファイルを VS Code で使用するために簡単にパッケージ化できます。拡張機能 API ドキュメントの TextMate スニペットの使用 を参照してください。

スニペットで貼り付けられたスクリプトに変数を配置するにはどうすればよいですか?

貼り付けられたスクリプトに変数を配置するには、スニペットの展開フェーズで解析されないように、$variable 名の '$' をエスケープする必要があります。

"VariableSnippet":{
    "prefix": "_Var",
    "body": "\\$MyVar = 2",
    "description": "A basic snippet that places a variable into script with the $ prefix"
  }

これにより、貼り付けられたスニペットは次のようになります

$MyVar = 2

IntelliSense からスニペットを削除できますか?

はい、[スニペットの挿入] コマンドのドロップダウンにあるスニペット項目の右側にある [IntelliSense から非表示] ボタンを選択することで、IntelliSense (補完リスト) に表示されないように特定の��スニペットを非表示にすることができます。

Hide from IntelliSense button in Insert Snippet dropdown

[スニペットの挿入] コマンドでスニペットを選択することはできますが、非表示のスニペットは IntelliSense に表示されません。