Bagaimana cara menggunakan php exec jangan menunggu

Seperti yang telah Anda lihat di topik Fitur Bahasa Terprogram, dimungkinkan untuk mengimplementasikan Fitur Bahasa dengan langsung menggunakan

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
9 API. Ekstensi Server Bahasa, bagaimanapun, menyediakan cara alternatif untuk mengimplementasikan dukungan bahasa tersebut

Topik ini

  • Menjelaskan manfaat Ekstensi Server Bahasa
  • Memandu Anda membangun Server Bahasa menggunakan perpustakaan
    "configuration": {
        "type": "object",
        "title": "Example configuration",
        "properties": {
            "languageServerExample.maxNumberOfProblems": {
                "scope": "resource",
                "type": "number",
                "default": 100,
                "description": "Controls the maximum number of problems produced by the server."
            }
        }
    }
    
    0. Anda juga dapat melompat langsung ke kode di lsp-sample

Mengapa Server Bahasa?

Server Bahasa adalah jenis khusus dari ekstensi Kode Visual Studio yang memberdayakan pengalaman pengeditan untuk banyak bahasa pemrograman. Dengan Server Bahasa, Anda dapat mengimplementasikan pelengkapan otomatis, pemeriksaan kesalahan (diagnostik), lompat ke definisi, dan banyak fitur bahasa lainnya yang didukung dalam Kode VS

Namun, saat mengimplementasikan dukungan untuk fitur bahasa di VS Code, kami menemukan tiga masalah umum

Pertama, Server Bahasa biasanya diimplementasikan dalam bahasa pemrograman asli mereka, dan itu menghadirkan tantangan dalam mengintegrasikannya dengan VS Code, yang memiliki Node. waktu proses js

Selain itu, fitur bahasa dapat menjadi intensif sumber daya. Misalnya, untuk memvalidasi file dengan benar, Language Server perlu mengurai sejumlah besar file, membangun Pohon Sintaks Abstrak untuknya, dan melakukan analisis program statis. Operasi tersebut dapat menyebabkan penggunaan CPU dan memori yang signifikan dan kami perlu memastikan bahwa kinerja VS Code tetap tidak terpengaruh

Terakhir, mengintegrasikan beberapa alat bahasa dengan banyak editor kode dapat melibatkan upaya yang signifikan. Dari perspektif alat bahasa, mereka perlu beradaptasi dengan editor kode dengan API yang berbeda. Dari sudut pandang editor kode, mereka tidak dapat mengharapkan API seragam dari perkakas bahasa. Hal ini membuat implementasi dukungan bahasa untuk

"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
1 bahasa di
"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
2 editor kode karya
"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
3

Untuk mengatasi masalah tersebut, Microsoft menetapkan Protokol Server Bahasa, yang menstandarkan komunikasi antara perkakas bahasa dan editor kode. Dengan cara ini, Server Bahasa dapat diimplementasikan dalam bahasa apa pun dan dijalankan dalam prosesnya sendiri untuk menghindari biaya kinerja, karena mereka berkomunikasi dengan editor kode melalui Protokol Server Bahasa. Selain itu, alat bahasa yang sesuai dengan LSP dapat diintegrasikan dengan beberapa editor kode yang sesuai dengan LSP, dan editor kode yang sesuai dengan LSP dapat dengan mudah mengambil beberapa alat bahasa yang sesuai dengan LSP. LSP adalah kemenangan bagi penyedia perkakas bahasa dan vendor editor kode

Bagaimana cara menggunakan php exec jangan menunggu

Dalam panduan ini, kita akan

  • Jelaskan cara membuat ekstensi Language Server di VS Code menggunakan Node SDK yang disediakan
  • Jelaskan cara menjalankan, men-debug, mencatat, dan menguji ekstensi Server Bahasa
  • Arahkan Anda ke beberapa topik lanjutan di Server Bahasa

Menerapkan Server Bahasa

Ringkasan

Dalam VS Code, server bahasa memiliki dua bagian

  • Klien Bahasa. Ekstensi Kode VS normal yang ditulis dalam JavaScript / TypeScript. Ekstensi ini memiliki akses ke semua VS Code Namespace API
  • Server Bahasa. Alat analisis bahasa berjalan dalam proses terpisah

Seperti yang dinyatakan secara singkat di atas, ada dua manfaat menjalankan Server Bahasa dalam proses terpisah

  • Alat analisis dapat diimplementasikan dalam bahasa apa pun, asalkan dapat berkomunikasi dengan Klien Bahasa mengikuti Protokol Server Bahasa
  • Karena alat analisis bahasa seringkali berat pada penggunaan CPU dan Memori, menjalankannya dalam proses terpisah akan menghindari biaya kinerja

