Compartilhar via


Adicionar uma extensão de Protocolo do Servidor de Idiomas

O LSP (Language Server Protocol) é um protocolo comum, na forma de JSON RPC v2.0, usado para fornecer recursos de serviço de idioma para vários editores de código. Usando o protocolo, os desenvolvedores podem escrever um único servidor de idiomas para fornecer recursos de serviço de idioma, como IntelliSense, diagnóstico de erro, localizar todas as referências e assim por diante, em vários editores de código que dão suporte ao LSP. Tradicionalmente, os serviços de linguagem no Visual Studio podem ser adicionados usando arquivos de gramática TextMate para fornecer funcionalidades básicas, como realce de sintaxe ou gravação de serviços de linguagem personalizados que usam o conjunto completo de APIs de extensibilidade do Visual Studio para fornecer dados mais avançados. Com o suporte do Visual Studio para LSP, há uma terceira opção.

serviço de protocolo do servidor de linguagem no Visual Studio

Para garantir a melhor experiência do usuário possível, implemente também a Configuração de Linguagem, que fornece processamento local de muitas das mesmas operações e, portanto, pode melhorar o desempenho de muitas das operações de editor específicas da linguagem compatíveis com o LSP.

Protocolo do Servidor de Idiomas

implementação do protocolo de servidor de linguagem

Este artigo descreve como criar uma extensão do Visual Studio que usa um servidor de linguagem baseado em LSP. Ele pressupõe que você já desenvolveu um servidor de linguagem baseado em LSP e apenas deseja integrá-lo ao Visual Studio.

Para obter suporte no Visual Studio, os servidores de linguagem podem se comunicar com o cliente (Visual Studio) por meio de qualquer mecanismo de transmissão baseado em fluxo, por exemplo:

  • Fluxos de entrada/saída padrão
  • Pipes nomeados
  • Soquetes (somente TCP)

