Compartilhar via


Pontos de extensão do editor e do serviço de idioma

O editor fornece pontos de extensão que você pode estender como partes do componente MEF (Managed Extensibility Framework), incluindo a maioria dos recursos de serviço de idioma. Estas são as principais categorias de pontos de extensão:

  • Tipos de conteúdo

  • Tipos de classificação e formatos de classificação

  • Margens e barras de rolagem

  • Marcações

  • Adornos

  • Processadores de mouse

  • Manipuladores de queda

  • Opções

  • IntelliSense

Estender tipos de conteúdo

Tipos de conteúdo são as definições dos tipos de texto manipulados pelo editor, por exemplo, "texto", "código" ou "CSharp". Você define um novo tipo de conteúdo declarando uma variável do tipo e dando ao novo tipo ContentTypeDefinition de conteúdo um nome exclusivo. Para registrar o tipo de conteúdo com o editor, exporte-o junto com os seguintes atributos:

  • NameAttribute é o nome do tipo de conteúdo.

  • BaseDefinitionAttribute é o nome do tipo de conteúdo do qual esse tipo de conteúdo é derivado. Um tipo de conteúdo pode herdar de vários outros tipos de conteúdo.

    Como a ContentTypeDefinition classe é selada, você pode exportá-la sem nenhum parâmetro de tipo.

    O exemplo a seguir mostra atributos de exportação em uma definição de tipo de conteúdo.

[Export]
[Name("test")]
[BaseDefinition("code")]
[BaseDefinition("projection")]
internal static ContentTypeDefinition TestContentTypeDefinition;

Os tipos de conteúdo podem ser baseados em zero ou mais tipos de conteúdo pré-existentes. Estes são os tipos internos:

  • Qualquer: o tipo de conteúdo básico. Pai de todos os outros tipos de conteúdo.

  • Texto: o tipo básico para conteúdo não projetivo. Herda de "qualquer".

  • Texto sem formatação: para texto não codificado. Herda de "texto".

  • Código: para códigos de todos os tipos. Herda de "texto".

  • Inerte: exclui o texto de qualquer tipo de manuseio. O texto desse tipo de conteúdo nunca terá nenhuma extensão aplicada a ele.

  • Projeção: para o conteúdo de buffers de projeção. Herda de "qualquer".

  • Intellisense: para o conteúdo do IntelliSense. Herda de "texto".

  • Sighelp: ajuda de assinatura. Herda de "intellisense".

  • Sighelp-doc: documentação de ajuda de assinatura. Herda de "intellisense".

    Estes são alguns dos tipos de conteúdo que são definidos pelo Visual Studio e algumas das linguagens que são hospedadas no Visual Studio:

  • Basic

  • C/C++

  • ConsoleOutput

  • CSharp

  • CSS

  • ENC

  • FindResults

  • F#

  • HTML

  • JScript

  • XAML

  • XML

    Para descobrir a lista de tipos de conteúdo disponíveis, importe o , que mantém a coleção de tipos de conteúdo para o IContentTypeRegistryServiceeditor. O código a seguir importa esse serviço como uma propriedade.

[Import]
internal IContentTypeRegistryService ContentTypeRegistryService { get; set; }

Para associar um tipo de conteúdo a uma extensão de nome de arquivo, use FileExtensionToContentTypeDefinition.

Observação

No Visual Studio, as extensões de nome de arquivo são registradas usando o em um pacote de serviço de ProvideLanguageExtensionAttribute idioma. O FileExtensionToContentTypeDefinition associa um tipo de conteúdo MEF a uma extensão de nome de arquivo que foi registrada dessa maneira.

Para exportar a extensão de nome de arquivo para a definição de tipo de conteúdo, você deve incluir os seguintes atributos:

[Export]
[FileExtension(".test")]
[ContentType("test")]
internal static FileExtensionToContentTypeDefinition TestFileExtensionDefinition;

O IFileExtensionRegistryService gerencia as associações entre extensões de nome de arquivo e tipos de conteúdo.

Estender tipos de classificação e formatos de classificação

