Visual Studio Code 中的程式碼片段
程式碼片段是範本,可讓您更輕鬆地輸入重複的程式碼模式,例如迴圈或條件陳述式。
在 Visual Studio Code 中,程式碼片段會與其他建議混合顯示在 IntelliSense 中 (⌃Space (Windows、Linux Ctrl+Space)),以及專用的程式碼片段選擇器中 (命令面板中的 插入程式碼片段)。 也支援 Tab 鍵完成:使用 "editor.tabCompletion": "on"
啟用它,輸入程式碼片段前置字元 (觸發文字),然後按下 Tab 以插入程式碼片段。
程式碼片段語法遵循 TextMate 程式碼片段語法,但「內插 Shell 程式碼」和 \u
的使用除外;兩者都不受支援。
內建程式碼片段
VS Code 具有許多語言的內建程式碼片段,例如:JavaScript、TypeScript、Markdown 和 PHP。
您可以執行命令面板中的 插入程式碼片段 命令,以取得目前檔案語言的程式碼片段清單,藉此查看語言可用的程式碼片段。 不過,請記住,此清單也包含您定義的使用者程式碼片段,以及您已安裝的擴充功能提供的任何程式碼片段。
從市集安裝程式碼片段
市集上的許多 擴充功能 VS Code 市集 都包含程式碼片段。 您可以使用 @category:"snippets"
篩選器,在擴充功能檢視 (⇧⌘X (Windows、Linux Ctrl+Shift+X)) 中搜尋包含程式碼片段的擴充功能。
如果您找到想要使用的擴充功能,請安裝它,然後重新啟動 VS Code,新的程式碼片段就會可供使用。
建立您自己的程式碼片段
您可以輕鬆定義自己的程式碼片段,而無需任何擴充功能。 若要建立或編輯自己的程式碼片段,請選取 檔案 > 喜好設定 下的 設定程式碼片段,然後選取程式碼片段應顯示的語言 (依 語言識別碼),或選取 新增全域程式碼片段檔案 選項 (如果程式碼片段應顯示在所有語言中)。 VS Code 會為您管理基礎程式碼片段檔案的建立和重新整理。
程式碼片段檔案以 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
屬性新增至程式碼片段的定義。 當您在新檔案或現有檔案中執行 程式碼片段:從程式碼片段填入檔案 命令時,檔案範本程式碼片段會顯示在下拉式清單中。
程式碼片段範圍
程式碼片段具有範圍,因此只會建議相關的程式碼片段。 程式碼片段可以依下列項目設定範圍
- 程式碼片段範圍設定到的語言 (可能全部)
- 程式碼片段範圍設定到的專案 (可能全部)
語言程式碼片段範圍
每個程式碼片段都會根據它是否定義在下列位置,將範圍設定為一種、多種或所有 (「全域」) 語言
- 語言程式碼片段檔案
- 全域程式碼片段檔案
單一語言使用者定義的程式碼片段定義在特定語言的程式碼片段檔案中 (例如 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
月份的完整名稱 (範例「七月」)CURRENT_MONTH_NAME_SHORT
月份的簡短名稱 (範例「七月」)CURRENT_DATE
月份中的日期,以兩位數字表示 (範例「08」)CURRENT_DAY_NAME
星期的名稱 (範例「星期一」)CURRENT_DAY_NAME_SHORT
星期的簡短名稱 (範例「週一」)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"
}
}
變數轉換
轉換可讓您在插入變數之前修改變數的值。 轉換的定義包含三個部分
- 與變數值比對的規則運算式,或在無法解析變數時為空字串。
- 「格式字串」,可讓您參考規則運算式的比對群組。 格式字串允許條件式插入和簡單修改。
- 傳遞至規則運算式的選項。
下列範例會插入目前檔案的名稱,但不含副檔名,因此從 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 子句內容 (用於啟用鍵盤快速鍵時機) 照常定義自訂 鍵盤快速鍵。
此外,您可以使用 langId
和 name
引數參考現有的程式碼片段,而不用使用 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 中 按鈕,該按鈕位於 插入程式碼片段 命令下拉式清單中程式碼片段項目的右側。
您仍然可以使用 插入程式碼片段 命令選取程式碼片段,但隱藏的程式碼片段不會顯示在 IntelliSense 中。