Berikut adalah ilustrasi VS Code yang menjalankan dua ekstensi Server Bahasa. Klien Bahasa HTML dan Klien Bahasa PHP adalah ekstensi Kode VS normal yang ditulis dalam TypeScript. Masing-masing menginstansiasi Server Bahasa yang sesuai dan berkomunikasi dengan mereka melalui LSP. Meskipun Server Bahasa PHP ditulis dalam PHP, ia masih dapat berkomunikasi dengan Klien Bahasa PHP melalui LSP

Bagaimana cara menggunakan php exec jangan menunggu

Panduan ini akan mengajari Anda cara membangun Klien / Server Bahasa menggunakan Node SDK kami. Dokumen yang tersisa mengasumsikan bahwa Anda sudah familiar dengan VS Code Extension API

Sampel LSP - Server Bahasa sederhana untuk file teks biasa

Mari buat ekstensi Server Bahasa sederhana yang mengimplementasikan pelengkapan otomatis dan diagnostik untuk file teks biasa. Kami juga akan membahas sinkronisasi konfigurasi antara Klien / Server

Jika Anda lebih suka langsung masuk ke kode

  • dll-sampel. Kode sumber yang sangat terdokumentasi untuk panduan ini
  • lsp-multi-server-sampel. Versi lsp-sample yang sangat terdokumentasi dan canggih yang memulai instance server yang berbeda per folder ruang kerja untuk mendukung fitur ruang kerja multi-root di VS Code

Kloning repositori Microsoft/vscode-extension-samples dan buka sampelnya

> git clone https://github.com/microsoft/vscode-extension-samples.git
> cd vscode-extension-samples/lsp-sample
> npm install
> npm run compile
> code .

Di atas menginstal semua dependensi dan membuka ruang kerja lsp-sample yang berisi kode klien dan server. Berikut adalah gambaran kasar dari struktur lsp-sample

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point

Menjelaskan 'Klien Bahasa'

Pertama mari kita lihat

"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
_4, yang menjelaskan kemampuan Klien Bahasa. Ada dua bagian yang menarik

Pertama, lihat bagiannya

"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
_

Bagian ini menyumbangkan

"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
5 pengaturan ke VS Code. Contoh ini akan menjelaskan bagaimana pengaturan ini dikirim ke server bahasa saat startup dan setiap perubahan pengaturan

Catatan. Jika ekstensi Anda kompatibel dengan versi Kode VS sebelum 1. 74. 0, Anda harus menyatakan

"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
_7 di bidang
"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
8 dari
"configuration": {
    "type": "object",
    "title": "Example configuration",
    "properties": {
        "languageServerExample.maxNumberOfProblems": {
            "scope": "resource",
            "type": "number",
            "default": 100,
            "description": "Controls the maximum number of problems produced by the server."
        }
    }
}
4 untuk memberi tahu VS Code untuk mengaktifkan ekstensi segera setelah file teks biasa dibuka (misalnya file dengan ekstensi
"activationEvents": []
0)

"activationEvents": []

Kode sumber Klien Bahasa aktual dan

"activationEvents": []
1 yang sesuai ada di folder
"activationEvents": []
2. Bagian yang menarik dalam file
"activationEvents": []
3 adalah ia mereferensikan API host ekstensi
"activationEvents": []
4 melalui bidang
"activationEvents": []
5 dan menambahkan dependensi ke pustaka
"activationEvents": []
6

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}

Seperti yang disebutkan, klien diimplementasikan sebagai ekstensi Kode VS normal, dan memiliki akses ke semua API ruang nama Kode VS

Di bawah ini adalah konten dari ekstensi yang sesuai. ts, yang merupakan entri dari ekstensi lsp-sample

import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}

Menjelaskan 'Server Bahasa'

Catatan. Implementasi 'Server' yang digandakan dari repositori GitHub memiliki implementasi panduan terakhir. Untuk mengikuti panduan ini, Anda dapat membuat

"activationEvents": []
7 baru atau mengubah konten versi kloning

Dalam contoh, server juga diimplementasikan dalam TypeScript dan dieksekusi menggunakan Node. js. Karena VS Code sudah dikirimkan dengan Node. js runtime, tidak perlu menyediakan sendiri, kecuali jika Anda memiliki persyaratan khusus untuk runtime

Kode sumber untuk Server Bahasa ada di

"activationEvents": []
8. Bagian yang menarik di file ________13______1 server adalah