Você pode usar tipos de classificação para definir os tipos de texto para os quais deseja fornecer manipulação diferente (por exemplo, colorir o texto da "palavra-chave" de azul e o texto do "comentário" de verde). Defina um novo tipo de classificação declarando uma variável de tipo ClassificationTypeDefinition e dando-lhe um nome exclusivo.

Para registrar o tipo de classificação com o editor, exporte-o junto com os seguintes atributos:

  • NameAttribute: o nome do tipo de classificação.

  • BaseDefinitionAttribute: o nome do tipo de classificação do qual esse tipo de classificação herda. Todos os tipos de classificação herdam de "texto", e um tipo de classificação pode herdar de vários outros tipos de classificação.

    Como a ClassificationTypeDefinition classe é selada, você pode exportá-la sem nenhum parâmetro de tipo.

    O exemplo a seguir mostra atributos de exportação em uma definição de tipo de classificação.

[Export]
[Name("csharp.test")]
[BaseDefinition("test")]
internal static ClassificationTypeDefinition CSharpTestDefinition;

O IStandardClassificationService fornece acesso a classificações padrão. Os tipos de classificação internos incluem estes:

  • "texto"

  • "linguagem natural" (deriva de "texto")

  • "linguagem formal" (deriva de "texto")

  • "string" (deriva de "literal")

  • "personagem" (deriva de "literal")

  • "numérico" (deriva de "literal")

    Um conjunto de tipos de erro diferentes herda do ErrorTypeDefinition. Eles incluem os seguintes tipos de erro:

  • "erro de sintaxe"

  • "erro do compilador"

  • "outro erro"

  • "Atenção"

    Para descobrir a lista de tipos de classificação disponíveis, importe o , que mantém a coleção de tipos de classificação para o IClassificationTypeRegistryServiceeditor. O código a seguir importa esse serviço como uma propriedade.

[Import]
internal IClassificationTypeRegistryService ClassificationTypeRegistryService { get; set; }

Você pode definir uma definição de formato de classificação para seu novo tipo de classificação. Derive uma classe de ClassificationFormatDefinition e exporte-a com o tipo EditorFormatDefinition, juntamente com os seguintes atributos:

[Export(typeof(EditorFormatDefinition))]
[ClassificationType(ClassificationTypeNames = "test")]
[Name("test")]
[DisplayName("Test")]
[UserVisible(true)]
[Order(After = Priority.Default, Before = Priority.High)]
internal sealed class TestFormat : ClassificationFormatDefinition

Para descobrir a lista de formatos disponíveis, importe o , que mantém a coleção de formatos para o IEditorFormatMapServiceeditor. O código a seguir importa esse serviço como uma propriedade.

[Import]
internal IEditorFormatMapService FormatMapService { get; set; }

Estender margens e barras de rolagem

Margens e barras de rolagem são os principais elementos de exibição do editor, além da própria exibição de texto. Você pode fornecer qualquer número de margens, além das margens padrão que aparecem ao redor do modo de exibição de texto.

Implemente uma interface para definir uma IWpfTextViewMargin margem. Você também deve implementar a interface para criar a IWpfTextViewMarginProvider margem.

Para registrar o provedor de margem com o editor, você deve exportar o provedor junto com os seguintes atributos:

  • NameAttribute: o nome da margem.

  • OrderAttribute: a ordem em que a margem aparece, em relação às outras margens.

    Estas são as margens internas:

    • "Barra de rolagem horizontal do WPF"

    • "Barra de rolagem vertical do WPF"

    • "Margem do número de linha do WPF"

      As margens horizontais que têm um atributo order de são exibidas abaixo da margem interna e as margens horizontais que têm um atributo order After="Wpf Horizontal Scrollbar" of Before ="Wpf Horizontal Scrollbar" são exibidas acima da margem interna. As margens verticais direitas que têm um atributo order de são exibidas à direita da barra de After="Wpf Vertical Scrollbar" rolagem. As margens verticais esquerdas que têm um atributo order de aparecem à esquerda da margem do número de After="Wpf Line Number Margin" linha (se estiver visível).

  • MarginContainerAttribute: o tipo de margem (esquerda, direita, superior ou inferior).

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") para o qual sua margem é válida.

    O exemplo a seguir mostra atributos de exportação em um provedor de margem para uma margem que aparece à direita da margem do número de linha.

