使用語言設定自定義編輯器行為

您可以使用語言組態來啟用語言特定語法作業,在 Visual Studio 編輯器中實作自定義的語言特定語法。 相較於使用語言伺服器,使用語言設定可以改善效能,因為其所有作業都是本機作業。

什麼是語言設定

Visual Studio 透過語言延伸模組為各種程式設計語言提供智慧型手機編輯功能。 語言設定會補充使用語言伺服器通訊協定 (LSP) 的伺服器,並提供宣告式數據,讓Visual Studio編輯器能夠進行格式化、著色和完成決策,而不會延遲對LSP伺服器進行異步查詢。 宣告式語言功能定義於組態檔中。 例如,與Visual Studio搭配的HTML、CSS和 typescript-basic延伸模組提供下列宣告式語言功能的子集:

  • 語法醒目提示
  • 代碼段完成
  • 括弧比對
  • 括號自動遺失
  • 批注切換
  • 自動縮排

Visual Studio 提供擴充功能來定義任何程式設計語言的語言組態。 語言組態檔會控制基本編輯功能,例如批註切換,以及括弧比對和周圍。

使用語言設定有助於:

  • 用戶輸入時同步工作
  • 簡單性:具有正則表達式的簡短 JSON 檔案比複雜的演算法更容易維護
  • 可移植性:Visual Studio Code 與 Visual Studio 之間不需要或最少的變更

此外,語言組態檔也提供簡單的方法來擴充Visual Studio,以支援一些透過容易閱讀的JSON檔案的基本重構功能。

將語言設定支援新增至 Visual Studio 延伸模組

將語言組態支援新增至 Visual Studio 延伸模組有三個部分:

  1. 建立 VSIX 專案
  2. 建立語言組態檔
  3. 新增文法檔案
  4. 更新 pkgdef 檔案

您可以在語言設定範例中 探索工作範例

建立 VSIX 專案

若要使用語言設定建立語言服務延伸模組,請先確定您 已安裝 VS 實例的 Visual Studio 延伸模塊開發 工作負載。

接下來,流覽至 [檔案>新專案]、搜尋 「vsix」 並尋找 VSIX 專案,以建立新的 VSIX 專案:

Screenshot showing how to create a VSIX project.

建立語言組態檔

建立自己的語言組態檔時,您可以選擇要在 JSON 檔案中上線的哪些層面。 例如,您可以選擇支援批注切換、自動套用大括弧,或本節所述的任何可用功能組合。

若要將支援新增至您的延伸模組,您必須先建立語言組態檔。 檔案名稱必須遵循標準:使用連字元來分隔檔名中的單字,並確定其結尾為 language-configuration.json

下列程式代碼顯示範例語言組態檔。

{
    "comments": {
      "lineComment": "***",
      "blockComment": ["{*", "*}"]
    },
    "brackets": [
      ["@", "@"],
      ["#", "#"],
      ["$", "$"],
      ["(", ")"]
    ],
    "autoClosingPairs": [
      { "open": "{", "close": "}" },
      { "open": "@", "close": "@" },
      { "open": "#", "close": "#" },
      { "open": "$", "close": "$" },
      { "open": "(", "close": ")" },
      { "open": "'", "close": "'", "notIn": ["string", "comment"] },
      { "open": "\"", "close": "\"", "notIn": ["string"] },
    ],
    "autoCloseBefore": ";:.,=}])>` \n\t",
    "surroundingPairs": [
      ["@", "@"],
      ["#", "#"],
      ["$", "$"],
      ["[", "]"],
      ["(", ")"],
      ["'", "'"],
      ["\"", "\""],
      ["`", "`"]
    ],
    "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)",
    "indentationRules": {
      "increaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$",
      "decreaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\)\\}\\]].*$"
    }
  }

組態設定

下列各節說明語言組態檔中可用的設定。

批注切換

語言組態檔提供兩個命令來批注切換。 切換行批注切換區塊批注。 您可以指定 comments.blockCommentcomments.lineComment 來控制 Visual Studio 應該如何批注出行/區塊。

{
  "comments": {
    "lineComment": "//",
    "blockComment": ["/*", "*/"]
  }
}

當您按下 Ctrl KCtrl++C 時,此設定會影響 Visual Studio 文字編輯器的行為。

括號定義

當您將游標移至此處定義的括弧時,Visual Studio 會醒目提示該括號與其相符的配對。