"dependencies": {
    "vscode-languageserver": "^7.0.0",
    "vscode-languageserver-textdocument": "^1.0.1"
}

Ini menarik

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
_0 perpustakaan

Di bawah ini adalah implementasi server yang menggunakan pengelola dokumen teks yang disediakan yang menyinkronkan dokumen teks dengan selalu mengirimkan delta inkremental dari VS Code ke server

import {
  createConnection,
  TextDocuments,
  Diagnostic,
  DiagnosticSeverity,
  ProposedFeatures,
  InitializeParams,
  DidChangeConfigurationNotification,
  CompletionItem,
  CompletionItemKind,
  TextDocumentPositionParams,
  TextDocumentSyncKind,
  InitializeResult
} from 'vscode-languageserver/node';

import { TextDocument } from 'vscode-languageserver-textdocument';

// Create a connection for the server, using Node's IPC as a transport.
// Also include all preview / proposed LSP features.
let connection = createConnection(ProposedFeatures.all);

// Create a simple text document manager.
let documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);

let hasConfigurationCapability: boolean = false;
let hasWorkspaceFolderCapability: boolean = false;
let hasDiagnosticRelatedInformationCapability: boolean = false;

connection.onInitialize((params: InitializeParams) => {
  let capabilities = params.capabilities;

  // Does the client support the `workspace/configuration` request?
  // If not, we fall back using global settings.
  hasConfigurationCapability = !!(
    capabilities.workspace && !!capabilities.workspace.configuration
  );
  hasWorkspaceFolderCapability = !!(
    capabilities.workspace && !!capabilities.workspace.workspaceFolders
  );
  hasDiagnosticRelatedInformationCapability = !!(
    capabilities.textDocument &&
    capabilities.textDocument.publishDiagnostics &&
    capabilities.textDocument.publishDiagnostics.relatedInformation
  );

  const result: InitializeResult = {
    capabilities: {
      textDocumentSync: TextDocumentSyncKind.Incremental,
      // Tell the client that this server supports code completion.
      completionProvider: {
        resolveProvider: true
      }
    }
  };
  if (hasWorkspaceFolderCapability) {
    result.capabilities.workspace = {
      workspaceFolders: {
        supported: true
      }
    };
  }
  return result;
});

connection.onInitialized(() => {
  if (hasConfigurationCapability) {
    // Register for all configuration changes.
    connection.client.register(DidChangeConfigurationNotification.type, undefined);
  }
  if (hasWorkspaceFolderCapability) {
    connection.workspace.onDidChangeWorkspaceFolders(_event => {
      connection.console.log('Workspace folder change event received.');
    });
  }
});

// The example settings
interface ExampleSettings {
  maxNumberOfProblems: number;
}

// The global settings, used when the `workspace/configuration` request is not supported by the client.
// Please note that this is not the case when using this server with the client provided in this example
// but could happen with other clients.
const defaultSettings: ExampleSettings = { maxNumberOfProblems: 1000 };
let globalSettings: ExampleSettings = defaultSettings;

// Cache the settings of all open documents
let documentSettings: Map<string, Thenable<ExampleSettings>> = new Map();

connection.onDidChangeConfiguration(change => {
  if (hasConfigurationCapability) {
    // Reset all cached document settings
    documentSettings.clear();
  } else {
    globalSettings = <ExampleSettings>(
      (change.settings.languageServerExample || defaultSettings)
    );
  }

  // Revalidate all open text documents
  documents.all().forEach(validateTextDocument);
});

function getDocumentSettings(resource: string): Thenable<ExampleSettings> {
  if (!hasConfigurationCapability) {
    return Promise.resolve(globalSettings);
  }
  let result = documentSettings.get(resource);
  if (!result) {
    result = connection.workspace.getConfiguration({
      scopeUri: resource,
      section: 'languageServerExample'
    });
    documentSettings.set(resource, result);
  }
  return result;
}

// Only keep settings for open documents
documents.onDidClose(e => {
  documentSettings.delete(e.document.uri);
});

// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent(change => {
  validateTextDocument(change.document);
});

async function validateTextDocument(textDocument: TextDocument): Promise<void> {
  // In this simple example we get the settings for every validate run.
  let settings = await getDocumentSettings(textDocument.uri);

  // The validator creates diagnostics for all uppercase words length 2 and more
  let text = textDocument.getText();
  let pattern = /\b[A-Z]{2,}\b/g;
  let m: RegExpExecArray | null;

  let problems = 0;
  let diagnostics: Diagnostic[] = [];
  while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
    problems++;
    let diagnostic: Diagnostic = {
      severity: DiagnosticSeverity.Warning,
      range: {
        start: textDocument.positionAt(m.index),
        end: textDocument.positionAt(m.index + m[0].length)
      },
      message: `${m[0]} is all uppercase.`,
      source: 'ex'
    };
    if (hasDiagnosticRelatedInformationCapability) {
      diagnostic.relatedInformation = [
        {
          location: {
            uri: textDocument.uri,
            range: Object.assign({}, diagnostic.range)
          },
          message: 'Spelling matters'
        },
        {
          location: {
            uri: textDocument.uri,
            range: Object.assign({}, diagnostic.range)
          },
          message: 'Particularly for names'
        }
      ];
    }
    diagnostics.push(diagnostic);
  }

  // Send the computed diagnostics to VS Code.
  connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}

connection.onDidChangeWatchedFiles(_change => {
  // Monitored files have change in VS Code
  connection.console.log('We received a file change event');
});

// This handler provides the initial list of the completion items.
connection.onCompletion(
  (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
    // The pass parameter contains the position of the text document in
    // which code complete got requested. For the example we ignore this
    // info and always provide the same completion items.
    return [
      {
        label: 'TypeScript',
        kind: CompletionItemKind.Text,
        data: 1
      },
      {
        label: 'JavaScript',
        kind: CompletionItemKind.Text,
        data: 2
      }
    ];
  }
);

// This handler resolves additional information for the item selected in
// the completion list.
connection.onCompletionResolve(
  (item: CompletionItem): CompletionItem => {
    if (item.data === 1) {
      item.detail = 'TypeScript details';
      item.documentation = 'TypeScript documentation';
    } else if (item.data === 2) {
      item.detail = 'JavaScript details';
      item.documentation = 'JavaScript documentation';
    }
    return item;
  }
);

// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);

// Listen on the connection
connection.listen();

Menambahkan Validasi Sederhana

Untuk menambahkan validasi dokumen ke server, kami menambahkan pendengar ke pengelola dokumen teks yang dipanggil setiap kali konten dokumen teks berubah. Terserah server untuk memutuskan kapan waktu terbaik untuk memvalidasi dokumen. Dalam implementasi contoh, server memvalidasi dokumen teks biasa dan menandai semua kemunculan kata yang menggunakan HURUF BESAR SEMUA. Cuplikan kode yang sesuai terlihat seperti ini

// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent(async change => {
  let textDocument = change.document;
  // In this simple example we get the settings for every validate run.
  let settings = await getDocumentSettings(textDocument.uri);

  // The validator creates diagnostics for all uppercase words length 2 and more
  let text = textDocument.getText();
  let pattern = /\b[A-Z]{2,}\b/g;
  let m: RegExpExecArray | null;

  let problems = 0;
  let diagnostics: Diagnostic[] = [];
  while ((m = pattern.exec(text)) && problems < settings.maxNumberOfProblems) {
    problems++;
    let diagnostic: Diagnostic = {
      severity: DiagnosticSeverity.Warning,
      range: {
        start: textDocument.positionAt(m.index),
        end: textDocument.positionAt(m.index + m[0].length)
      },
      message: `${m[0]} is all uppercase.`,
      source: 'ex'
    };
    if (hasDiagnosticRelatedInformationCapability) {
      diagnostic.relatedInformation = [
        {
          location: {
            uri: textDocument.uri,
            range: Object.assign({}, diagnostic.range)
          },
          message: 'Spelling matters'
        },
        {
          location: {
            uri: textDocument.uri,
            range: Object.assign({}, diagnostic.range)
          },
          message: 'Particularly for names'
        }
      ];
    }
    diagnostics.push(diagnostic);
  }

  // Send the computed diagnostics to VS Code.
  connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});

Tip dan Trik Diagnostik

  • Jika posisi awal dan akhir sama, VS Code akan menggarisbawahi dengan coretan kata pada posisi tersebut
  • Jika ingin menggarisbawahi dengan coretan hingga akhir baris, maka atur karakter posisi akhir menjadi Angka. MAX_VALUE

Untuk menjalankan Server Bahasa, lakukan langkah-langkah berikut

  • Tekan ⇧⌘B (Windows, Linux Ctrl+Shift+B) untuk memulai tugas build. Tugas mengkompilasi klien dan server.
  • Buka tampilan Run, pilih konfigurasi peluncuran Launch Client, dan tekan tombol Start Debugging untuk meluncurkan instance Extension Development Host tambahan dari VS Code yang mengeksekusi kode ekstensi
  • Buat file
    "engines": {
        "vscode": "^1.52.0"
    },
    "dependencies": {
        "vscode-languageclient": "^7.0.0"
    }
    
    _1 di folder root dan rekatkan konten berikut
TypeScript lets you write JavaScript the way you really want to.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
ANY browser. ANY host. ANY OS. Open Source.

Instance Extension Development Host kemudian akan terlihat seperti ini

Bagaimana cara menggunakan php exec jangan menunggu

Debugging baik Klien dan Server

Men-debug kode klien semudah men-debug ekstensi normal. Setel breakpoint dalam kode klien dan debug ekstensi dengan menekan F5 .

Bagaimana cara menggunakan php exec jangan menunggu

Karena server dimulai oleh

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
2 yang berjalan di ekstensi (klien), kita perlu melampirkan debugger ke server yang sedang berjalan. Untuk melakukannya, alihkan ke tampilan Jalankan dan Debug dan pilih konfigurasi peluncuran Lampirkan ke Server dan tekan F5 . Ini akan melampirkan debugger ke server.

Bagaimana cara menggunakan php exec jangan menunggu

Dukungan Pencatatan untuk Server Bahasa

Jika Anda menggunakan

"activationEvents": []
6 untuk mengimplementasikan klien, Anda dapat menentukan pengaturan
"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
4 yang menginstruksikan Klien untuk mencatat komunikasi antara Klien/Server Bahasa ke saluran
"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
5 Klien Bahasa

Untuk lsp-sample, Anda dapat mengatur pengaturan ini.

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
6. Sekarang menuju ke saluran "Contoh Server Bahasa". Anda harus melihat log

Bagaimana cara menggunakan php exec jangan menunggu

Menggunakan Pengaturan Konfigurasi di Server

Saat menulis bagian klien dari ekstensi, kami telah menentukan pengaturan untuk mengontrol jumlah maksimum masalah yang dilaporkan. Kami juga menulis kode di sisi server untuk membaca pengaturan ini dari klien

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
0

Satu-satunya hal yang perlu kita lakukan sekarang adalah mendengarkan perubahan konfigurasi di sisi server dan jika pengaturan berubah, validasi ulang dokumen teks yang terbuka. Agar dapat menggunakan kembali logika validasi penanganan peristiwa perubahan dokumen, kami mengekstrak kode menjadi fungsi

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
7 dan memodifikasi kode untuk menghormati variabel
"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
8

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_1

Penanganan perubahan konfigurasi dilakukan dengan menambahkan notification handler untuk perubahan konfigurasi pada koneksi. Kode yang sesuai terlihat seperti ini

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_2

Memulai kembali klien dan mengubah pengaturan ke laporan maksimum 1 masalah menghasilkan validasi berikut

Bagaimana cara menggunakan php exec jangan menunggu

Menambahkan fitur bahasa tambahan

Fitur menarik pertama yang biasanya diterapkan oleh server bahasa adalah validasi dokumen. Dalam hal ini, bahkan linter dianggap sebagai server bahasa dan dalam VS Code linter biasanya diimplementasikan sebagai server bahasa (lihat contoh eslint dan jshint). Tetapi ada lebih banyak lagi ke server bahasa. Mereka dapat memberikan penyelesaian kode, Temukan Semua Referensi, atau Buka Definisi. Kode contoh di bawah menambahkan penyelesaian kode ke server. Ini mengusulkan dua kata 'TypeScript' dan 'JavaScript'

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_3

Bidang

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
_9 digunakan untuk secara unik mengidentifikasi item penyelesaian dalam penangan penyelesaian. Properti data transparan untuk protokol. Karena protokol penerusan pesan yang mendasari berbasis JSON, bidang data hanya boleh menyimpan data yang dapat diserialisasi ke dan dari JSON

Yang kurang hanyalah memberi tahu VS Code bahwa server mendukung permintaan penyelesaian kode. Untuk melakukannya, tandai kemampuan yang sesuai di penangan inisialisasi

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_4

Tangkapan layar di bawah menunjukkan kode lengkap yang berjalan pada file teks biasa

Bagaimana cara menggunakan php exec jangan menunggu

Menguji Server Bahasa

Untuk membuat Server Bahasa berkualitas tinggi, kita perlu membuat rangkaian pengujian yang bagus yang mencakup fungsinya. Ada dua cara umum untuk menguji Server Bahasa

  • Tes Satuan. Ini berguna jika Anda ingin menguji fungsionalitas tertentu di Server Bahasa dengan meniru semua informasi yang dikirim ke sana. Server Bahasa HTML / CSS / JSON VS Code menggunakan pendekatan ini untuk pengujian. Modul LSP npm juga menggunakan pendekatan ini. Lihat di sini untuk beberapa pengujian unit yang ditulis menggunakan modul protokol npm
  • Pengujian Ujung-ke-Ujung. Ini mirip dengan tes ekstensi Kode VS. Manfaat dari pendekatan ini adalah ia menjalankan pengujian dengan membuat instance VS Code dengan ruang kerja, membuka file, mengaktifkan Klien/Server Bahasa, dan menjalankan perintah VS Code. Pendekatan ini lebih unggul jika Anda memiliki file, pengaturan, atau dependensi (seperti
    import * as path from 'path';
    import { workspace, ExtensionContext } from 'vscode';
    
    import {
      LanguageClient,
      LanguageClientOptions,
      ServerOptions,
      TransportKind
    } from 'vscode-languageclient/node';
    
    let client: LanguageClient;
    
    export function activate(context: ExtensionContext) {
      // The server is implemented in node
      let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
      // The debug options for the server
      // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
      let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
    
      // If the extension is launched in debug mode then the debug server options are used
      // Otherwise the run options are used
      let serverOptions: ServerOptions = {
        run: { module: serverModule, transport: TransportKind.ipc },
        debug: {
          module: serverModule,
          transport: TransportKind.ipc,
          options: debugOptions
        }
      };
    
      // Options to control the language client
      let clientOptions: LanguageClientOptions = {
        // Register the server for plain text documents
        documentSelector: [{ scheme: 'file', language: 'plaintext' }],
        synchronize: {
          // Notify the server about file changes to '.clientrc files contained in the workspace
          fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
        }
      };
    
      // Create the language client and start the client.
      client = new LanguageClient(
        'languageServerExample',
        'Language Server Example',
        serverOptions,
        clientOptions
      );
    
      // Start the client. This will also launch the server
      client.start();
    }
    
    export function deactivate(): Thenable<void> | undefined {
      if (!client) {
        return undefined;
      }
      return client.stop();
    }
    
    0) yang sulit atau tidak mungkin untuk ditiru. Ekstensi Python yang populer menggunakan pendekatan ini untuk pengujian

Dimungkinkan untuk melakukan Tes Unit dalam kerangka pengujian pilihan Anda. Di sini kami menjelaskan cara melakukan pengujian End-to-End untuk Ekstensi Server Bahasa

Buka

import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
1, dan Anda dapat menemukan target pengujian
import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
2

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
5

Jika Anda menjalankan target debug ini, itu akan meluncurkan instance Kode VS dengan

import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
3 sebagai ruang kerja aktif. Kode VS kemudian akan melanjutkan untuk menjalankan semua tes di
import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
4. Sebagai tip debugging, Anda dapat mengatur breakpoint dalam file TypeScript di
import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
4 dan mereka akan terkena

Mari kita lihat file

import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
6

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_6

Dalam pengujian ini, kami

  • Aktifkan ekstensi
  • Jalankan perintah
    import * as path from 'path';
    import { workspace, ExtensionContext } from 'vscode';
    
    import {
      LanguageClient,
      LanguageClientOptions,
      ServerOptions,
      TransportKind
    } from 'vscode-languageclient/node';
    
    let client: LanguageClient;
    
    export function activate(context: ExtensionContext) {
      // The server is implemented in node
      let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
      // The debug options for the server
      // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
      let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
    
      // If the extension is launched in debug mode then the debug server options are used
      // Otherwise the run options are used
      let serverOptions: ServerOptions = {
        run: { module: serverModule, transport: TransportKind.ipc },
        debug: {
          module: serverModule,
          transport: TransportKind.ipc,
          options: debugOptions
        }
      };
    
      // Options to control the language client
      let clientOptions: LanguageClientOptions = {
        // Register the server for plain text documents
        documentSelector: [{ scheme: 'file', language: 'plaintext' }],
        synchronize: {
          // Notify the server about file changes to '.clientrc files contained in the workspace
          fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
        }
      };
    
      // Create the language client and start the client.
      client = new LanguageClient(
        'languageServerExample',
        'Language Server Example',
        serverOptions,
        clientOptions
      );
    
      // Start the client. This will also launch the server
      client.start();
    }
    
    export function deactivate(): Thenable<void> | undefined {
      if (!client) {
        return undefined;
      }
      return client.stop();
    }
    
    _7 dengan URI dan posisi untuk mensimulasikan pemicu penyelesaian
  • Nyatakan item penyelesaian yang dikembalikan dengan item penyelesaian yang kami harapkan

Mari selami lebih dalam fungsi