[Export(typeof(IWpfTextViewMarginProvider))]
[Name("TestMargin")]
[Order(Before = "Wpf Line Number Margin")]
[MarginContainer(PredefinedMarginNames.Left)]
[ContentType("text")]

Estender tags

As tags são uma forma de associar dados a diferentes tipos de texto. Em muitos casos, os dados associados são exibidos como um efeito visual, mas nem todas as marcas têm uma apresentação visual. Você pode definir seu próprio tipo de tag implementando ITago . Você também deve implementar ITagger<T> para fornecer as marcas para um determinado conjunto de extensões de texto e um ITaggerProvider para fornecer o tagger. Você deve exportar o provedor de tagger junto com os seguintes atributos:

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") para o qual sua tag é válida.

  • TagTypeAttribute: o tipo de tag.

    O exemplo a seguir mostra atributos de exportação em um provedor de pichador.

<CodeContentPlaceHolder>8 Os seguintes tipos de tag são internos:

[Import]
internal IViewTagAggregatorFactoryService ViewTagAggregatorFactoryService { get; set; }

Tags e MarkerFormatDefinitions

Você pode estender a classe para definir a MarkerFormatDefinition aparência de uma marca. Você deve exportar sua classe (como um EditorFormatDefinition) com os seguintes atributos:

  • NameAttribute: o nome usado para fazer referência a este formato

  • UserVisibleAttribute: isso faz com que o formato apareça na interface do usuário

    No construtor, você define o nome para exibição e a aparência da marca. BackgroundColor Define a cor de preenchimento e ForegroundColor define a cor da borda. O DisplayName é o nome localizável da definição de formato.

    Veja a seguir um exemplo de uma definição de formato:

[Export(typeof(EditorFormatDefinition))]
[Name("MarkerFormatDefinition/HighlightWordFormatDefinition")]
[UserVisible(true)]
internal class HighlightWordFormatDefinition : MarkerFormatDefinition
{
    public HighlightWordFormatDefinition()
    {
        this.BackgroundColor = Colors.LightBlue;
        this.ForegroundColor = Colors.DarkBlue;
        this.DisplayName = "Highlight Word";
        this.ZOrder = 5;
    }
}

Para aplicar essa definição de formato a uma marca, faça referência ao nome definido no atributo name da classe (não ao nome para exibição).

Observação

Para obter um exemplo de um MarkerFormatDefinition, consulte a classe HighlightWordFormatDefinition em Passo a passo: realçando texto.

Estender adornos

Os adornos definem efeitos visuais que podem ser adicionados ao texto exibido em um modo de exibição de texto ou ao próprio modo de exibição de texto. Você pode definir seu próprio adorno como qualquer tipo de UIElement.

Em sua classe de adorno, você deve declarar um AdornmentLayerDefinitionarquivo . Para registrar sua camada de adorno, exporte-a juntamente com os seguintes atributos:

  • NameAttribute: o nome do adorno.

  • OrderAttribute: a ordenação do adorno em relação a outras camadas de adorno. A classe PredefinedAdornmentLayers define quatro camadas padrão: Seleção, Estrutura de Tópicos, Caret e Texto.

    O exemplo a seguir mostra atributos de exportação em uma definição de camada de adorno.