{
  "brackets": [["{", "}"], ["[", "]"], ["(", ")"]]
}

[Visual Studio 工具選項] 對話框的 [文字編輯器]、[一般]、[顯示] 中的相關設定是 [啟用大括弧配對色彩設定] 複選框。>

自動遺失

當您輸入 '時,Visual Studio 會建立一對單引號,並將游標放在中間: '|'。 本節會定義這類配對。

{
  "autoClosingPairs": [
    { "open": "{", "close": "}" },
    { "open": "[", "close": "]" },
    { "open": "(", "close": ")" },
    { "open": "'", "close": "'", "notIn": ["string", "comment"] },
    { "open": "\"", "close": "\"", "notIn": ["string"] },
    { "open": "`", "close": "`", "notIn": ["string", "comment"] },
    { "open": "/**", "close": " */", "notIn": ["string"] }
  ]
}

notIn 碼會在特定程式代碼範圍中停用此功能。 例如,當您撰寫下列程式代碼時:

// ES6's Template String
`ES6's Template String`;

單引號不會自動封閉。

不需要 notIn 屬性的配對也可以使用更簡單的語法:

{
  "autoClosingPairs": [ ["{", "}"], ["[", "]"] ]
}
自動遺失之前

根據預設,如果游標後面有空格符,Visual Studio 只會自動重設配對。 因此,當您輸入 { 下列 JSX 程式代碼時,將不會取得自動關閉:

const Component = () =>
  <div className={>
                  ^ Does not get autoclosed by default
  </div>

不過,此定義會覆寫該行為:

{
  "autoCloseBefore": ";:.,=}])>` \n\t"
}

現在,當您在 之前>輸入 { 時,Visual Studio 會使用 }自動將它套用。

自動保險

當您在 Visual Studio 中選取範圍並輸入左括弧時,Visual Studio 會以一對括弧括住選取的內容。 這項功能稱為「自動復原」,您可以在這裡定義特定語言的自動復原配對:

{
  "surroundingPairs": [
    ["{", "}"],
    ["[", "]"],
    ["(", ")"],
    ["'", "'"],
    ["\"", "\""],
    ["`", "`"]
  ]
}

Visual Studio 工具選項中的相關設定位於 [文字編輯器]、[一般]、[顯示] 複選框:輸入引號或括弧時自動括住選取範圍。>

Word 模式

wordPattern 定義程式設計語言中被視為單字的內容。 程式代碼建議功能會使用此設定來判斷是否 wordPattern 設定文字界限。

{
  "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)"
}

縮排規則

indentationRules定義當您輸入、貼上和移動行時,或當您使用 Ctrl+K、Ctrl D(格式檔)和+ Ctrl K、Ctrl++F(格式選取範圍)格式化文字時,編輯器應該如何調整目前行或下一行的縮排。

{
  "indentationRules": {
    "increaseIndentPattern": "^((?!\\/\\/).)*(\\{[^}\"'`]*|\\([^)\"'`]*|\\[[^\\]\"'`]*)$",
    "decreaseIndentPattern": "^((?!.*?\\/\\*).*\\*/)?\\s*[\\)\\}\\]].*$"
  }
}

例如,if (true) {increaseIndentPattern對 ,然後在左括弧{後面按 Enter 鍵時,編輯器會自動縮排一次,而您的程式代碼最終會是:

if (true) {
  console.log();

除了 increaseIndentPatterndecreaseIndentPatter之外,還有另外兩個縮排規則:

  • indentNextLinePattern - 如果一行符合此模式,則 只應該縮排一次之後的下一行
  • unIndentedLinePattern - 如果一行符合此模式,則不應該變更其縮排,而且不應該根據其他規則進行評估。

如果程式設計語言沒有設定縮排規則,當您輸入右括弧時,當行結尾為左括號和未縮排時,編輯器會縮排。 此處的括號是由 brackets定義。

按 Enter 鍵

onEnterRules定義在編輯器中按下 Enter要評估的規則清單。

{
  "onEnterRules": [{
    "beforeText": "^\\s*(?:def|class|for|if|elif|else|while|try|with|finally|except|async).*?:\\s*$",
    "action": { "indent": "indent" }
  }]
}

按下 Enter 鍵時,會根據下列屬性檢查游標上方的文字之前、之後或一行:

  • beforeText (強制性)。 符合游標前文字的正則表達式(僅限於目前行)。
  • afterText. 符合游標後面文字的正則表達式(僅限於目前行)。
  • previousLineText. 符合游標上方一行文字的正則表達式。

如果所有指定的屬性都相符,則會將規則視為相符,而且不會進一步 onEnterRules 評估。 onEnterRule可以指定下列動作:

  • indent (強制性)。 的 none, indent, outdent, indentOutdent其中一個。
    • none 表示新行會繼承目前行的縮排。
    • indent 表示新行相對於目前行縮排。
    • outdent 表示新行與目前行相對未輸入。
    • indentOutdent 表示插入兩個新行,一個縮排,第二個未縮排。
  • appendText. 在新的行之後和縮排之後附加的字串。
  • removeText. 要從新行縮排中移除的字元數。

屬性設定

在擴充專案中,確定您的 language-configuration.json 檔案具有下列屬性設定:

Build Action = Content
Include in VSIX = True
Copy to output = Copy always 

(選擇性)新增文法檔案

此外,您可以新增 TextMate 文法檔案,以提供語言的語法著色。 TextMate 文法是正則表達式的結構化集合,會寫入為 plist (XML) 或 JSON 檔案。 請參閱 語言文法。 如果您沒有提供語言特定的文法檔案,則會使用內建的預設設定。

若要新增自定義 TextMate 文法或主題檔案,請遵循下列步驟:

  1. 在您的延伸模組內建立名為 「Grammars」 的資料夾(或可以是您選擇的任何名稱)。

  2. 在 Grammars 資料夾內,包含任何 *.tmlanguage*.plist*.tmtheme*.json您想要提供自定義色彩化的檔案。

    提示

    .tmtheme 檔案會定義範圍如何對應至 Visual Studio 分類(具名色彩索引鍵)。 如需指引,您可以在 %ProgramFiles(x86)%\Microsoft Visual Studio\<version<>\SKU>\Common7\IDE\CommonExtensions\Microsoft\TextMate\Starterkit\Themesg 目錄中參考全域 .tmtheme 檔案

建立 pkgdef 檔案

接下來,建立檔案 .pkgdef 。 檔案 .pkgdef 包含所有註冊資訊,否則會新增至系統登錄。 如需檔案的詳細資訊pkgdef,請參閱註冊 VSPackages什麼是 pkgdef 檔案?為什麼? 在您的 pkgdef 檔案中,您應該具有檔案的路徑 language-configuration.json 和語言文法的路徑。 LSP 等語言服務會要求編輯器內容類型,並透過語言設定取得。 此資訊提供伺服器內可與開發工具通訊的語言特定智慧。 當語言服務不存在時,語言設定引擎會回復為 TextMate 文法。 您的 .pkgdef 檔案看起來應該像這樣:

[$RootKey$\TextMate\Repositories]
"AspNetCoreRazor="$PackageFolder$\Grammars

// Defines where the language configuration file for a given
// grammar name is (value of the ScopeName tag in the tmlanguage file).
[$RootKey$\TextMate\LanguageConfiguration\GrammarMapping]
"text.aspnetcorerazor"="$PackageFolder$\language-configuration.json"

// Defines where the language configuration file for a given
// language name is (partial value of the content type name).
[$RootKey$\TextMate\LanguageConfiguration\ContentTypeMapping]
"RazorLSP"="$PackageFolder$\language-configuration.json"

[$RootKey$\TextMate\LanguageConfiguration\GrammarMapping]
"text.html.basic"="$PackageFolder$\html-language-configuration.json"
"source.js"="$PackageFolder$\javascript-language-configuration.json"
"source.css"="$PackageFolder$\css-language-configuration.json"
"source.cs"="$PackageFolder$\csharp-language-configuration.json

請確定檔案的屬性 pkgdef 已設定如下:

Build Action = Content
Include in VSIX = True
Copy to output = Copy always 

若要讓 Visual Studio 能夠存取語言元件資訊, language-configuration 請在 VSIX 套件中包含 檔案。 包含此檔案表示隨附於Visual Studio延伸模組。 檔案可讓 Visual Studio 知道語言組態可供使用。 若要新增檔案,請編輯 以 vsixmanifest 新增 PKGDEF def 檔案,例如:

<Asset Type="Microsoft.VisualStudio.VsPackage" Path="Test.pkgdef"/>