Partilhar via


Personalização do comportamento do editor usando a Configuração da Linguagem

Pode implementar sintaxe personalizada específica da linguagem no editor Visual Studio usando a Configuração da Linguagem para permitir operações de sintaxe específicas da linguagem. Em comparação com a utilização de um Language Server, usar a Language Configuration pode melhorar o desempenho, uma vez que todas as suas operações são locais.

O que é a Configuração da Linguagem

O Visual Studio oferece capacidades inteligentes de edição para várias linguagens de programação através de extensões de linguagem. A Language Configuration complementa os servidores que utilizam o Language Server Protocol (LSP) e fornece dados declarativos que permitem ao editor Visual Studio tomar decisões de formatação, colorização e conclusão sem o atraso de fazer uma consulta assíncrona ao servidor LSP. As funcionalidades declarativas da linguagem são definidas em ficheiros de configuração. Por exemplo, extensões HTML, CSS e typescript-basic incluídas no Visual Studio oferecem um subconjunto das seguintes funcionalidades declarativas da linguagem:

  • Realce da sintaxe
  • Completação de fragmentos
  • Correspondência entre parênteses
  • Encerramento automático de colchetes
  • Alternância de comentários
  • Autoindentação

O Visual Studio oferece a capacidade para extensões definirem uma configuração de linguagem para qualquer linguagem de programação. O ficheiro de configuração da linguagem controla funcionalidades fundamentais de edição, como a alternância de comentários, a correspondência e o envolvimento de colchetes.

Usar a Configuração de Linguagem ajuda com:

  • Trabalho síncrono no processo de escrita do utilizador
  • Simplicidade: Ficheiros JSON curtos com expressões regulares são mais fáceis de manter do que algoritmos complexos
  • Portabilidade: Requer nenhuma ou mínimas alterações entre o Visual Studio Code e o Visual Studio

Além disso, os ficheiros de configuração de linguagem oferecem uma forma fácil de estender o Visual Studio para suportar algumas funcionalidades básicas de refatoração através de um ficheiro JSON fácil de ler.

Adicionar suporte para Configuração de Linguagem a uma extensão Visual Studio

Existem três partes para adicionar suporte de Configuração de Linguagem a uma extensão do Visual Studio:

  1. Criar um projeto VSIX
  2. Criar um ficheiro de Configuração de Linguagem
  3. Adicionar um ficheiro gramatical
  4. Atualizar o ficheiro pkgdef

Pode explorar um exemplo funcional em Language Configuration Sample.

Criar um projeto VSIX

Para criar uma extensão de serviço de linguagem usando o Language Configuration, primeiro certifique-se de que tem instalado o Workload de desenvolvimento de extensões do Visual Studio para a sua instância do VS.

De seguida, crie um novo projeto VSIX navegando até Fichar>Novo Projeto, procure por "vsix" e procure por Projeto VSIX:

Captura de ecrã a mostrar como criar um projeto VSIX.

Criar um ficheiro de configuração de linguagem

Ao criar o seu próprio ficheiro de configuração de linguagem, pode escolher quais os aspetos a integrar no ficheiro JSON. Por exemplo, pode optar por suportar a alternância de comentários, o fecho automático dos coletes ou qualquer combinação das funcionalidades disponíveis descritas nesta secção.

Para adicionar suporte à sua extensão, primeiro cria um ficheiro de configuração de linguagem. O nome do ficheiro deve seguir um padrão: usar hífenes para separar as palavras no nome do ficheiro e garantir que termina em language-configuration.json.

O código seguinte mostra um ficheiro de configuração de linguagem de exemplo.

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

Definições de configuração

As secções seguintes descrevem as definições disponíveis no ficheiro de configuração da língua.

Alternância de comentários

Os ficheiros de configuração de linguagem oferecem dois comandos para alternar comentários. Alternar Comentário de Linha e Alternar Comentário de Bloco. Podes especificar comments.blockComment e comments.lineComment para controlar a forma como o Visual Studio deve comentar as linhas / blocos.

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

Esta configuração afeta o comportamento do editor de texto do Visual Studio quando pressiona Ctrl+K, Ctrl+C.

Definição entre parênteses

Quando moves o cursor para um colchete definido aqui, o Visual Studio destaca esse colchete juntamente com o par correspondente.

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

No painel Opções de Ferramentas>, a definição relevante é a opção Ativar colorização de pares de chaves, localizada em Todas as Definições>Editor de Texto>Geral>Exibir.

No diálogo Ferramentas Opções>, a definição relevante é a opção Ativar coloração de pares de chaves, localizada em Editor de Texto>Geral>Visualização.

Fecho automático

Quando escreves ', o Visual Studio cria um par de aspas simples e coloca o cursor no meio: '|'. Esta secção define tais pares.

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

A notIn chave desativa esta funcionalidade em certos intervalos de código. Por exemplo, quando está a escrever o seguinte código:

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

A citação única não está fechada automaticamente.

Pares que não requerem uma notIn propriedade também podem usar uma sintaxe mais simples:

{
  "autoClosingPairs": [ ["{", "}"], ["[", "]"] ]
}
Fecho automático prévio