[Export]
[Name("TestEmbeddedAdornment")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
internal AdornmentLayerDefinition testLayerDefinition;

Você deve criar uma segunda classe que implementa IWpfTextViewCreationListener e manipula seu TextViewCreated evento instanciando o adorno. Você deve exportar essa classe junto com os seguintes atributos:

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") para o qual o adorno é válido.

  • TextViewRoleAttribute: o tipo de visualização de texto para o qual este adorno é válido. A classe PredefinedTextViewRoles tem o conjunto de funções de exibição de texto predefinidas. Por exemplo, Document é usado principalmente para exibições de texto de arquivos. Interactive é usado para modos de exibição de texto que um usuário pode editar ou navegar usando um mouse e teclado. Exemplos de modos de exibição são o modo de exibição de Interactive texto do editor e a janela Saída .

    O exemplo a seguir mostra atributos de exportação no provedor de adorno.

[Export(typeof(IWpfTextViewCreationListener))]
[ContentType("csharp")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class TestAdornmentProvider : IWpfTextViewCreationListener

Um adorno de negociação de espaço é aquele que ocupa espaço no mesmo nível do texto. Para criar esse tipo de adorno, você deve definir uma classe de tag que herda do , que define a quantidade de SpaceNegotiatingAdornmentTagespaço que o adorno ocupa.

Como acontece com todos os adornos, você deve exportar a definição da camada de adorno.

[Export]
[Name("TestAdornment")]
[Order(After = DefaultAdornmentLayers.Text)]
internal AdornmentLayerDefinition testAdornmentLayer;

Para instanciar o adorno de negociação de espaço, você deve criar uma classe que implementa , além da classe que implementa ITaggerProviderIWpfTextViewCreationListener (como com outros tipos de adornos).

Para registrar o provedor de tagger, você deve exportá-lo junto com os seguintes atributos:

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") para o qual seu adorno é válido.

  • TextViewRoleAttribute: o tipo de exibição de texto para o qual essa tag ou adorno é válido. A classe PredefinedTextViewRoles tem o conjunto de funções de exibição de texto predefinidas. Por exemplo, Document é usado principalmente para exibições de texto de arquivos. Interactive é usado para modos de exibição de texto que um usuário pode editar ou navegar usando um mouse e teclado. Exemplos de modos de exibição são o modo de exibição de Interactive texto do editor e a janela Saída .

  • TagTypeAttribute: o tipo de tag ou adorno que você definiu. Você deve adicionar um segundo TagTypeAttribute para SpaceNegotiatingAdornmentTago .

    O exemplo a seguir mostra atributos de exportação no provedor de tagger para uma marca de adorno de negociação de espaço.

[Export(typeof(ITaggerProvider))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
[TagType(typeof(SpaceNegotiatingAdornmentTag))]
[TagType(typeof(TestSpaceNegotiatingTag))]
internal sealed class TestTaggerProvider : ITaggerProvider

Estendendo processadores de mouse

Você pode adicionar manipulação especial para entrada do mouse. Crie uma classe que herde e substitua os eventos do MouseProcessorBase mouse para a entrada que você deseja manipular. Você também deve implementar IMouseProcessorProvider em uma segunda classe e exportá-la junto com o que especifica o tipo de conteúdo (por exemplo, "texto" ou "código") para o qual o ContentTypeAttribute manipulador do mouse é válido.

O exemplo a seguir mostra atributos de exportação em um provedor de processador de mouse.

[Export(typeof(IMouseProcessorProvider))]
[Name("test mouse processor")]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal sealed class TestMouseProcessorProvider : IMouseProcessorProvider

Estender manipuladores de queda

Você pode personalizar o comportamento de manipuladores de soltar para tipos específicos de texto criando uma classe que implementa e uma segunda classe que implementa IDropHandler IDropHandlerProvider para criar o manipulador de soltar. Você deve exportar o manipulador de soltar junto com os seguintes atributos:

  • DropFormatAttribute: o formato de texto para o qual esse manipulador de descarte é válido. Os seguintes formatos são tratados em ordem de prioridade do mais alto para o mais baixo:

    1. Qualquer formato personalizado

    2. FileDrop

    3. Metarquivo aprimorado

    4. WaveAudio

    5. Riff

    6. Dif

    7. Localidade

    8. Paleta

    9. PenData

    10. Serializável

    11. Ligação simbólica

    12. Xaml

    13. XamlPackage

    14. Tiff

    15. Bitmap

    16. Dib

    17. MetafilePicture

    18. CSV

    19. System.String

    20. Formato HTML

    21. UnicodeText

    22. OEMText

    23. Texto

  • NameAttribute: o nome do manipulador de gotas.

  • OrderAttribute: a ordem do manipulador de soltar antes ou depois do manipulador de soltar padrão. O manipulador de recebimento padrão para Visual Studio é chamado "DefaultFileDropHandler".

    O exemplo a seguir mostra atributos de exportação em um provedor de manipulador de gota.

[Export(typeof(IDropHandlerProvider))]
[DropFormat("Text")]
[Name("TestDropHandler")]
[Order(Before="DefaultFileDropHandler")]
internal class TestDropHandlerProvider : IDropHandlerProvider

Estendendo opções do editor

Você pode definir opções para serem válidas somente em um determinado escopo, por exemplo, em um modo de exibição de texto. O editor fornece esse conjunto de opções predefinidas: opções do editor, opções de exibição e opções de exibição do Windows Presentation Foundation (WPF). Essas opções podem ser encontradas em DefaultOptions, DefaultTextViewOptionse DefaultWpfViewOptions.

Para adicionar uma nova opção, derive uma classe de uma destas classes de definição de opção:

[Export(typeof(EditorOptionDefinition))]
internal sealed class TestOption : EditorOptionDefinition<bool>

Estenda o IntelliSense

IntelliSense é um termo geral para um grupo de recursos que fornecem informações sobre texto estruturado e conclusão de instrução para ele. Esses recursos incluem conclusão de instrução, ajuda de assinatura, Informações Rápidas e lâmpadas. A conclusão da instrução ajuda os usuários a digitar uma palavra-chave de idioma ou um nome de membro corretamente. A Ajuda de assinatura exibe a assinatura ou assinaturas do método que o usuário acabou de digitar. As Informações Rápidas exibem uma assinatura completa para um tipo ou nome de membro quando o mouse está sobre ele. As lâmpadas fornecem ações adicionais para determinados identificadores em determinados contextos, por exemplo, renomeando todas as ocorrências de uma variável após uma ocorrência ter sido renomeada.

O design de um recurso do IntelliSense é praticamente o mesmo em todos os casos:

  • Um corretor IntelliSense é responsável pelo processo geral.

  • Uma sessão do IntelliSense representa a sequência de eventos entre o acionamento do apresentador e a confirmação ou cancelamento da seleção. Normalmente, a sessão é acionada por algum gesto do usuário.

  • Um controlador IntelliSense é responsável por decidir quando a sessão deve começar e terminar. Ele também decide quando as informações devem ser confirmadas e quando a sessão deve ser cancelada.

  • Uma fonte IntelliSense fornece o conteúdo e decide a melhor correspondência.

  • Um apresentador IntelliSense é responsável por exibir o conteúdo.

    Na maioria dos casos, recomendamos que você forneça pelo menos uma fonte e um controlador. Você também pode fornecer um apresentador se quiser personalizar a exibição.

Implementar uma fonte do IntelliSense

Para personalizar uma origem, você deve implementar uma (ou mais) das seguintes interfaces de origem:

Importante

ISmartTagSource foi preterido em favor do ISuggestedActionsSource.

Além disso, você deve implementar um provedor do mesmo tipo:

Importante

ISmartTagSourceProvider foi preterido em favor do ISuggestedActionsSourceProvider.

Você deve exportar o provedor junto com os seguintes atributos:

  • NameAttribute: o nome da fonte.

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") ao qual a fonte se aplica.

  • OrderAttribute: a ordem em que a fonte deve aparecer (em relação a outras fontes).

  • O exemplo a seguir mostra atributos de exportação em um provedor de origem de conclusão.

Export(typeof(ICompletionSourceProvider))]
[Name(" Test Statement Completion Provider")]
[Order(Before = "default")]
[ContentType("text")]
internal class TestCompletionSourceProvider : ICompletionSourceProvider

Para obter mais informações sobre como implementar fontes do IntelliSense, consulte as seguintes instruções passo a passo:

Implementar um controlador IntelliSense

Para personalizar um controlador, você deve implementar a IIntellisenseController interface. Além disso, você deve implementar um provedor de controlador junto com os seguintes atributos:

  • NameAttribute: o nome do controlador.

  • ContentTypeAttribute: o tipo de conteúdo (por exemplo, "texto" ou "código") ao qual o controlador se aplica.

  • OrderAttribute: a ordem em que o controlador deve aparecer (em relação a outros controladores).

    O exemplo a seguir mostra atributos de exportação em um provedor de controlador de conclusão.

Export(typeof(IIntellisenseControllerProvider))]
[Name(" Test Controller Provider")]
[Order(Before = "default")]
[ContentType("text")]
internal class TestIntellisenseControllerProvider : IIntellisenseControllerProvider

Para obter mais informações sobre como usar controladores IntelliSense, consulte as seguintes instruções passo a passo: