🚀 在 VS Code 中免費取得

Visual Studio Code 的程式碼片段

程式碼片段是範本,可讓您更輕鬆地輸入重複的程式碼模式,例如迴圈或條件陳述式。

在 Visual Studio Code 中,程式碼片段會與其他建議一起出現在 IntelliSense 中 (⌃Space (Windows、Linux Ctrl+Space)),以及專用的程式碼片段選取器中 (命令面板中的 [插入程式碼片段])。 也支援 Tab 鍵完成:使用 "editor.tabCompletion": "on" 啟用它,輸入程式碼片段前置字元 (觸發文字),然後按下 Tab 以插入程式碼片段。

程式碼片段語法遵循 TextMate 程式碼片段語法,但「內插 Shell 程式碼」和 \u 的使用除外;兩者皆不支援。

ajax snippet

內建程式碼片段

VS Code 針對多種語言 (例如:JavaScript、TypeScript、Markdown 和 PHP) 內建程式碼片段。

builtin javascript snippet

您可以執行命令面板中的 [插入程式碼片段] 命令,取得目前檔案語言的程式碼片段清單,藉此查看可用於語言的程式碼片段。 不過,請記住,此清單也包含您已定義的使用者程式碼片段,以及您已安裝的擴充功能提供的任何程式碼片段。

從市集安裝程式碼片段

擴充功能檢視 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中,您可以使用 @category:"snippets" 篩選器搜尋包含程式碼片段的擴充功能,VS Code 市集 上有許多擴充功能包含程式碼片段。

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 中顯示程式碼片段。 子字串比對會在前置字元上執行,因此在此案例中,「fc」可能會比對「for-const」。
  • body 是一行或多行內容,將在插入時聯結為多行。 換行字元和內嵌 Tab 字元將根據插入程式碼片段的內容格式化。
  • description 是 IntelliSense 顯示的程式碼片段選用描述。

此外,上述範例的 body 具有三個預留位置 (依周遊順序排列):${1:array}${2:element}$0。 您可以使用 Tab 快速跳到下一個預留位置,此時您可以編輯預留位置或跳到下一個預留位置。 冒號 : 後面的字串 (如果有的話) 是預設文字,例如 ${2:element} 中的 element。 預留位置周遊順序依數字遞增,從一開始;零是選用的特殊案例,永遠排在最後,並在游標位於指定位置時結束程式碼片段模式。

檔案範本程式碼片段

如果程式碼片段旨在填入或取代檔案內容,您可以將 isFileTemplate 屬性新增至程式碼片段的定義。 當您在新檔案或現有檔案中執行 [程式碼片段:從程式碼片段填入檔案] 命令時,檔案範本程式碼片段會顯示在下拉式清單中。

程式碼片段範圍

程式碼片段具有範圍,因此只會建議相關的程式碼片段。 程式碼片段可以依下列項目設定範圍:

  1. 程式碼片段範圍設定的語言 (可能全部)
  2. 程式碼片段範圍設定的專案 (可能全部)

語言程式碼片段範圍

每個程式碼片段都會根據其定義位置,將範圍設定為一種、多種或所有 ("全域") 語言:

  1. 語言程式碼片段檔案
  2. 全域程式碼片段檔案

單一語言使用者定義的程式碼片段定義於特定語言的程式碼片段檔案 (例如 javascript.json) 中,您可以透過 [程式碼片段:設定程式碼片段] 依語言識別碼存取。 程式碼片段僅在編輯定義程式碼片段的語言時可存取。

多語言和全域使用者定義的程式碼片段全部定義於「全域」程式碼片段檔案 (JSON,副檔名為 .code-snippets) 中,也可以透過 [程式碼片段:設定程式碼片段] 存取。 在全域程式碼片段檔案中,程式碼片段定義可能具有額外的 scope 屬性,該屬性會採用一個或多個 語言識別碼,這使得程式碼片段僅適用於那些指定的語言。 如果未提供 scope 屬性,則全域程式碼片段適用於所有語言。

大多數使用者定義的程式碼片段範圍都設定為單一語言,因此定義於語言特定的程式碼片段檔案中。

專案程式碼片段範圍

您也可以擁有範圍設定為專案的全域程式碼片段檔案 (JSON,副檔名為 .code-snippets)。 專案資料夾程式碼片段是使用 [程式碼片段:設定程式碼片段] 下拉式功能表中的 [新增 '<資料夾名稱>' 的程式碼片段檔案...] 選項建立,並位於專案根目錄的 .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 以零為索引的行號
  • TM_LINE_NUMBER 以一為索引的行號
  • TM_FILENAME 目前文件的檔案名稱
  • TM_FILENAME_BASE 目前文件的檔案名稱 (不含副檔名)
  • TM_DIRECTORY 目前文件的目錄
  • TM_FILEPATH 目前文件的完整檔案路徑
  • RELATIVE_FILEPATH 目前文件的相對 (相對於開啟的工作區或資料夾) 檔案路徑
  • CLIPBOARD 剪貼簿的內容
  • WORKSPACE_NAME 開啟的工作區或資料夾名稱
  • WORKSPACE_FOLDER 開啟的工作區或資料夾路徑
  • CURSOR_INDEX 以零為索引的游標編號
  • CURSOR_NUMBER 以一為索引的游標編號

若要插入目前的日期和時間:

  • CURRENT_YEAR 目前年份
  • CURRENT_YEAR_SHORT 目前年份的後兩位數字
  • CURRENT_MONTH 月份 (以兩位數字表示,例如 '02')
  • CURRENT_MONTH_NAME 月份完整名稱 (例如 'July')
  • CURRENT_MONTH_NAME_SHORT 月份簡短名稱 (例如 'Jul')
  • CURRENT_DATE 月份中的日期 (以兩位數字表示,例如 '08')
  • CURRENT_DAY_NAME 星期名稱 (例如 'Monday')
  • CURRENT_DAY_NAME_SHORT 星期簡短名稱 (例如 'Mon')
  • CURRENT_HOUR 目前時間 (24 小時制)
  • CURRENT_MINUTE 目前分鐘 (以兩位數字表示)
  • CURRENT_SECOND 目前秒數 (以兩位數字表示)
  • CURRENT_SECONDS_UNIX 自 Unix 紀元以來的秒數
  • CURRENT_TIMEZONE_OFFSET 目前 UTC 時區偏移量,格式為 +HH:MM-HH:MM (例如 -07:00)。

若要插入隨機值:

  • RANDOM 6 個隨機十進位數字
  • RANDOM_HEX 6 個隨機十六進位數字
  • 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"
  }
}

變數轉換

轉換可讓您在插入變數之前修改變數的值。 轉換的定義包含三個部分:

  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 程式碼片段

您也可以將現有的 TextMate 程式碼片段 (.tmSnippets) 與 VS Code 搭配使用。 請參閱擴充功能 API 區段中的 使用 TextMate 程式碼片段 主題,以深入瞭解。

將鍵盤快速鍵指派給程式碼片段

您可以建立自訂 鍵盤快速鍵,以插入特定程式碼片段。 開啟 keybindings.json ([喜好設定:開啟鍵盤快速鍵檔案]),其中定義所有鍵盤快速鍵,並新增鍵盤快速鍵,將 "snippet" 作為額外引數傳遞

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

鍵盤快速鍵將叫用 [插入程式碼片段] 命令,但不會提示您選取程式碼片段,而是會插入提供的程式碼片段。 您可以像平常一樣定義自訂 鍵盤繫結,其中包含鍵盤快速鍵、命令 ID 和選用的 when 子句內容,以指定何時啟用鍵盤快速鍵。

此外,您可以使用 langIdname 引數參考現有的程式碼片段,而不是使用 snippet 引數值來內嵌定義程式碼片段。 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 中。