A intenção do LSP e o suporte para ele no Visual Studio é integrar serviços de linguagem que não fazem parte do produto do Visual Studio. Ele não se destina a estender os serviços de linguagem existentes (como C#) no Visual Studio. Para estender as linguagens existentes, veja o guia de extensibilidade do serviço de linguagem (por exemplo, o Compilador do .NET "Roslyn") ou confira Estender os serviços de editor e linguagem.

Para obter mais informações sobre o protocolo em si, consulte a documentação aqui.

Para obter mais informações sobre como criar um servidor de idioma de exemplo ou como integrar um servidor de idiomas existente ao Visual Studio Code, consulte a documentação aqui.

Recursos compatíveis com o Protocolo do Servidor de Idiomas

As tabelas a seguir mostram quais recursos LSP têm suporte no Visual Studio:

Mensagem Tem suporte no Visual Studio
inicializar sim
inicializado sim
desligamento sim
sair sim
$/cancelRequest sim
window/showMessage sim
window/showMessageRequest sim
window/logMessage sim
telemetry/event
client/registerCapability
client/unregisterCapability
workspace/didChangeConfiguration sim
workspace/didChangeWatchedFiles sim
workspace/symbol sim
workspace/executeCommand sim
workspace/applyEdit sim
textDocument/publishDiagnostics sim
textDocument/didOpen sim
textDocument/didChange sim
textDocument/willSave
textDocument/willSaveWaitUntil
textDocument/didSave sim
textDocument/didClose sim
textDocument/completion sim
completion/resolve sim
textDocument/hover sim
textDocument/signatureHelp sim
textDocument/references sim
textDocument/documentHighlight sim
textDocument/documentSymbol sim
textDocument/formatting sim
textDocument/rangeFormatting sim
textDocument/onTypeFormatting
textDocument/definition sim
textDocument/codeAction sim
textDocument/codeLens
codeLens/resolve
textDocument/documentLink
documentLink/resolve
textDocument/rename sim

Começar

Nota

A partir do Visual Studio 2017 versão 15.8, o suporte para o Common Language Server Protocol é integrado ao Visual Studio. Se você criou extensões LSP usando o VSIX do Cliente de Servidor de Linguagem na versão prévia, elas deixarão de funcionar quando você atualizar para a versão 15.8 ou superior. Você precisará fazer o seguinte para que as extensões LSP funcionem novamente:

  1. Desinstale o VSIX da Versão Prévia do Protocolo do Servidor de Linguagem do Microsoft Visual Studio.

    A partir da versão 15.8, sempre que você realiza uma atualização no Visual Studio, o VSIX de pré-visualização é detectado e removido automaticamente.

  2. Atualize sua referência do Nuget para a versão mais recente que não seja a versão prévia dos pacotes LSP.

  3. Remova a dependência do Protocolo do Servidor de Linguagem do Microsoft Visual Studio no manifesto VSIX.

  4. Verifique se o VSIX especifica o Visual Studio 2017 versão 15.8 Versão Prévia 3 como o limite inferior para o destino de instalação.

  5. Recompilar e reimplantar.

Criar um projeto VSIX

Para criar uma extensão de serviço de linguagem usando um servidor de linguagem baseado em LSP, primeiro verifique se você tem a Carga de Trabalho de desenvolvimento de extensões do Visual Studio instalada para sua instância do VS.

Em seguida, crie um novo Projeto VSIX navegando até Arquivo>Novo Projeto>Visual C#>Extensibilidade>Projeto VSIX:

criar projeto vsix

Instalação do servidor de idiomas e do runtime

Por padrão, as extensões criadas para dar suporte a servidores de linguagem baseados em LSP no Visual Studio não contêm os próprios servidores de linguagem ou os runtimes necessários para executá-los. Os desenvolvedores de extensão são responsáveis por distribuir os servidores de idioma e os runtimes necessários. Há várias maneiras de fazer isso:

  • Os servidores de linguagem podem ser inseridos no VSIX como arquivos de conteúdo.
  • Crie uma MSI para instalar o servidor de idiomas e/ou os runtimes necessários.
  • Forneça instruções no Marketplace informando aos usuários como obter ambientes de execução e servidores de linguagem.

Arquivos de gramática TextMate

O LSP não inclui especificação sobre como fornecer coloração de texto para idiomas. Para fornecer colorização personalizada para idiomas no Visual Studio, os desenvolvedores de extensão podem usar um arquivo de gramática TextMate. Para adicionar arquivos de gramática ou tema do TextMate personalizados, siga estas etapas:

  1. Crie uma pasta chamada "Gramáticas" dentro de sua extensão (ou pode ser qualquer nome que você escolher).

  2. Dentro da pasta gramáticas, inclua quaisquer arquivos *.tmlanguage, *.plist, *.tmthemeou *.json que você deseja que forneçam colorização personalizada.

    Dica

    Um arquivo .tmtheme define como as áreas de escopos são mapeadas para as classificações do Visual Studio (chaves de cores nomeadas). Para obter diretrizes, você pode referenciar o arquivo .tmtheme global no diretório %ProgramFiles(x86)%\Microsoft Visual Studio\<versão>\<SKU>\Common7\IDE\CommonExtensions\Microsoft\TextMate\Starterkit\Themesg.

  3. Crie um arquivo .pkgdef e adicione uma linha semelhante a esta:

    [$RootKey$\TextMate\Repositories]
    "MyLang"="$PackageFolder$\Grammars"
    
  4. Clique com o botão direito do mouse nos arquivos e selecione Propriedades. Altere a ação Build para Conteúdo e altere a propriedade Include in VSIX para true.

Depois de concluir as etapas anteriores, uma pasta Grammars é adicionada ao diretório de instalação do pacote como uma fonte de repositório chamada 'MyLang' ('MyLang' é apenas um nome para desambiguação e pode ser qualquer cadeia de caracteres exclusiva). Todas as gramáticas (arquivos.tmlanguage) e arquivos de tema (arquivos.tmtheme) neste diretório são identificados como potenciais e eles substituem as gramáticas internas do TextMate. Se as extensões declaradas do arquivo gramatical corresponderem à extensão do arquivo que está sendo aberto, o TextMate intervirá.

Criar um cliente de linguagem simples

Interface principal – ILanguageClient

Depois de criar seu projeto VSIX, adicione os seguintes pacotes NuGet ao seu projeto:

Nota

Quando você assume uma dependência do pacote NuGet depois de concluir as etapas anteriores, os pacotes Newtonsoft.Json e StreamJsonRpc também são adicionados ao seu projeto. Não atualize esses pacotes, a menos que você tenha certeza de que essas novas versões serão instaladas na versão do Visual Studio que sua extensão tem como destino. Os assemblies não serão incluídos no VSIX. Em vez disso, eles serão separados do diretório de instalação do Visual Studio. Se você estiver fazendo referência a uma versão mais recente dos assemblies do que a instalada no computador de um usuário, sua extensão não funcionará.

Em seguida, você pode criar uma nova classe que implementa a interface ILanguageClient, que é a interface principal necessária para clientes de linguagem que se conectam a um servidor de linguagem baseado em LSP.

Veja a seguir um exemplo:

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;
        }
    }
}