import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
8. Ini didefinisikan dalam
import * as path from 'path';
import { workspace, ExtensionContext } from 'vscode';

import {
  LanguageClient,
  LanguageClientOptions,
  ServerOptions,
  TransportKind
} from 'vscode-languageclient/node';

let client: LanguageClient;

export function activate(context: ExtensionContext) {
  // The server is implemented in node
  let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
  // The debug options for the server
  // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
  let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };

  // If the extension is launched in debug mode then the debug server options are used
  // Otherwise the run options are used
  let serverOptions: ServerOptions = {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: {
      module: serverModule,
      transport: TransportKind.ipc,
      options: debugOptions
    }
  };

  // Options to control the language client
  let clientOptions: LanguageClientOptions = {
    // Register the server for plain text documents
    documentSelector: [{ scheme: 'file', language: 'plaintext' }],
    synchronize: {
      // Notify the server about file changes to '.clientrc files contained in the workspace
      fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
    }
  };

  // Create the language client and start the client.
  client = new LanguageClient(
    'languageServerExample',
    'Language Server Example',
    serverOptions,
    clientOptions
  );

  // Start the client. This will also launch the server
  client.start();
}

export function deactivate(): Thenable<void> | undefined {
  if (!client) {
    return undefined;
  }
  return client.stop();
}
_9

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_7

Di bagian aktivasi, kami

  • Dapatkan ekstensi menggunakan
    "dependencies": {
        "vscode-languageserver": "^7.0.0",
        "vscode-languageserver-textdocument": "^1.0.1"
    }
    
    _0, sebagaimana didefinisikan dalam
    "activationEvents": []
    
    1
  • Buka dokumen yang ditentukan, dan tampilkan di editor teks aktif
  • Tidur selama 2 detik, jadi kami yakin Server Bahasa sudah dipakai

Setelah persiapan, kita dapat menjalankan Perintah Kode VS yang sesuai dengan setiap fitur bahasa, dan menegaskan hasil yang dikembalikan

Ada satu tes lagi yang mencakup fitur diagnostik yang baru saja kami implementasikan. Lihat di

"dependencies": {
    "vscode-languageserver": "^7.0.0",
    "vscode-languageserver-textdocument": "^1.0.1"
}
_2

Topik Lanjutan

Sejauh ini, panduan ini tertutup

  • Tinjauan singkat tentang Server Bahasa dan Protokol Server Bahasa
  • Arsitektur ekstensi Server Bahasa di VS Code
  • Ekstensi lsp-sample, dan cara mengembangkan/men-debug/memeriksa/mengujinya

Ada beberapa topik lebih lanjut yang tidak dapat kami masukkan ke dalam panduan ini. Kami akan menyertakan tautan ke sumber daya ini untuk mempelajari lebih lanjut pengembangan Server Bahasa

Fitur Server Bahasa tambahan

Fitur bahasa berikut saat ini didukung di server bahasa bersama dengan penyelesaian kode

  • Sorotan Dokumen. menyoroti semua simbol 'sama' dalam dokumen teks
  • Arahkan. memberikan informasi hover untuk simbol yang dipilih dalam dokumen teks
  • Bantuan Tanda Tangan. memberikan bantuan tanda tangan untuk simbol yang dipilih dalam dokumen teks
  • Definisi Goto. menyediakan dukungan definisi untuk simbol yang dipilih dalam dokumen teks
  • Definisi Tipe Goto. menyediakan dukungan definisi tipe/antarmuka untuk simbol yang dipilih dalam dokumen teks
  • Implementasi Goto. menyediakan dukungan definisi implementasi untuk simbol yang dipilih dalam dokumen teks
  • Temukan Referensi. menemukan semua referensi proyek untuk simbol yang dipilih dalam dokumen teks
  • Daftar Simbol Dokumen. mencantumkan semua simbol yang didefinisikan dalam dokumen teks
  • Daftar Simbol Ruang Kerja. daftar semua simbol proyek-lebar
  • Tindakan Kode. menghitung perintah untuk menjalankan (biasanya memperindah/memfaktor ulang) untuk dokumen dan rentang teks tertentu
  • CodeLens. menghitung statistik CodeLens untuk dokumen teks tertentu
  • Pemformatan Dokumen. ini termasuk pemformatan seluruh dokumen, rentang dokumen, dan pemformatan berdasarkan jenis
  • Ganti nama. mengganti nama simbol di seluruh proyek
  • Tautan Dokumen. menghitung dan menyelesaikan tautan di dalam dokumen
  • Warna Dokumen. menghitung dan menyelesaikan warna di dalam dokumen untuk menyediakan pemilih warna di editor

