Condividi tramite


Aggiungere l'estensione del protocollo del Language Server

Il protocollo LSP (Language Server Protocol) è un protocollo comune, sotto forma di RPC JSON v2.0, usato per fornire funzionalità del servizio di linguaggio a vari editor di codice. Usando il protocollo, gli sviluppatori possono scrivere un singolo server di linguaggio per fornire funzionalità del servizio di linguaggio come IntelliSense, diagnostica degli errori, trovare tutti i riferimenti e così via, a vari editor di codice che supportano il LSP. Tradizionalmente, i servizi di linguaggio in Visual Studio possono essere aggiunti usando i file di grammatica TextMate per fornire funzionalità di base, ad esempio l'evidenziazione della sintassi o scrivendo servizi di linguaggio personalizzati che usano il set completo di API di estendibilità di Visual Studio per fornire dati più completi. Con il supporto di Visual Studio per LSP, è disponibile una terza opzione.

servizio del protocollo del server di linguaggio in Visual Studio

Per garantire la migliore esperienza utente possibile, è consigliabile implementare anche Language Configuration, che fornisce l'elaborazione locale di molte delle stesse operazioni e può quindi migliorare le prestazioni di molte delle operazioni dell'editor specifiche del linguaggio supportate dal LSP (Language Server Protocol).

Protocollo del Server di Lingua (Language Server Protocol)

implementazione del protocollo del server linguistico

Questo articolo descrive come creare un'estensione di Visual Studio che usa un server di linguaggio basato su LSP. Si presuppone che sia già stato sviluppato un server di linguaggio basato su LSP e che si voglia semplicemente integrarlo in Visual Studio.

Per il supporto in Visual Studio, i server di linguaggio possono comunicare con il client (Visual Studio) tramite qualsiasi meccanismo di trasmissione basato su flusso, ad esempio:

  • Flussi di input/output standard
  • Named pipes
  • Socket (solo TCP)

Lo scopo del protocollo LSP e del supporto in Visual Studio è integrare i servizi linguistici che non sono inclusi nel prodotto Visual Studio. Non è progettato per estendere i servizi di linguaggio esistenti (ad esempio C#) in Visual Studio. Per estendere i linguaggi esistenti, consultare la guida all'estendibilità dei servizi linguistici (ad esempio il "Roslyn" .NET Compiler Platform) oppure consultare Estendere l'editor e i servizi linguistici.

Per altre informazioni sul protocollo stesso, vedere la documentazione qui.

Per altre informazioni su come creare un server di linguaggio di esempio o su come integrare un server di linguaggio esistente in Visual Studio Code, vedere la documentazione qui.

Funzionalità supportate da Language Server Protocol

Le tabelle seguenti illustrano le funzionalità LSP supportate in Visual Studio:

Messaggio Ha Supporto in Visual Studio
inizializzare
Inizializzato
spegnimento
uscita
$/cancelRequest
window/showMessage
finestra/mostraRichiestaMessaggio
window/logMessage
telemetria/evento
client/registerCapability
client/unregisterCapability
workspace/didChangeConfiguration
workspace/didChangeWatchedFiles
area di lavoro/simbolo
workspace/eseguiComando
spazio di lavoro/applica modifica
Diagnostica pubblica documento di testo
textDocument/didOpen
textDocument/didChange
textDocument/willSave
textDocument/willSaveWaitUntil
textDocument/didSave
textDocument/didClose
textDocument/completamento
completamento/risoluzione
textDocument/passaggio del mouse
documentoDiTesto/aiutoFirma
documentoTesto/riferimenti
textDocument/documentHighlight
textDocument/documentSymbol
documentoTesto/formattazione
textDocument/rangeFormatting
textDocument/onTypeFormatting
textDocument/definition
textDocument/codeAction
textDocument/codeLens
codeLens/resolve (risoluzione di CodeLens)
textDocument/documentLink
documentLink/resolve
textDocument/rename

Inizia

Nota

A partire da Visual Studio 2017 versione 15.8, il supporto per Common Language Server Protocol è integrato in Visual Studio. Se hai creato estensioni LSP usando l'anteprima della versione VSIX del client Language Server, queste smetteranno di funzionare una volta eseguito l'aggiornamento alla versione 15.8 o successiva. Per ripristinare il funzionamento delle estensioni LSP, è necessario eseguire le operazioni seguenti:

  1. Disinstallare Microsoft Visual Studio Language Server Protocol Preview VSIX.

    A partire dalla versione 15.8, ogni volta che si esegue un aggiornamento in Visual Studio l'anteprima VSIX viene rilevata e rimossa automaticamente.

  2. Aggiornare il riferimento NuGet alla versione non di anteprima più recente per i pacchetti LSP .

  3. Rimuovere la dipendenza da Microsoft Visual Studio Language Server Protocol Preview VSIX nel manifesto VSIX.

  4. Assicurarsi che il VSIX specifichi Visual Studio 2017 versione 15.8 Preview 3 come limite inferiore per l'obiettivo di installazione.

  5. Ricompilare e ridistribuire.

Creare un progetto VSIX

Per creare un'estensione del servizio di linguaggio usando un server di linguaggio basato su LSP, assicurati prima di tutto di avere installato il Workload per lo sviluppo di estensioni di Visual Studio per la tua istanza di Visual Studio.

Creare quindi un nuovo progetto VSIX passando a File>Nuovo progetto>Visual C#>Estendibilità>VSIX progetto:

crea un progetto VSIX

Installazione del server di linguaggio e del runtime

Per impostazione predefinita, le estensioni create per supportare i server di linguaggio basati su LSP in Visual Studio non contengono i server di linguaggio stessi o i runtime necessari per eseguirli. Gli sviluppatori di estensioni sono responsabili della distribuzione dei server di linguaggio e dei runtime necessari. Esistono diversi modi per eseguire questa operazione:

  • I server di linguaggio possono essere incorporati in VSIX come file di contenuto.
  • Creare un pacchetto MSI per installare il server della lingua e/o i runtime necessari.
  • Fornire su Marketplace istruzioni agli utenti su come ottenere runtime e server linguistici.

File di grammatica TextMate

Il provider di servizi di configurazione locale non include specifiche su come fornire la colorazione del testo per le lingue. Per fornire colorazioni personalizzate per i linguaggi in Visual Studio, gli sviluppatori di estensioni possono usare un file di grammatica TextMate. Per aggiungere file di grammatica o tema TextMate personalizzati, seguire questa procedura:

  1. Creare una cartella denominata "Grammars" all'interno dell'estensione (o può essere qualsiasi nome scelto).

  2. All'interno della cartella grammars, includere qualsiasi *.tmlanguage, *.plist, *.tmthemeo *.json file desiderato che fornisca colorazione personalizzata.

    Suggerimento

    Un file .tmtheme definisce come gli ambiti vengono mappati alle classificazioni di Visual Studio (chiavi di colore denominate). Per indicazioni, è possibile fare riferimento al file globale nel percorso %ProgramFiles(x86)%\Microsoft Visual Studio\<versione>\<SKU>\Common7\IDE\CommonExtensions\Microsoft\TextMate\Starterkit\Themesg.

  3. Creare un file con estensione pkgdef e aggiungere una riga simile alla seguente:

    [$RootKey$\TextMate\Repositories]
    "MyLang"="$PackageFolder$\Grammars"
    
  4. Fare clic con il pulsante destro del mouse sui file e selezionare Proprietà. Modificare l'azione Build in Contenuto e cambiare la proprietà Include in VSIX in true.

Dopo aver completato i passaggi precedenti, una cartella Grammars viene aggiunta alla directory di installazione del pacchetto come sorgente del repository denominata "MyLang" ('MyLang' è solo un nome per la disambiguazione e può essere qualsiasi stringa univoca). Tutte le grammatiche (file tmlanguage.tmlanguage) e i file di tema (file tmtheme.tmtheme) in questa directory sono considerati come potenziali e sovrascrivono le grammatiche predefinite fornite con TextMate. Se le estensioni dichiarate del file grammaticale corrispondono all'estensione del file aperto, TextMate eseguirà il passaggio.

Creare un client di linguaggio semplice

Interfaccia principale - ILanguageClient

Dopo aver creato il progetto VSIX, aggiungere i pacchetti NuGet seguenti al progetto:

Nota

Quando si accetta una dipendenza dal pacchetto NuGet dopo aver completato i passaggi precedenti, anche i pacchetti Newtonsoft.Json e StreamJsonRpc vengono aggiunti al progetto. Non aggiornare questi pacchetti, a meno che non si sia certi che tali nuove versioni verranno installate nella versione di Visual Studio destinata all'estensione. Gli assembly non verranno inclusi nel VSIX; verranno invece prelevati dalla directory di installazione di Visual Studio. Se si fa riferimento a una versione più recente degli assembly rispetto a quella installata nel computer di un utente, l'estensione non funzionerà.

È quindi possibile creare una nuova classe che implementa l'interfaccia ILanguageClient , ovvero l'interfaccia principale necessaria per i client di linguaggio che si connettono a un server di linguaggio basato su LSP.

Di seguito è riportato un esempio:

namespace MockLanguageExtension
{
    [ContentType("bar")]
    [Export(typeof(ILanguageClient))]
    public class BarLanguageClient : ILanguageClient
    {
        public string Name => "Bar Language Extension";

        public IEnumerable<string> ConfigurationSections => null;

        public object InitializationOptions => null;

        public IEnumerable<string> FilesToWatch => null;

        public event AsyncEventHandler<EventArgs> StartAsync;
        public event AsyncEventHandler<EventArgs> StopAsync;

        public async Task<Connection> ActivateAsync(CancellationToken token)
        {
            await Task.Yield();

            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Server", @"MockLanguageServer.exe");
            info.Arguments = "bar";
            info.RedirectStandardInput = true;
            info.RedirectStandardOutput = true;
            info.UseShellExecute = false;
            info.CreateNoWindow = true;

            Process process = new Process();
            process.StartInfo = info;

            if (process.Start())
            {
                return new Connection(process.StandardOutput.BaseStream, process.StandardInput.BaseStream);
            }

            return null;
        }

        public async Task OnLoadedAsync()
        {
            await StartAsync.InvokeAsync(this, EventArgs.Empty);
        }

        public Task OnServerInitializeFailedAsync(Exception e)
        {
            return Task.CompletedTask;
        }

        public Task OnServerInitializedAsync()
        {
            return Task.CompletedTask;
        }
    }
}

I metodi principali da implementare sono OnLoadedAsync e ActivateAsync. viene chiamato il OnLoadedAsync quando Visual Studio ha caricato l'estensione e il server di linguaggio è pronto per l'avvio. In questo metodo è possibile richiamare immediatamente il delegato StartAsync per segnalare che il server di linguaggio deve essere avviato oppure è possibile eseguire logica aggiuntiva e richiamare StartAsync in un secondo momento. Per attivare il server di lingua, è necessario chiamare StartAsync a un certo punto.

ActivateAsync è il metodo richiamato chiamando il delegato StartAsync. Contiene la logica per avviare il server di lingua e stabilire la connessione. È necessario restituire un oggetto di connessione che contiene flussi per scrivere sul server e leggere dal server. Tutte le eccezioni generate qui vengono rilevate e mostrate all'utente mediante un messaggio InfoBar in Visual Studio.

Attivazione

Dopo aver implementato la classe client del linguaggio, è necessario definire due attributi per definirne la modalità di caricamento in Visual Studio e attivazione:

  [Export(typeof(ILanguageClient))]
  [ContentType("bar")]

Ministero dell'Economia e delle Finanze (MEF)

Visual Studio usa MEF (Managed Extensibility Framework) per gestire i punti di estendibilità. L'attributo esportazione indica a Visual Studio che questa classe deve essere prelevata come punto di estensione e caricata al momento appropriato.

Per usare MEF, è anche necessario definire MEF come asset nel manifesto VSIX.

Apri la finestra di progettazione del manifesto VSIX e vai alla scheda Assets.

aggiungere asset MEF

Fare clic su Nuovo per creare un nuovo asset:

definisce l'asset MEF

  • Tipo: Microsoft.VisualStudio.MefComponent
  • Sorgente: Un progetto nella soluzione corrente
  • Progetto: [Your project]

Definizione del tipo di contenuto

Attualmente, l'unico modo per caricare l'estensione del server di linguaggio basata su LSP è per tipo di contenuto di file. In altre parole, quando si definisce la classe client del linguaggio (che implementa ILanguageClient), sarà necessario definire i tipi di file che, quando aperti, causeranno il caricamento dell'estensione. Se non vengono aperti file che corrispondono al tipo di contenuto definito, l'estensione non verrà caricata.

Questa operazione viene eseguita definendo una o più classi ContentTypeDefinition:

namespace MockLanguageExtension
{
    public class BarContentDefinition
    {
        [Export]
        [Name("bar")]
        [BaseDefinition(CodeRemoteContentDefinition.CodeRemoteContentTypeName)]
        internal static ContentTypeDefinition BarContentTypeDefinition;

        [Export]
        [FileExtension(".bar")]
        [ContentType("bar")]
        internal static FileExtensionToContentTypeDefinition BarFileExtensionDefinition;
    }
}

Nell'esempio precedente viene creata una definizione del tipo di contenuto per i file che terminano estensione di file con estensione bar. Alla definizione del tipo di contenuto viene assegnato il nome "bar" e deve derivare da CodeRemoteContentTypeName.

Dopo aver aggiunto una definizione del tipo di contenuto, è possibile definire quando caricare l'estensione del client del linguaggio nella classe del client del linguaggio.

    [ContentType("bar")]
    [Export(typeof(ILanguageClient))]
    public class BarLanguageClient : ILanguageClient
    {
    }

L'aggiunta del supporto per i server di linguaggio LSP non richiede l'implementazione del proprio sistema di progetto in Visual Studio. I clienti possono aprire un singolo file o una cartella in Visual Studio per iniziare a usare il servizio linguistico. In effetti, il supporto per i server di linguaggio LSP è progettato per funzionare solo in scenari di cartella/file aperti. Se viene implementato un sistema di progetto personalizzato, alcune funzionalità (ad esempio le impostazioni) non funzioneranno.

Funzionalità avanzate

Impostazioni

È disponibile il supporto per impostazioni personalizzate specifiche del server del linguaggio, ma è ancora in fase di miglioramento. Le impostazioni sono specifiche del supporto del server di lingua e in genere controllano il modo in cui il server di lingua genera dati. Ad esempio, un server di lingua potrebbe avere un'impostazione per il numero massimo di errori segnalati. Gli autori di estensioni definiscono un valore predefinito, che può essere modificato dagli utenti per progetti specifici.

Seguire questa procedura per aggiungere il supporto per le impostazioni all'estensione del servizio di linguaggio LSP:

  1. Aggiungere un file JSON (ad esempio, MockLanguageExtensionSettings.json) al progetto che contiene le impostazioni e i relativi valori predefiniti. Per esempio:

    {
        "foo.maxNumberOfProblems": -1
    }
    
  2. Fare clic con il pulsante destro del mouse sul file JSON e selezionare Proprietà. Modificare l'azione "Build" in "Contenuto" e la proprietà "Includi in VSIX" in vero.

  3. Implementa ConfigurationSections e restituisci l'elenco di prefissi per le impostazioni definite nel file JSON (in Visual Studio Code, questo verrà mappato al nome della sezione di configurazione in package.json):

    public IEnumerable<string> ConfigurationSections
    {
        get
        {
            yield return "foo";
        }
    }
    
  4. Aggiungere un file con estensione pkgdef al progetto (aggiungere un nuovo file di testo e modificare l'estensione del file in pkgdef). Il file pkgdef deve contenere queste informazioni:

    [$RootKey$\OpenFolder\Settings\VSWorkspaceSettings\[settings-name]]
    @="$PackageFolder$\[settings-file-name].json"
    

    Campione:

    [$RootKey$\OpenFolder\Settings\VSWorkspaceSettings\MockLanguageExtension]
    @="$PackageFolder$\MockLanguageExtensionSettings.json"
    
  5. Fare clic con il pulsante destro del mouse sul file .pkgdef e selezionare Proprietà. Modificare l'azione di Build in contenuto e la proprietà Includi in VSIX in vero.

  6. Aprire il file source.extension.vsixmanifest e aggiungere un asset nella scheda Asset:

    modificare l'asset vspackage

    • Type: Microsoft.VisualStudio.VsPackage
    • origine: file nel file system
    • percorso: [percorso del tuo file .pkgdef]

Modifica delle impostazioni utente per un'area di lavoro

  1. L'utente apre un'area di lavoro contenente file di proprietà del server.

  2. L'utente aggiunge un file nella cartella vs denominata VSWorkspaceSettings.json.

  3. L'utente aggiunge una riga al file VSWorkspaceSettings.json per un'impostazione fornita dal server. Per esempio:

    {
        "foo.maxNumberOfProblems": 10
    }
    

Abilitare il tracciamento diagnostico

La traccia diagnostica può essere abilitata per l'output di tutti i messaggi tra il client e il server, che possono essere utili durante il debug dei problemi. Per abilitare la traccia diagnostica, eseguire le operazioni seguenti:

  1. Aprire o creare il file delle impostazioni dell'area di lavoro VSWorkspaceSettings.json (vedere "Modifica utente delle impostazioni per un'area di lavoro").
  2. Aggiungere la riga seguente nel file JSON delle impostazioni:
{
    "foo.trace.server": "Off"
}

Esistono tre valori possibili per la verbosità della traccia:

  • "Off": tracciamento disattivato completamente
  • "Messages": la traccia è attivata, ma vengono tracciati solo il nome del metodo e l'ID risposta.
  • "Dettagliato": tracciamento attivato; viene tracciato l'intero messaggio RPC.

Quando la traccia è attivata, il contenuto viene scritto in un file nella directory %temp%\VisualStudio\LSP. Il log segue il formato di denominazione [LanguageClientName]-[Datetime Stamp].log. Attualmente, il tracciamento può essere abilitato solo per scenari di cartelle aperte. L'apertura di un singolo file per attivare un server linguistico non supporta la tracciatura diagnostica.

Messaggi personalizzati

Sono disponibili API per facilitare il passaggio di messaggi e la ricezione di messaggi dal server di lingua che non fanno parte del protocollo server di linguaggio standard. Per gestire i messaggi personalizzati, implementare l'interfaccia ILanguageClientCustomMessage2 nella classe client del linguaggio. libreria di VS-StreamJsonRpc viene usata per trasmettere messaggi personalizzati tra il client di lingua e il server di lingua. Poiché l'estensione del linguaggio LSP è esattamente come qualsiasi altra estensione di Visual Studio, puoi decidere di aggiungere ulteriori funzionalità (non supportate dal LSP) a Visual Studio utilizzando altre API di Visual Studio nella tua estensione tramite messaggi personalizzati.

Ricevere messaggi personalizzati

Per ricevere messaggi personalizzati dal server di linguaggio, implementare la proprietà [CustomMessageTarget]((/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessagetarget) in ILanguageClientCustomMessage2 e restituire un oggetto che sa gestire i messaggi personalizzati. Esempio seguente:

Proprietà (/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessagetarget) nella ILanguageClientCustomMessage2 che restituisce un oggetto in grado di gestire i messaggi personalizzati. Esempio seguente:

internal class MockCustomLanguageClient : MockLanguageClient, ILanguageClientCustomMessage2
{
    private JsonRpc customMessageRpc;

    public MockCustomLanguageClient() : base()
    {
        CustomMessageTarget = new CustomTarget();
    }

    public object CustomMessageTarget
    {
        get;
        set;
    }

    public class CustomTarget
    {
        public void OnCustomNotification(JToken arg)
        {
            // Provide logic on what happens OnCustomNotification is called from the language server
        }

        public string OnCustomRequest(string test)
        {
            // Provide logic on what happens OnCustomRequest is called from the language server
        }
    }
}

Inviare messaggi personalizzati

Per inviare messaggi personalizzati al server di linguaggio, implementare il metodo AttachForCustomMessageAsync ILanguageClientCustomMessage2. Questo metodo viene richiamato quando il server linguistico è stato avviato ed è pronto per ricevere messaggi. Un oggetto JsonRpc viene passato come parametro, che si può conservare per inviare messaggi al server di linguaggio tramite le API VS-StreamJsonRpc. Esempio seguente:

internal class MockCustomLanguageClient : MockLanguageClient, ILanguageClientCustomMessage2
{
    private JsonRpc customMessageRpc;

    public MockCustomLanguageClient() : base()
    {
        CustomMessageTarget = new CustomTarget();
    }

    public async Task AttachForCustomMessageAsync(JsonRpc rpc)
    {
        await Task.Yield();

        this.customMessageRpc = rpc;
    }

    public async Task SendServerCustomNotification(object arg)
    {
        await this.customMessageRpc.NotifyWithParameterObjectAsync("OnCustomNotification", arg);
    }

    public async Task<string> SendServerCustomMessage(string test)
    {
        return await this.customMessageRpc.InvokeAsync<string>("OnCustomRequest", test);
    }
}

Livello intermedio

A volte uno sviluppatore di estensioni potrebbe voler intercettare i messaggi LSP inviati e ricevuti dal server di lingua. Ad esempio, uno sviluppatore di estensioni può voler modificare il parametro del messaggio inviato per un determinato messaggio LSP o modificare i risultati restituiti dal server di linguaggio per una funzionalità LSP (ad esempio i completamenti). Quando necessario, gli sviluppatori di estensioni possono usare l'API MiddleLayer per intercettare i messaggi LSP.

Per intercettare un messaggio specifico, creare una classe che implementi l'interfaccia ILanguageClientMiddleLayer. Implementare quindi l'interfaccia ILanguageClientCustomMessage2 nella classe client del linguaggio e restituire un'istanza dell'oggetto nella proprietà MiddleLayer. Esempio seguente:

public class MockLanguageClient : ILanguageClient, ILanguageClientCustomMessage2
{
  public object MiddleLayer => DiagnosticsFilterMiddleLayer.Instance;

  private class DiagnosticsFilterMiddleLayer : ILanguageClientMiddleLayer
  {
    internal readonly static DiagnosticsFilterMiddleLayer Instance = new DiagnosticsFilterMiddleLayer();

    private DiagnosticsFilterMiddleLayer() { }

    public bool CanHandle(string methodName)
    {
      return methodName == "textDocument/publishDiagnostics";
    }

    public async Task HandleNotificationAsync(string methodName, JToken methodParam, Func<JToken, Task> sendNotification)
    {
      if (methodName == "textDocument/publishDiagnostics")
      {
        var diagnosticsToFilter = (JArray)methodParam["diagnostics"];
        // ony show diagnostics of severity 1 (error)
        methodParam["diagnostics"] = new JArray(diagnosticsToFilter.Where(diagnostic => diagnostic.Value<int?>("severity") == 1));

      }
      await sendNotification(methodParam);
    }

    public async Task<JToken> HandleRequestAsync(string methodName, JToken methodParam, Func<JToken, Task<JToken>> sendRequest)
    {
      return await sendRequest(methodParam);
    }
  }
}

La funzionalità del livello intermedio è ancora in fase di sviluppo e non è ancora completa.

Estensione del server del linguaggio LSP di esempio

Per visualizzare il codice sorgente di un'estensione di esempio usando l'API client LSP in Visual Studio, vedere VSSDK-Extensibility-Samples esempio LSP.

Domande frequenti

Vorrei creare un sistema di progetto personalizzato per integrare il server di linguaggio LSP per fornire supporto più avanzato alle funzionalità in Visual Studio, come posso procedere?

Il supporto per i server di linguaggio basati su LSP in Visual Studio si basa sulla funzionalità cartella aperta ed è progettato per non richiedere un sistema di progetto personalizzato. È possibile compilare un sistema di progetto personalizzato seguendo le istruzioni qui, ma alcune funzionalità, ad esempio le impostazioni, potrebbero non funzionare. La logica di inizializzazione predefinita per i server di linguaggio LSP consiste nel passare il percorso della cartella radice della cartella attualmente aperta, pertanto se si usa un sistema di progetto personalizzato, potrebbe essere necessario fornire logica personalizzata durante l'inizializzazione per assicurarsi che il server di lingua possa essere avviato correttamente.

Come si aggiunge il supporto del debugger?

Microsoft fornirà supporto per il protocollo di debug comune in una versione futura.

Se è già installato un servizio di linguaggio supportato da Visual Studio (ad esempio, JavaScript), è comunque possibile installare un'estensione del server del linguaggio LSP che offre funzionalità aggiuntive (ad esempio linting)?

Sì, ma non tutte le funzionalità funzioneranno correttamente. L'obiettivo finale per le estensioni del server di linguaggio LSP è abilitare i servizi di linguaggio non supportati in modo nativo da Visual Studio. È possibile creare estensioni che offrono supporto aggiuntivo usando i server di linguaggio LSP, ma alcune funzionalità (ad esempio IntelliSense) non saranno un'esperienza ottimale. In generale, è consigliabile usare le estensioni del server di linguaggio LSP per fornire nuove esperienze linguistiche, non estendendone quelle esistenti.

dove si pubblica il server di linguaggio LSP completato VSIX?

Consultare le istruzioni del Marketplace qui.