Os principais métodos que precisam ser implementados são OnLoadedAsync e ActivateAsync. OnLoadedAsync é chamado quando o Visual Studio carrega sua extensão e o servidor de idiomas está pronto para ser iniciado. Nesse método, você pode invocar o delegado StartAsync imediatamente para sinalizar que o servidor de idiomas deve ser iniciado ou você pode fazer lógica adicional e invocar StartAsync posteriormente. Para ativar o servidor de idiomas, você deve chamar StartAsync em algum momento.

ActivateAsync é o método invocado eventualmente ao chamar o delegado StartAsync. Ele contém a lógica para iniciar o servidor de idiomas e estabelecer conexão com ele. Um objeto de conexão que contém fluxos para gravação no servidor e leitura dele deve ser retornado. Todas as exceções lançadas aqui são capturadas e exibidas ao usuário por meio de uma mensagem do InfoBar no Visual Studio.

Ativação

Depois que a classe cliente de idioma for implementada, você precisará definir dois atributos para que ela defina como ela será carregada no Visual Studio e ativada:

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

MEF

O Visual Studio usa mef (Managed Extensibility Framework) para gerenciar seus pontos de extensibilidade. O atributo Exportar indica ao Visual Studio que essa classe deve ser selecionada como um ponto de extensão e carregada no momento apropriado.

Para usar o MEF, você também deve definir MEF como um ativo no manifesto VSIX.

Abra o designer de manifesto do VSIX e navegue até a guia Ativos:

adicionar ativo do MEF do MEF

Clique em Novo para criar um novo recurso:

definir ativo do MEF

  • Tipo: Microsoft.VisualStudio.MefComponent
  • Fonte: um projeto na solução atual
  • Project: [Seu projeto]

Definição de tipo de conteúdo

Atualmente, a única maneira de carregar sua extensão de servidor de linguagem baseada em LSP é por tipo de conteúdo de arquivo. Ou seja, ao definir sua classe de cliente de idioma (que implementa ILanguageClient), você precisará definir os tipos de arquivos que, quando abertos, farão com que sua extensão seja carregada. Se nenhum arquivo que corresponda ao tipo de conteúdo definido for aberto, sua extensão não será carregada.

Isso é feito por meio da definição de uma ou mais classes de 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;
    }
}

No exemplo anterior, uma definição de tipo de conteúdo é criada para arquivos que terminam na extensão de arquivo .bar. A definição de tipo de conteúdo recebe o nome "bar" e deve derivar de CodeRemoteContentTypeName.

Depois de adicionar uma definição de tipo de conteúdo, você pode definir quando carregar a extensão do cliente de idioma na classe de cliente de idioma:

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

Adicionar suporte para servidores de linguagem LSP não exige que você implemente seu próprio sistema de projetos no Visual Studio. Os clientes podem abrir um único arquivo ou uma pasta no Visual Studio para começar a usar seu serviço de idioma. Na verdade, o suporte para servidores de linguagem LSP foi projetado para funcionar somente em cenários de pasta/arquivo abertos. Se um sistema de projeto personalizado for implementado, alguns recursos (como configurações) não funcionarão.

Recursos avançados

Configurações

O suporte para configurações personalizadas específicas do servidor de idiomas está disponível, mas ainda está em processo de melhoria. As configurações são específicas para o que o servidor de idiomas dá suporte e geralmente controlam como o servidor de idiomas emite dados. Por exemplo, um servidor de idiomas pode ter uma configuração para o número máximo de erros relatados. Os autores de extensão definiriam um valor padrão, que pode ser alterado pelos usuários para projetos específicos.

