語意醒目提示指南
語意醒目提示是語法醒目提示的附加功能,如語法醒目提示指南中所述。Visual Studio Code 使用 TextMate 文法作為主要的符記化引擎。TextMate 文法以單一檔案作為輸入,並根據以正規表示式表示的詞法規則將其分解。
語意符記化允許語言伺服器根據語言伺服器在專案上下文中解析符號的知識,提供額外的符記資訊。佈景主題可以選擇使用語意符記來改進和精緻化文法的語法醒目提示。編輯器將語意符記的醒目提示套用在文法的醒目提示之上。
以下是語意醒目提示可以新增的範例
不使用語意醒目提示
使用語意醒目提示
請注意基於語言服務符號理解的色彩差異
- 第 10 行:
languageModes
以參數著色 - 第 11 行:
Range
和Position
以類別著色,而document
以參數著色。 - 第 13 行:
getFoldingRanges
以函式著色。
語意符記提供者
若要實作語意醒目提示,語言擴充功能可以依文件語言和/或檔案名稱註冊 semantic token provider
(語意符記提供者)。當需要語意符記時,編輯器將向提供者發出請求。
const tokenTypes = ['class', 'interface', 'enum', 'function', 'variable'];
const tokenModifiers = ['declaration', 'documentation'];
const legend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers);
const provider: vscode.DocumentSemanticTokensProvider = {
provideDocumentSemanticTokens(
document: vscode.TextDocument
): vscode.ProviderResult<vscode.SemanticTokens> {
// analyze the document and return semantic tokens
const tokensBuilder = new vscode.SemanticTokensBuilder(legend);
// on line 1, characters 1-5 are a class declaration
tokensBuilder.push(
new vscode.Range(new vscode.Position(1, 1), new vscode.Position(1, 5)),
'class',
['declaration']
);
return tokensBuilder.build();
}
};
const selector = { language: 'java', scheme: 'file' }; // register for all Java documents from the local file system
vscode.languages.registerDocumentSemanticTokensProvider(selector, provider, legend);
語意符記提供者 API 提供兩種風格,以適應語言伺服器的能力
-
DocumentSemanticTokensProvider
- 始終將完整文件作為輸入。provideDocumentSemanticTokens
- 提供文件的所有符記。provideDocumentSemanticTokensEdits
- 以與先前回應的差異形式提供文件的所有符記。
-
DocumentRangeSemanticTokensProvider
- 僅適用於範圍。provideDocumentRangeSemanticTokens
- 提供文件範圍的所有符記。
提供者傳回的每個符記都帶有一個分類,其中包含符記類型、任意數量的符記修飾詞和符記語言。
如上面的範例所示,提供者在 SemanticTokensLegend
中命名其將使用的類型和修飾詞。這允許 provide
API 將符記類型和修飾詞作為圖例的索引傳回。
語意符記分類
語意符記提供者的輸出包含符記。每個符記都有一個範圍和一個符記分類,用於描述符記代表的語法元素種類。或者,如果符記是嵌入式語言的一部分,則分類也可以命名語言。
為了描述語法元素的種類,使用了語意符記類型和修飾詞。此資訊類似於語法醒目提示指南中描述的 TextMate 範圍,但我們希望提出一個專用且更清晰的分類系統。
VS Code 隨附一組標準語意符記類型和修飾詞,供所有語意符記提供者使用。儘管如此,語意符記提供者可以自由定義新類型和修飾詞,並建立標準類型的子類型。
標準符記類型和修飾詞
標準類型和修飾詞涵蓋了許多語言使用的通用概念。雖然每種語言對於某些類型和修飾詞可能使用不同的術語,但透過遵守標準分類,佈景主題作者可以定義跨語言工作的佈景主題規則。
以下是 VS Code 預先定義的標準語意符記類型和語意符記修飾詞
標準符記類型
ID | 描述 |
---|---|
namespace |
用於宣告或參考命名空間、模組或套件的識別碼。 |
class |
用於宣告或參考類別類型的識別碼。 |
enum |
用於宣告或參考列舉類型的識別碼。 |
interface |
用於宣告或參考介面類型的識別碼。 |
struct |
用於宣告或參考結構類型的識別碼。 |
typeParameter |
用於宣告或參考型別參數的識別碼。 |
type |
用於宣告或參考上述未涵蓋的型別的識別碼。 |
parameter |
用於宣告或參考函式或方法參數的識別碼。 |
variable |
用於宣告或參考區域或全域變數的識別碼。 |
property |
用於宣告或參考成員屬性、成員欄位或成員變數的識別碼。 |
enumMember |
用於宣告或參考列舉屬性、常數或成員的識別碼。 |
decorator |
用於宣告或參考裝飾器和註釋的識別碼。 |
event |
用於宣告事件屬性的識別碼。 |
function |
用於宣告函式的識別碼。 |
method |
用於宣告成員函式或方法的識別碼。 |
macro |
用於宣告巨集的識別碼。 |
label |
用於宣告標籤的識別碼。 |
comment |
用於表示註解的符記。 |
string |
用於表示字串常值的符記。 |
keyword |
用於表示語言關鍵字的符記。 |
number |
用於表示數字常值的符記。 |
regexp |
用於表示正規表示式常值的符記。 |
operator |
用於表示運算子的符記。 |
標準符記修飾詞
ID | 描述 |
---|---|
declaration |
用於符號的宣告。 |
definition |
用於符號的定義,例如,在標頭檔中。 |
readonly |
用於唯讀變數和成員欄位(常數)。 |
static |
用於類別成員(靜態成員)。 |
deprecated |
用於不應再使用的符號。 |
abstract |
用於抽象的類型和成員函式。 |
async |
用於標記為 async 的函式。 |
modification |
用於變數被賦值的變數參考。 |
documentation |
用於符號在文件中的出現。 |
defaultLibrary |
用於屬於標準程式庫一部分的符號。 |
除了標準類型和修飾詞之外,VS Code 還定義了類型和修飾詞到類似 TextMate 範圍的對應。這在語意符記範圍對應章節中介紹。
自訂符記類型和修飾詞
如有必要,擴充功能可以透過其擴充功能的 package.json
中的 semanticTokenTypes
和 semanticTokenModifiers
貢獻點宣告新類型和修飾詞,或建立現有類型的子類型
{
"contributes": {
"semanticTokenTypes": [
{
"id": "templateType",
"superType": "type",
"description": "A template type."
}
],
"semanticTokenModifiers": [
{
"id": "native",
"description": "Annotates a symbol that is implemented natively"
}
]
}
}
在上面的範例中,擴充功能宣告了一個新的類型 templateType
和一個新的修飾詞 native
。透過將 type
命名為超類型,type
的佈景主題樣式規則也將適用於 templateType
{
"name": "Red Theme",
"semanticTokenColors": {
"type": "#ff0011"
}
}
上面顯示的 semanticTokenColors
值 "#ff0011"
同時適用於 type
及其所有子類型,包括 templateType
。
除了自訂符記類型之外,擴充功能還可以定義這些類型如何對應到 TextMate 範圍。這在自訂對應章節中描述。請注意,自訂對應規則不會自動從超類型繼承。相反,子類型需要重新定義對應,最好是對更特定的範圍進行對應。
啟用語意醒目提示
是否計算和醒目提示語意符記由設定 editor.semanticHighlighting.enabled
決定。它可以具有值 true
、false
和 configuredByTheme
。
true
和false
會為所有佈景主題開啟或關閉語意醒目提示。configuredByTheme
是預設值,並讓每個佈景主題控制是否啟用語意醒目提示。所有隨附 VS Code 的佈景主題(例如,「Dark+」預設佈景主題)預設都已啟用語意醒目提示。
依賴語意符記的語言擴充功能可以在其 package.json
中覆寫其語言的預設值
{
"configurationDefaults": {
"[languageId]": {
"editor.semanticHighlighting.enabled": true
}
}
}
佈景主題
佈景主題是關於為符記指派色彩和樣式。佈景主題規則在色彩佈景主題檔案(JSON 格式)中指定。使用者也可以在使用者設定中自訂佈景主題規則。
色彩佈景主題中的語意著色
已將兩個新屬性新增至色彩佈景主題檔案格式,以支援基於語意符記的醒目提示。
屬性 semanticHighlighting
定義佈景主題是否已準備好使用語意符記進行醒目提示。預設值為 false,但我們鼓勵所有佈景主題都啟用它。當設定 editor.semanticHighlighting.enabled
設定為 configuredByTheme
時,將使用此屬性。
屬性 semanticTokenColors
允許佈景主題定義新的著色規則,以比對語意符記提供者發出的語意符記類型和修飾詞。
{
"name": "Red Theme",
"tokenColors": [
{
"scope": "comment",
"settings": {
"foreground": "#dd0000",
"fontStyle": "italic"
}
}
],
"semanticHighlighting": true,
"semanticTokenColors": {
"variable.readonly:java": "#ff0011"
}
}
variable.readonly:java
稱為選取器,其形式為 (*|tokenType)(.tokenModifier)*(:tokenLanguage)?
。
該值描述規則比對時的樣式。它可以是字串(表示前景色彩),也可以是物件,形式為 { foreground: string, bold: boolean, italic: boolean, underline: boolean }
或 { foreground: string, fontStyle: string }
,與 tokenColors
中的 TextMate 佈景主題規則相同。
前景需要遵循色彩格式中描述的色彩格式。不支援透明度。
以下是選取器和樣式的其他範例
"*.declaration": { "bold": true } // 所有宣告都設為粗體
"class:java": { "foreground": "#0f0", "italic": true } // java 中的類別
如果沒有規則符合,或者佈景主題沒有 semanticTokenColors
區段(但已啟用 semanticHighlighting
),則 VS Code 會使用語意符記範圍對應來評估給定語意符記的 TextMate 範圍。該範圍會與佈景主題 tokenColors
中的 TextMate 佈景主題規則比對。
語意符記範圍對應
為了使語意醒目提示適用於未定義任何特定語意規則的佈景主題,並作為自訂符記類型和修飾詞的回退,VS Code 維護從語意符記選取器到 TextMate 範圍的對應。
如果佈景主題已啟用語意醒目提示,但不包含給定語意符記的規則,則會使用這些 TextMate 範圍來尋找 TextMate 佈景主題規則。
預先定義的 TextMate 範圍對應
下表列出了目前預先定義的對應。
語意符記選取器 | 回退 TextMate 範圍 |
---|---|
namespace |
entity.name.namespace |
type |
entity.name.type |
type.defaultLibrary |
support.type |
struct |
storage.type.struct |
class |
entity.name.type.class |
class.defaultLibrary |
support.class |
interface |
entity.name.type.interface |
enum |
entity.name.type.enum |
function |
entity.name.function |
function.defaultLibrary |
support.function |
method |
entity.name.function.member |
macro |
entity.name.function.preprocessor |
variable |
variable.other.readwrite , entity.name.variable |
variable.readonly |
variable.other.constant |
variable.readonly.defaultLibrary |
support.constant |
parameter |
variable.parameter |
property |
variable.other.property |
property.readonly |
variable.other.constant.property |
enumMember |
variable.other.enummember |
event |
variable.other.event |
自訂 TextMate 範圍對應
此對應可以透過擴充功能的 package.json
中的 semanticTokenScopes
貢獻點進行擴充。
擴充功能執行此操作有兩種使用案例
-
定義自訂符記類型和符記修飾詞的擴充功能提供 TextMate 範圍作為回退,當佈景主題未定義新增語意符記類型或修飾詞的佈景主題規則時
{ "contributes": { "semanticTokenScopes": [ { "scopes": { "templateType": ["entity.name.type.template"] } } ] } }
-
TextMate 文法的提供者可以描述語言特定的範圍。這有助於包含語言特定佈景主題規則的佈景主題。
{ "contributes": { "semanticTokenScopes": [ { "language": "typescript", "scopes": { "property.readonly": ["variable.other.constant.property.ts"] } } ] } }
試用看看
我們有一個語意符記範例,說明如何建立語意符記提供者。
範圍檢查器工具可讓您探索來源檔案中存在的語意符記,以及它們比對的佈景主題規則。若要查看語意符記,請在 TypeScript 檔案上使用內建佈景主題(例如,Dark+)。