英語で読む

次の方法で共有


言語構成を使用したエディター動作のカスタマイズ

言語構成を使用して言語固有構文の操作を有効にすると、Visual Studio エディターでカスタマイズされた言語固有構文を実装することができます。 言語サーバーを使用した場合と比較して、言語構成を使用すると、すべての操作がローカルで行われるため、パフォーマンスを向上させることができます。

言語構成とは

Visual Studio には、言語拡張機能を使用したさまざまなプログラミング言語用のインテリジェントな編集機能が用意されています。 言語構成は、言語サーバー プロトコル (LSP) を使用するサーバーを補完します。また、Visual Studio エディターが、LSP サーバーに対して非同期クエリを実行するための遅延なしに、書式設定、色付け、および完成の決定を行うことができるようにする宣言型データを提供します。 宣言型言語機能は、構成ファイルで定義されます。 たとえば、Visual Studio にバンドルされている HTML、CSS、および typescript-basic の拡張機能には、次の宣言型言語機能のサブセットが用意されています。

  • 構文の強調表示
  • スニペット補完
  • 角かっこの一致
  • 角かっこの自動閉じ
  • コメント切り替え
  • 自動インデント

Visual Studio には、拡張機能を使用して任意のプログラミング言語の言語構成を定義するための機能が用意されています。 言語構成ファイルは、コメント切り替え、角かっこの一致や取り囲みなど、基本的な編集機能を制御します。

言語構成を使用すると、次のことに役立ちます。

  • ユーザー入力の同期作業
  • 簡潔さ: 正規表現を含む短い JSON ファイルは、複雑なアルゴリズムよりも保守が簡単です。
  • 移植性: Visual Studio Code と Visual Studio の間で変更を必要としない、または最小限に抑えます。

また、言語構成ファイルを使用すると、読みやすい JSON ファイルを使用して基本的なリファクタリング機能をサポートするように Visual Studio を簡単に拡張できます。

Visual Studio 拡張機能に言語構成のサポートを追加する

Visual Studio 拡張機能に言語構成のサポートを追加する作業には、次の 3 つの部分があります。

  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*[\\)\\}\\]].*$"
    }
  }

構成設定

以降のセクションで、言語構成ファイルで使用できる設定について説明していきます。

コメント切り替え

言語構成ファイルには、コメント切り替え用の 2 つのコマンドが用意されています。 [行コメントの切り替え][ブロック コメントの切り替え]comments.blockCommentcomments.lineComment を指定して、Visual Studio で行/ブロックをコメント アウトする方法を制御できます。

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

この設定は、Ctrl+K キー、Ctrl+C キーを押したときの Visual Studio テキスト エディターの動作に影響を及ぼします。

角かっこの定義

カーソルをここで定義されている角かっこに移動すると、その角かっこが一致するペアと共に強調表示されます。

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

Visual Studio の [ツール] > [オプション] ダイアログの関連する設定は、[テキスト エディター]、[全般]、[表示] の順にクリックして表示される [中かっこペアの色付けを有効にする] チェックボックスです。

自動閉じ

'」と入力すると、1 つのペアの一重引用符が作成され、カーソルが '|' の中央に配置されます。 このセクションでは、そのようなペアを定義します。

{
  "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": [ ["{", "}"], ["[", "]"] ]
}
前置での自動閉じ

既定では、カーソルの直後に空白がある場合にのみ、ペアが自動的に閉じられます。 したがって、次の JSX コードに「{」と入力すると、自動閉じは実行されません。

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

ただし、この定義はその動作をオーバーライドします。

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

ここで、「{」を「>」の直前に入力すると、「}」を使用して自動的に閉じられます。

自動取り囲み

Visual Studio で範囲を選択し、左角かっこを入力すると、選択したコンテンツが 1 つのペアの角かっこで囲まれます。 この機能は「自動取り囲み」と呼ばれ、ここで特定の言語の自動取り囲みペアを定義できます。

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

Visual Studio の[ツール]> [オプション] の関連する設定は、[テキスト エディター]、[全般]、[表示] の順にクリックして表示される [引用符または角かっこを入力すると、選択範囲が自動的に囲まれます] チェックボックスです。

ワード パターン

wordPattern は、プログラミング言語で単語と見なされる内容を定義します。 コード候補機能では、この設定を使用して、単語の境界を判断します (wordPatternが設定されている場合)。

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

インデント ルール

indentationRules は、行の入力、貼り付け、移動を行ったとき、または Ctrl+KCtrl+D (ドキュメントのフォーマット)、および Ctrl+KCtrl+F (選択範囲のフォーマット) を使用してテキストの書式設定を行ったときに、エディターが現在の行または次の行のインデントをどのように調整するのかを定義します。

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

たとえば、「if (true) {」は「increaseIndentPattern」に一致します。この場合、カーソルを左角かっこの直後に当てた後にEnter キーを押すと{、エディターは自動的に 1 回インデントし、コードは最終的に次のようになります。

if (true) {
  console.log();

increaseIndentPattern および decreaseIndentPatter 以外にも、2 つのインデント ルールがあります。

  • indentNextLinePattern - いずれかの行がこのパターンと一致する場合は、その後の次の行のみを 1 回インデントする必要があります。
  • 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 キーを押すと、カーソルの前、後、または 1 行上のテキストが、次のプロパティに対してチェックされます。

  • beforeText (必須) カーソルの前のテキストと一致する正規表現 (現在の行に限定)
  • afterText. カーソルの後のテキストと一致する正規表現 (現在の行に限定)
  • previousLineText. カーソルの 1 行上のテキストに一致する正規表現

指定されたすべてのプロパティが一致する場合、ルールは一致していると見なされ、onEnterRules はそれ以上評価されません。 onEnterRule は次のアクションを指定できます。

  • indent (必須) none, indent, outdent, indentOutdent のいずれか
    • none は、新しい行が現在の行のインデントを継承することを意味します。
    • indent は、新しい行が現在の行を基準にインデントされることを意味します。
    • outdent は、新しい行が現在の行を基準にインデントされないことを意味します。
    • indentOutdent は、2 つの新しい行が挿入され、1 行目はインデントされ、2 行目はインデントされないことを意味します。
  • 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 ファイルの詳細については、「VSPackage の登録」および「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"/>