Points d’extension du service de langage et de l’éditeur

L’éditeur fournit des points d’extension que vous pouvez étendre en tant que composants MEF (Managed Extensibility Framework), y compris la plupart des fonctionnalités du service de langage. Voici les principales catégories de points d’extension :

  • Types de contenu

  • Types de classification et formats de classification

  • Marges et barres de défilement

  • Balises

  • Ornements

  • Processeurs de souris

  • Gestionnaires de suppression

  • Options

  • IntelliSense

Étendre les types de contenu

Les types de contenu sont les définitions des types de texte gérés par l’éditeur, par exemple « text », « code » ou « CSharp ». Vous définissez un nouveau type de contenu en déclarant une variable du type ContentTypeDefinition et en donnant au nouveau type de contenu un nom unique. Pour inscrire le type de contenu auprès de l’éditeur, exportez-le avec les attributs suivants :

  • NameAttribute est le nom du type de contenu.

  • BaseDefinitionAttribute est le nom du type de contenu à partir duquel ce type de contenu est dérivé. Un type de contenu peut hériter de plusieurs autres types de contenu.

    Étant donné que la ContentTypeDefinition classe est scellée, vous pouvez l’exporter sans paramètre de type.

    L’exemple suivant montre les attributs d’exportation sur une définition de type de contenu.

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

Les types de contenu peuvent être basés sur zéro ou plusieurs types de contenu préexistants. Voici les types intégrés :

  • Tout : type de contenu de base. Parent de tous les autres types de contenu.

  • Texte : type de base pour le contenu non-projection. Hérite de « any ».

  • Texte en clair : pour le texte non codé. Hérite de « text ».

  • Code : pour le code de toutes sortes. Hérite de « text ».

  • Inert : exclut le texte de tout type de gestion. Le texte de ce type de contenu n’aura jamais d’extension appliquée.

  • Projection : pour le contenu des mémoires tampons de projection. Hérite de « any ».

  • IntelliSense : pour le contenu d’IntelliSense. Hérite de « text ».

  • Sighelp : aide de signature. Hérite de « intellisense ».

  • Sighelp-doc : documentation d’aide sur la signature. Hérite de « intellisense ».

    Voici quelques-uns des types de contenu définis par Visual Studio et certaines des langues hébergées dans Visual Studio :

  • De base

  • C/C++

  • ConsoleOutput

  • CSharp

  • CSS

  • ENC

  • FindResults

  • F#

  • HTML

  • JScript

  • XAML

  • XML

    Pour découvrir la liste des types de contenu disponibles, importez le IContentTypeRegistryService, qui gère la collection de types de contenu pour l’éditeur. Le code suivant importe ce service en tant que propriété.

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

Pour associer un type de contenu à une extension de nom de fichier, utilisez FileExtensionToContentTypeDefinition.

Remarque

Dans Visual Studio, les extensions de nom de fichier sont inscrites à l’aide du ProvideLanguageExtensionAttribute package de service de langage. L’association FileExtensionToContentTypeDefinition d’un type de contenu MEF à une extension de nom de fichier qui a été inscrite de cette façon.

Pour exporter l’extension de nom de fichier vers la définition de type de contenu, vous devez inclure les attributs suivants :

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

Gère IFileExtensionRegistryService les associations entre les extensions de nom de fichier et les types de contenu.

Étendre les types de classification et les formats de classification

Vous pouvez utiliser des types de classification pour définir les types de texte pour lesquels vous souhaitez fournir une gestion différente (par exemple, la couleur du texte « mot clé » bleu et le vert de texte « commentaire »). Définissez un nouveau type de classification en déclarant une variable de type ClassificationTypeDefinition et en lui donnant un nom unique.

Pour inscrire le type de classification auprès de l’éditeur, exportez-le avec les attributs suivants :

  • NameAttribute: nom du type de classification.

  • BaseDefinitionAttribute: nom du type de classification à partir duquel ce type de classification hérite. Tous les types de classification héritent de « text », et un type de classification peut hériter de plusieurs autres types de classification.

    Étant donné que la ClassificationTypeDefinition classe est scellée, vous pouvez l’exporter sans paramètre de type.

    L’exemple suivant montre les attributs d’exportation sur une définition de type de classification.

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

L’accès IStandardClassificationService aux classifications standard est fourni. Les types de classification intégrés sont les suivants :

  • "text"

  • « langage naturel » (dérive de « texte »)

  • « langage formel » (dérive de « texte »)

  • « string » (dérive de « littéral »)

  • « character » (dérive de « littéral »)

  • « numérique » (dérive de « littéral »)

    Un ensemble de différents types d’erreurs héritent de ErrorTypeDefinition. Ils incluent les types d’erreurs suivants :

  • « erreur de syntaxe »

  • « Erreur du compilateur »

  • « autre erreur »

  • « avertissement »

    Pour découvrir la liste des types de classification disponibles, importez la IClassificationTypeRegistryServicecollection de types de classification pour l’éditeur. Le code suivant importe ce service en tant que propriété.

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

Vous pouvez définir une définition de format de classification pour votre nouveau type de classification. Dérivez une classe de ClassificationFormatDefinition et exportez-la avec le type EditorFormatDefinition, ainsi que les attributs suivants :

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

Pour découvrir la liste des formats disponibles, importez la IEditorFormatMapServicecollection de formats pour l’éditeur. Le code suivant importe ce service en tant que propriété.

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

Étendre les marges et les barres de défilement

Les marges et les barres de défilement sont les principaux éléments d’affichage de l’éditeur en plus de la vue de texte elle-même. Vous pouvez fournir n’importe quel nombre de marges en plus des marges standard qui apparaissent autour de la vue de texte.

Implémentez une IWpfTextViewMargin interface pour définir une marge. Vous devez également implémenter l’interface IWpfTextViewMarginProvider pour créer la marge.

Pour inscrire le fournisseur de marge avec l’éditeur, vous devez exporter le fournisseur avec les attributs suivants :

  • NameAttribute: nom de la marge.

  • OrderAttribute: ordre dans lequel la marge apparaît, par rapport aux autres marges.

    Voici les marges intégrées :

    • « Barre de défilement horizontale Wpf »

    • « Barre de défilement verticale Wpf »

    • « Marge de numéro de ligne Wpf »

      Les marges horizontales qui ont un attribut After="Wpf Horizontal Scrollbar" d’ordre sont affichées sous la marge intégrée et les marges horizontales dont l’attribut Before ="Wpf Horizontal Scrollbar" d’ordre est affiché au-dessus de la marge intégrée. Les marges verticales droites dont l’attribut After="Wpf Vertical Scrollbar" d’ordre est affiché à droite de la barre de défilement. Les marges verticales gauches dont l’attribut After="Wpf Line Number Margin" d’ordre apparaît à gauche de la marge de numéro de ligne (s’il est visible).

  • MarginContainerAttribute: type de marge (gauche, droite, haut ou bas).

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») pour lequel votre marge est valide.

    L’exemple suivant montre les attributs d’exportation sur un fournisseur de marge pour une marge qui apparaît à droite de la marge de numéro de ligne.

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

Étendre les balises

Les balises permettent d’associer des données à différents types de texte. Dans de nombreux cas, les données associées sont affichées en tant qu’effet visuel, mais toutes les balises n’ont pas de présentation visuelle. Vous pouvez définir votre propre type d’étiquette en implémentant ITag. Vous devez également implémenter ITagger<T> pour fournir les balises d’un ensemble donné d’étendues de texte et fournir ITaggerProvider le balisage. Vous devez exporter le fournisseur de balisage avec les attributs suivants :

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») pour lequel votre balise est valide.

  • TagTypeAttribute: type de balise.

    L’exemple suivant montre les attributs d’exportation sur un fournisseur de balisage.

<CodeContentPlaceHolder>8 Les types d’étiquettes suivants sont intégrés :

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

Balises et MarkerFormatDefinitions

Vous pouvez étendre la MarkerFormatDefinition classe pour définir l’apparence d’une balise. Vous devez exporter votre classe (en tant que ) EditorFormatDefinitionavec les attributs suivants :

  • NameAttribute: nom utilisé pour référencer ce format

  • UserVisibleAttribute: cela entraîne l’affichage du format dans l’interface utilisateur

    Dans le constructeur, vous définissez le nom d’affichage et l’apparence de la balise. BackgroundColor définit la couleur de remplissage et ForegroundColor définit la couleur de bordure. Il DisplayName s’agit du nom localisable de la définition de format.

    Voici un exemple de définition de format :

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

Pour appliquer cette définition de format à une balise, référencez le nom que vous avez défini dans l’attribut name de la classe (et non le nom complet).

Remarque

Pour obtenir un exemple d’un MarkerFormatDefinition, consultez la classe HighlightWordFormatDefinition dans Walkthrough : Mise en surbrillance du texte.

Étendre les ornements

Les ornements définissent des effets visuels qui peuvent être ajoutés au texte affiché dans un affichage texte ou à l’affichage de texte lui-même. Vous pouvez définir votre propre ornement comme n’importe quel type de UIElement.

Dans votre classe d’ornement, vous devez déclarer un AdornmentLayerDefinition. Pour inscrire votre couche d’ornement, exportez-la avec les attributs suivants :

  • NameAttribute: nom de l’ornement.

  • OrderAttribute: ordre de l’ornement par rapport à d’autres couches d’ornement. La classe PredefinedAdornmentLayers définit quatre couches par défaut : Sélection, Plan, Caret et Text.

    L’exemple suivant montre les attributs d’exportation sur une définition de couche d’ornement.

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

Vous devez créer une deuxième classe qui implémente IWpfTextViewCreationListener et gère son TextViewCreated événement en instanciant l’ornement. Vous devez exporter cette classe avec les attributs suivants :

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») pour lequel l’ornement est valide.

  • TextViewRoleAttribute: type d’affichage de texte pour lequel cet ornement est valide. La classe PredefinedTextViewRoles a l’ensemble de rôles d’affichage de texte prédéfinis. Par exemple, Document il est principalement utilisé pour les vues de texte des fichiers. Interactive est utilisé pour les vues de texte qu’un utilisateur peut modifier ou naviguer à l’aide d’une souris et d’un clavier. Les exemples de vues sont l’affichage texte de Interactive l’éditeur et la fenêtre Sortie .

    L’exemple suivant montre les attributs d’exportation sur le fournisseur d’ornements.

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

Un ornement de négociation de l’espace est celui qui occupe l’espace au même niveau que le texte. Pour créer ce type d’ornement, vous devez définir une classe d’étiquette qui hérite de SpaceNegotiatingAdornmentTag, qui définit la quantité d’espace occupée par l’ornement.

Comme avec toutes les ornements, vous devez exporter la définition de couche d’ornement.

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

Pour instancier l’ornement de négociation de l’espace, vous devez créer une classe qui implémente ITaggerProvider, en plus de la classe qui implémente IWpfTextViewCreationListener (comme avec d’autres types d’ornements).

Pour inscrire le fournisseur de balisage, vous devez l’exporter avec les attributs suivants :

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») pour lequel votre ornement est valide.

  • TextViewRoleAttribute: type d’affichage de texte pour lequel cette balise ou ornement est valide. La classe PredefinedTextViewRoles a l’ensemble de rôles d’affichage de texte prédéfinis. Par exemple, Document il est principalement utilisé pour les vues de texte des fichiers. Interactive est utilisé pour les vues de texte qu’un utilisateur peut modifier ou naviguer à l’aide d’une souris et d’un clavier. Les exemples de vues sont l’affichage texte de Interactive l’éditeur et la fenêtre Sortie .

  • TagTypeAttribute: type d’étiquette ou d’ornement que vous avez défini. Vous devez ajouter une seconde TagTypeAttribute pour SpaceNegotiatingAdornmentTag.

    L’exemple suivant montre les attributs d’exportation sur le fournisseur de balisage pour une balise d’ornement de négociation d’espace.

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

Extension des processeurs de souris

Vous pouvez ajouter une gestion spéciale pour l’entrée de la souris. Créez une classe qui hérite des événements de MouseProcessorBase souris et remplacez les événements de souris pour l’entrée que vous souhaitez gérer. Vous devez également implémenter IMouseProcessorProvider dans une deuxième classe et l’exporter avec le ContentTypeAttribute type de contenu (par exemple, « texte » ou « code ») pour lequel votre gestionnaire de souris est valide.

L’exemple suivant montre les attributs d’exportation sur un fournisseur de processeur de souris.

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

Étendre les gestionnaires de suppression