Siga estas etapas abaixo para adicionar suporte para configurações à extensão do serviço de idioma LSP:

  1. Adicione um arquivo JSON (por exemplo, MockLanguageExtensionSettings.json) ao projeto que contém as configurações e seus valores padrão. Por exemplo:

    {
        "foo.maxNumberOfProblems": -1
    }
    
  2. Clique com o botão direito do mouse no arquivo JSON e selecione Propriedades. Altere a ação Build para "Conteúdo" e a propriedade "Include in VSIX" para true.

  3. Implemente ConfigurationSections e retorne a lista de prefixos para as configurações definidas no arquivo JSON (no Visual Studio Code, isso seria mapeado para o nome da seção de configuração em package.json):

    public IEnumerable<string> ConfigurationSections
    {
        get
        {
            yield return "foo";
        }
    }
    
  4. Adicione um arquivo .pkgdef ao projeto (adicione um novo arquivo de texto e altere a extensão de arquivo para .pkgdef). O arquivo pkgdef deve conter estas informações:

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

    Amostra:

    [$RootKey$\OpenFolder\Settings\VSWorkspaceSettings\MockLanguageExtension]
    @="$PackageFolder$\MockLanguageExtensionSettings.json"
    
  5. Clique com o botão direito do mouse no arquivo .pkgdef e selecione Propriedades. Altere a ação Build para Conteúdo e a propriedade Include in VSIX para true.

  6. Abra o arquivo source.extension.vsixmanifest e adicione um ativo na aba Asset.

    editar ativo do vspackage

    • Tipo: Microsoft.VisualStudio.VsPackage
    • Fonte: arquivo no sistema de arquivos
    • Caminho: [Caminho para o arquivo .pkgdef]

Edição das configurações do espaço de trabalho pelo usuário

  1. O usuário abre um workspace que contém arquivos que seu servidor possui.

  2. O usuário adiciona um arquivo na pasta .vs chamada VSWorkspaceSettings.json.

  3. O usuário adiciona uma linha ao arquivo VSWorkspaceSettings.json para uma configuração fornecida pelo servidor. Por exemplo:

    {
        "foo.maxNumberOfProblems": 10
    }
    

Habilitar rastreamento de diagnóstico

O rastreamento de diagnóstico pode ser ativado para exibir todas as mensagens entre o cliente e o servidor, o que pode ser útil ao depurar problemas. Para habilitar o rastreamento de diagnóstico, faça o seguinte:

  1. Abra ou crie o arquivo de configurações do workspace VSWorkspaceSettings.json (consulte "Edição de configurações do usuário para um workspace").
  2. Adicione a seguinte linha no arquivo json de configurações:
{
    "foo.trace.server": "Off"
}

Há três valores possíveis para detalhamento de rastreamento:

  • "Desativado": rastreamento completamente desativado
  • "Mensagens": o rastreamento ativado, mas apenas o nome do método e a ID de resposta são rastreados.
  • "Detalhado": rastreamento ativado; toda a mensagem RPC é rastreada.

Quando o rastreamento é ativado, o conteúdo é gravado em um arquivo no diretório %temp% \VisualStudio\LSP. O log segue o formato de nomenclatura [LanguageClientName]-[Datetime Stamp].log. Atualmente, o rastreamento só pode ser habilitado para cenários de pasta aberta. Abrir um único arquivo para ativar um servidor de idiomas não tem suporte para rastreamento de diagnóstico.

Mensagens personalizadas

Há APIs em vigor para facilitar a passagem de mensagens e o recebimento de mensagens do servidor de idiomas que não fazem parte do Protocolo padrão do Servidor de Idiomas. Para lidar com mensagens personalizadas, implemente a interface ILanguageClientCustomMessage2 na classe cliente de linguagem. A biblioteca VS-StreamJsonRpc é usada para transmitir mensagens personalizadas entre o cliente de linguagem e o servidor de linguagem. Como a extensão do cliente de linguagem LSP é como qualquer outra extensão do Visual Studio, você pode decidir adicionar recursos adicionais (que não têm suporte do LSP) ao Visual Studio (usando outras APIs do Visual Studio) em sua extensão por meio de mensagens personalizadas.