Por defeito, o Visual Studio só fecha automaticamente pares se houver espaço em branco logo após o cursor. Assim, quando escreves { o seguinte código JSX, não obtés autofechamento:

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

No entanto, esta definição sobrepõe-se a esse comportamento:

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

Agora, quando introduzir { logo antes de >, o Visual Studio fecha automaticamente com }.

Autocircundante

Quando seleciona um intervalo no Visual Studio e insere um colchete de abertura, o Visual Studio rodeia o conteúdo selecionado com um par de parênteses. Esta funcionalidade chama-se Autosurrounding, e nesta secção pode definir os pares de autosurrounding para um idioma específico.

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

No painel Ferramentas Opções>, a definição relevante é a opção Circundar automaticamente as seleções ao digitar aspas ou colchetes, localizada em Todas as Definições>Editor de Texto>Geral>Exibição.

No diálogo Ferramentas Opções>, a definição relevante é a opção Automaticamente envolver seleções ao digitar aspas ou parênteses, localizada em Editor de Texto>Geral>Exibição.

Padrão de palavras

wordPattern define o que é considerado uma palavra na linguagem de programação. As funcionalidades de sugestão de código usam esta configuração para determinar os limites das palavras se wordPattern estiver definida.

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

Regras de indentação

indentationRules define como o editor deve ajustar a indentação da linha atual ou da linha seguinte quando escreves, colas e moves linhas, ou quando formatas texto com Ctrl+K, Ctrl+D (Formatar Documento) e Ctrl+K, Ctrl+F (Seleção de Formato).

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

Por exemplo, se if (true) { corresponder a increaseIndentPattern, então ao carregares em Enter após o colchete { aberto, o editor irá indentar automaticamente uma vez, e o teu código acabará como:

if (true) {
  console.log();

Além de increaseIndentPattern e decreaseIndentPatter, existem outras duas regras de indentação:

  • indentNextLinePattern - Se uma linha corresponder a este padrão, então apenas a linha seguinte deverá ser recuada uma vez.
  • unIndentedLinePattern - Se uma linha corresponder a este padrão, então a sua indentação não deve ser alterada nem avaliada segundo as outras regras.

Se não houver um conjunto de regras de indentação para a linguagem de programação, o editor indenta quando a linha termina com um colchete aberto e undenta quando escreves um colchete de fechamento. O colchete aqui é definido por brackets.

Pressionar a tecla Enter

onEnterRules define uma lista de regras a avaliar quando Enter é pressionado no editor.

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

Ao pressionar Enter, o texto antes, depois ou uma linha acima do cursor é verificado contra as seguintes propriedades:

  • beforeText (obrigatório). Uma expressão regular que corresponde ao texto antes do cursor (limitada à linha atual).
  • afterText. Uma expressão regular que corresponde ao texto após o cursor (limitada à linha atual).
  • previousLineText. Uma expressão regular que corresponde ao texto uma linha acima do cursor.

Se todas as propriedades especificadas coincidirem, a regra é considerada uma correspondência e nenhuma outra onEnterRules é avaliada. An onEnterRule pode especificar as seguintes ações:

  • indent (obrigatório). Um dos none, indent, outdent, indentOutdent.
    • none significa que a nova linha herda a indentação da linha atual.
    • indent significa que a nova linha está indentada em relação à linha atual.
    • outdent significa que a nova linha não tem indentação em relação à linha atual.
    • indentOutdent significa que são inseridas duas novas linhas, uma indentada e a segunda sem indentar.
  • appendText. Uma cadeia que é adicionada após a nova linha e depois da indentação.
  • removeText. O número de caracteres a serem removidos da identação da nova linha.

Configurações de propriedade

No projeto de extensão, certifique-se de que o seu language-configuration.json ficheiro tem as seguintes definições de propriedades:

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

(Opcional) Adicionar um ficheiro gramatical

Além disso, pode adicionar um ficheiro gramatical TextMate para fornecer coloração sintática para a língua. As gramáticas TextMate são uma coleção estruturada de expressões regulares e são escritas como ficheiros plist (XML) ou JSON. Ver Gramáticas de Línguas. Se não fornecer um ficheiro gramatical específico da língua, é usada uma definição padrão incorporada.

Para adicionar ficheiros de gramática ou tema personalizados do TextMate, siga estes passos:

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

  2. Dentro da pasta Gramáticas, inclua qualquer *.tmlanguage, *.plist, *.tmthemeou qualquer outro *.json arquivos que pretende que forneçam colorização personalizada.

    Sugestão

    Um arquivo .tmtheme define como os âmbitos são mapeados para classificações do Visual Studio (identificadores de cor nomeados). Para orientação, pode-se fazer referência ao arquivo global .tmtheme no diretório <%ProgramFiles(x86)%\Microsoft Visual Studio\>versão<\>SKU\Common7\IDE\CommonExtensions\Microsoft\TextMate\Starterkit\Themesg.

Criar um ficheiro pkgdef

De seguida, cria um .pkgdef ficheiro. Um .pkgdef ficheiro contém toda a informação de registo que, de outra forma, seria adicionada ao registo do sistema. Para mais informações sobre pkgdef ficheiros, consulte Registo de VSPackages e O que é um ficheiro pkgdef? E porquê?. No teu pkgdef ficheiro, deves ter o caminho para o language-configuration.json ficheiro e o caminho para a gramática da linguagem. Serviços linguísticos como o LSP pedem o tipo de conteúdo do editor e obtêm-no através da Language Configuration. Esta informação fornece a inteligência específica da linguagem dentro de um servidor que pode comunicar com ferramentas de desenvolvimento. Quando um serviço de linguagem não existe, o motor de Configuração de Linguagem recorre à gramática TextMate. O seu .pkgdef ficheiro deve ter o seguinte aspeto:

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

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

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

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

Certifique-se de que as propriedades do pkgdef ficheiro estão definidas da seguinte forma:

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

Para tornar a informação de configuração da linguagem acessível para o Visual Studio, inclua o language-configuration ficheiro no pacote VSIX. Incluir este ficheiro significa que vem com a extensão Visual Studio. O ficheiro informa o Visual Studio de que existe uma Configuração de Linguagem disponível para uso. Para adicionar o ficheiro, edite o seu vsixmanifest para adicionar o seu ficheiro PKGDEF def, por exemplo:

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