Vous pouvez personnaliser le comportement des gestionnaires de suppression pour des types de texte spécifiques en créant une classe qui implémente IDropHandler et une deuxième classe qui implémente IDropHandlerProvider pour créer le gestionnaire de suppression. Vous devez exporter le gestionnaire de suppression avec les attributs suivants :

  • DropFormatAttribute: format de texte pour lequel ce gestionnaire de suppression est valide. Les formats suivants sont gérés dans l’ordre de priorité le plus élevé au plus bas :

    1. Tout format personnalisé

    2. FileDrop

    3. EnhancedMetafile

    4. WaveAudio

    5. Riff

    6. Dif

    7. Paramètres régionaux

    8. Palette

    9. PenData

    10. Sérialisable

    11. SymbolLink

    12. Xaml

    13. XamlPackage

    14. Tiff

    15. Bitmap

    16. Dib

    17. MetafilePicture

    18. CSV

    19. System.String

    20. HTML Format

    21. UnicodeText

    22. OEMText

    23. Texte

  • NameAttribute: nom du gestionnaire de suppression.

  • OrderAttribute: classement du gestionnaire de suppression avant ou après le gestionnaire de suppression par défaut. Le gestionnaire de suppression par défaut pour Visual Studio est nommé « DefaultFileDropHandler ».

    L’exemple suivant montre les attributs d’exportation sur un fournisseur de gestionnaires de suppression.

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

Extension des options de l’éditeur

Vous pouvez définir des options pour être valides uniquement dans une certaine étendue, par exemple dans une vue de texte. L’éditeur fournit cet ensemble d’options prédéfinies : options d’éditeur, options d’affichage et options d’affichage WPF (Windows Presentation Foundation). Ces options sont disponibles dans DefaultOptions, DefaultTextViewOptionset DefaultWpfViewOptions.

Pour ajouter une nouvelle option, dérivez une classe de l’une de ces classes de définition d’option :

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

Étendre IntelliSense

IntelliSense est un terme général pour un groupe de fonctionnalités qui fournissent des informations sur le texte structuré et la saisie semi-automatique des instructions. Ces fonctionnalités incluent la saisie semi-automatique des instructions, l’aide de signature, les infos rapides et les ampoules. La saisie semi-automatique des instructions permet aux utilisateurs de taper correctement un nom de langue mot clé ou de membre. L’aide sur les signatures affiche la signature ou les signatures de la méthode que l’utilisateur vient de taper. Les informations rapides affichent une signature complète pour un nom de type ou de membre lorsque la souris se trouve sur celle-ci. L’ampoule fournit des actions supplémentaires pour certains identificateurs dans certains contextes, par exemple, renommage de toutes les occurrences d’une variable après un changement de nom.

La conception d’une fonctionnalité IntelliSense est beaucoup la même dans tous les cas :

  • Un répartiteur IntelliSense est responsable du processus global.

  • Une session IntelliSense représente la séquence d’événements entre le déclenchement du présentateur et la validation ou l’annulation de la sélection. La session est généralement déclenchée par un mouvement utilisateur.

  • Un contrôleur IntelliSense est chargé de décider quand la session doit démarrer et se terminer. Il décide également quand les informations doivent être validées et quand la session doit être annulée.

  • Une source IntelliSense fournit le contenu et décide de la meilleure correspondance.

  • Un présentateur IntelliSense est responsable de l’affichage du contenu.

    Dans la plupart des cas, nous vous recommandons de fournir au moins une source et un contrôleur. Vous pouvez également fournir un présentateur si vous souhaitez personnaliser l’affichage.

Implémenter une source IntelliSense

Pour personnaliser une source, vous devez implémenter une (ou plusieurs) des interfaces sources suivantes :

Important

ISmartTagSource a été déprécié en faveur de ISuggestedActionsSource.

En outre, vous devez implémenter un fournisseur du même type :

Important

ISmartTagSourceProvider a été déprécié en faveur de ISuggestedActionsSourceProvider.

Vous devez exporter le fournisseur avec les attributs suivants :

  • NameAttribute: nom de la source.

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») auquel la source s’applique.

  • OrderAttribute: ordre dans lequel la source doit apparaître (par rapport à d’autres sources).

  • L’exemple suivant montre les attributs d’exportation sur un fournisseur source d’achèvement.

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

Pour plus d’informations sur l’implémentation de sources IntelliSense, consultez les procédures pas à pas suivantes :

Implémenter un contrôleur IntelliSense

Pour personnaliser un contrôleur, vous devez implémenter l’interface IIntellisenseController . En outre, vous devez implémenter un fournisseur de contrôleur avec les attributs suivants :

  • NameAttribute: nom du contrôleur.

  • ContentTypeAttribute: type de contenu (par exemple, « texte » ou « code ») auquel le contrôleur s’applique.

  • OrderAttribute: l’ordre dans lequel le contrôleur doit apparaître (par rapport à d’autres contrôleurs).

    L’exemple suivant montre les attributs d’exportation sur un fournisseur de contrôleur de saisie semi-automatique.

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

Pour plus d’informations sur l’utilisation des contrôleurs IntelliSense, consultez les procédures pas à pas suivantes :