Topik Fitur Bahasa Terprogram menjelaskan setiap fitur bahasa di atas dan memberikan panduan tentang cara mengimplementasikannya baik melalui protokol server bahasa atau dengan menggunakan API ekstensibilitas langsung dari ekstensi Anda

Sinkronisasi Dokumen Teks Tambahan

Contoh ini menggunakan pengelola dokumen teks sederhana yang disediakan oleh modul

"engines": {
    "vscode": "^1.52.0"
},
"dependencies": {
    "vscode-languageclient": "^7.0.0"
}
0 untuk menyinkronkan dokumen antara VS Code dan server bahasa

Ini memiliki dua kelemahan

  • Banyak data yang ditransfer karena seluruh isi dokumen teks dikirim ke server berulang kali
  • Jika perpustakaan bahasa yang ada digunakan, perpustakaan tersebut biasanya mendukung pembaruan dokumen tambahan untuk menghindari penguraian yang tidak perlu dan pembuatan pohon sintaksis abstrak

Oleh karena itu protokol mendukung sinkronisasi dokumen tambahan juga

Untuk memanfaatkan sinkronisasi dokumen inkremental, server perlu menginstal tiga penangan notifikasi

  • onDidOpenTextDocument. dipanggil saat dokumen teks dibuka di VS Code
  • onDidChangeTextDocument. dipanggil ketika konten dokumen teks berubah dalam VS Code
  • onDidCloseTextDocument. dipanggil ketika dokumen teks ditutup dalam VS Code

Di bawah ini adalah cuplikan kode yang mengilustrasikan cara mengaitkan penangan notifikasi ini pada koneksi dan cara mengembalikan kemampuan yang tepat saat menginisialisasi

.
├── client // Language Client
│   ├── src
│   │   ├── test // End to End tests for Language Client / Server
│   │   └── extension.ts // Language Client entry point
├── package.json // The extension manifest
└── server // Language Server
    └── src
        └── server.ts // Language Server entry point
_8

Menggunakan VS Code API secara langsung untuk mengimplementasikan Fitur Bahasa

Meskipun Server Bahasa memiliki banyak manfaat, mereka bukan satu-satunya pilihan untuk memperluas kemampuan pengeditan Kode VS. Jika Anda ingin menambahkan beberapa fitur bahasa sederhana untuk jenis dokumen, pertimbangkan untuk menggunakan

"dependencies": {
    "vscode-languageserver": "^7.0.0",
    "vscode-languageserver-textdocument": "^1.0.1"
}
4 sebagai opsi

Ini adalah

"dependencies": {
    "vscode-languageserver": "^7.0.0",
    "vscode-languageserver-textdocument": "^1.0.1"
}
_5 menggunakan
"dependencies": {
    "vscode-languageserver": "^7.0.0",
    "vscode-languageserver-textdocument": "^1.0.1"
}
6 untuk menambahkan beberapa cuplikan sebagai pelengkap untuk file teks biasa

Lebih banyak sampel yang menggambarkan penggunaan VS Code API dapat ditemukan di https. //github. com/microsoft/vscode-extension-samples

Error Tolerant Parser untuk Server Bahasa

Sering kali, kode di editor tidak lengkap dan salah secara sintaksis, tetapi pengembang masih mengharapkan pelengkapan otomatis dan fitur bahasa lainnya berfungsi. Oleh karena itu, pengurai toleran kesalahan diperlukan untuk Server Bahasa. Parser menghasilkan AST yang bermakna dari kode yang sebagian lengkap, dan Server Bahasa menyediakan fitur bahasa berdasarkan AST

Saat kami meningkatkan dukungan PHP di VS Code, kami menyadari bahwa parser resmi PHP tidak toleran terhadap kesalahan dan tidak dapat digunakan kembali secara langsung di Server Bahasa. Oleh karena itu, kami mengerjakan Microsoft/tolerant-php-parser dan meninggalkan catatan mendetail yang dapat membantu penulis Server Bahasa yang perlu mengimplementasikan parser yang toleran terhadap kesalahan

Pertanyaan umum

Ketika saya mencoba melampirkan ke server, saya mendapatkan "tidak dapat terhubung ke proses runtime (timeout setelah 5000 ms)"?

Anda akan melihat kesalahan batas waktu ini jika server tidak berjalan saat Anda mencoba memasang debugger. Klien memulai server bahasa jadi pastikan Anda telah memulai klien untuk menjalankan server. Anda mungkin juga perlu menonaktifkan breakpoint klien Anda jika mereka mengganggu memulai server