Receber mensagens personalizadas

Para receber mensagens personalizadas do servidor de idiomas, implemente a propriedade [CustomMessageTarget]((/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessagetarget) no ILanguageClientCustomMessage2 e retorne um objeto que saiba como lidar com suas mensagens personalizadas. Exemplo abaixo:

A propriedade (/dotnet/api/microsoft.visualstudio.languageserver.client.ilanguageclientcustommessage.custommessagetarget) em ILanguageClientCustomMessage2 retorna um objeto que sabe lidar com as mensagens personalizadas. Exemplo abaixo:

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
        }
    }
}

Enviar mensagens personalizadas

Para enviar mensagens personalizadas ao servidor de linguagem, implemente o método AttachForCustomMessageAsync no ILanguageClientCustomMessage2. Esse método é invocado quando o servidor de idiomas é iniciado e pronto para receber mensagens. Um objeto JsonRpc é passado como um parâmetro, que você pode manter para enviar mensagens para o servidor de linguagem usando a API VS-StreamJsonRpc. Exemplo abaixo:

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);
    }
}

Camada intermediária

Às vezes, um desenvolvedor de extensão pode querer interceptar mensagens LSP enviadas e recebidas do servidor de idiomas. Por exemplo, um desenvolvedor de extensão pode querer alterar o parâmetro de mensagem enviado para uma mensagem LSP específica ou modificar os resultados retornados do servidor de idioma para um recurso LSP (por exemplo, conclusões). Quando isso for necessário, os desenvolvedores de extensão poderão usar a API middlelayer para interceptar mensagens LSP.

Para interceptar uma mensagem específica, crie uma classe que implemente a interface ILanguageClientMiddleLayer. Em seguida, implemente a interface ILanguageClientCustomMessage2 na classe cliente de linguagem e retorne uma instância do objeto na propriedade MiddleLayer. Exemplo abaixo:

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);
    }
  }
}

O recurso de camada intermediária ainda está em desenvolvimento e ainda não é abrangente.

Extensão de servidor de linguagem LSP de exemplo

Para ver o código-fonte de uma extensão de exemplo usando a API do cliente LSP no Visual Studio, consulte VSSDK-Extensibility-Samples exemplo de LSP.

Perguntas Freqüentes

gostaria de criar um sistema de projeto personalizado para complementar meu servidor de linguagem LSP para fornecer suporte a recursos mais avançados no Visual Studio, como fazer isso?

O suporte para servidores de linguagem baseados em LSP no Visual Studio depende do recurso de pasta aberta e foi projetado para não exigir um sistema de projeto personalizado. Você pode criar seu próprio sistema de projetos personalizado seguindo as instruções aqui, mas alguns recursos, como configurações, podem não funcionar. A lógica de inicialização padrão para servidores de linguagem LSP é passar o local da pasta raiz da pasta que está sendo aberta no momento, portanto, se você usar um sistema de projeto personalizado, talvez seja necessário fornecer lógica personalizada durante a inicialização para garantir que o servidor de idiomas possa ser iniciado corretamente.

Como adicionar suporte ao depurador?

Forneceremos suporte para o protocolo de depuração comum em uma versão futura.

Se já houver um serviço de idioma com suporte para VS instalado (por exemplo, JavaScript), ainda posso instalar uma extensão de servidor de idioma LSP que oferece recursos adicionais (como linting)?

Sim, mas nem todos os recursos funcionarão corretamente. O objetivo final das extensões do servidor de linguagem LSP é habilitar serviços de linguagem sem suporte nativo pelo Visual Studio. Você pode criar extensões que oferecem suporte adicional usando servidores de linguagem LSP, mas alguns recursos (como o IntelliSense) não serão uma experiência tranquila. Em geral, é recomendável que as extensões do servidor de linguagem LSP sejam usadas para fornecer novas experiências de linguagem, não estender as existentes.

Onde publicar meu VSIX do servidor de linguagem LSP completo?

Confira as instruções do Marketplace aqui.