Créer une extension simple
Dans Créer votre première extension, vous avez appris à utiliser le modèle de projet VisualStudio.Extensibility pour créer un projet d’extension et appris à le générer et à le déboguer dans l’instance expérimentale de Visual Studio.
Dans ce tutoriel, vous allez apprendre à créer une extension avec une commande simple qui effectue quelque chose dans l’éditeur Visual Studio. Dans ce cas, il insère un GUID nouvellement généré. Vous voyez également comment indiquer à Visual Studio quels types de fichiers l’extension GUID est activé et comment faire apparaître la nouvelle commande en tant qu’élément de barre d’outils ou de menu.
L’exemple terminé pour ce didacticiel est disponible ici.
Le tutoriel contient les étapes suivantes :
Configurer la commande
Dans cette étape, vous allez découvrir les options de configuration et de placement de la commande. L’objectif de l’hébergement de la commande est de l’exposer à l’utilisateur d’une certaine manière, comme l’ajout d’un élément de menu ou d’un bouton de barre de commandes.
Le modèle de projet ou l’exemple que vous avez créé dans le didacticiel Créer votre première extension se compose d’un seul fichier C# qui inclut déjà une Command
classe. Vous pouvez le mettre à jour en place.
Renommez le
Command1.cs
fichierInsertGuidCommand.cs
en , renommez la classeInsertGuidCommand
, mettez à jour laCommandConfiguration
propriété.public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%") { Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu }, };
Placements
spécifie où la commande doit apparaître dans l’IDE. Dans ce cas, la commande est placée dans le menu Extensions, l’un des menus de niveau supérieur dans Visual Studio.L’argument du
CommandConfiguration
constructeur est le nom d’affichage de la commande, qui est le texte du menu. Le nom complet est entouré de%
caractères, car il fait référence à une ressource de chaîne à partir de.vsextension/string-resources.json
laquelle elle prend en charge la localisation.Mettre à jour
.vsextension/string-resources.json
avec le nom complet deInsertGuidCommand
.{ "InsertGuidCommand.DisplayName": "Insert new guid" }
Ajouter la propriété
Icon
public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%") { Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu }, Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText), };
Vous pouvez spécifier une icône intégrée connue, dans ce cas
OfficeWebExtension
, ou charger des images pour l’icône, comme décrit dans Ajouter des commandes Visual Studio. Le deuxième argument est une énumération qui détermine comment la commande doit apparaître dans les barres d’outils (en plus de sa place dans un menu). L’optionIconSettings.IconAndText
signifie afficher l’icône et le nom d’affichage en regard des autres.Ajoutez la
VisibleWhen
propriété, qui spécifie les conditions qui doivent s’appliquer pour que l’élément apparaisse à l’utilisateur.public override CommandConfiguration CommandConfiguration => new("%InsertGuidCommand.DisplayName%") { Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu }, Icon = new(ImageMoniker.KnownValues.OfficeWebExtension, IconSettings.IconAndText), VisibleWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveEditorContentType, ".+"), };
Pour plus d’informations, consultez l’utilisation de contraintes d’activation basées sur des règles.
Créer la méthode d’exécution
Dans cette étape, vous implémentez la méthode de ExecuteCommandAsync
la commande, qui définit ce qui se passe lorsque l’utilisateur choisit l’élément de menu ou appuie sur l’élément dans la barre d’outils de votre commande.
Copiez le code suivant pour implémenter la méthode.
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
Requires.NotNull(context, nameof(context));
var newGuidString = Guid.NewGuid().ToString("N", CultureInfo.CurrentCulture);
using var textView = await context.GetActiveTextViewAsync(cancellationToken);
if (textView is null)
{
this.logger.TraceInformation("There was no active text view when command is executed.");
return;
}
await this.Extensibility.Editor().EditAsync(
batch =>
{
textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString);
},
cancellationToken);
}
La première ligne valide les arguments, puis nous créons un nouvel Guid
argument à utiliser ultérieurement.
Ensuite, nous créons un ITextViewSnapshot
(l’objet textView
ici) en appelant la méthode GetActiveTextViewAsync
asynchrone. Un jeton d’annulation est transmis pour conserver la possibilité d’annuler la requête asynchrone, mais cette partie n’est pas illustrée dans cet exemple. Si nous n’obtenons pas d’affichage de texte correctement, nous écrivons dans le journal et nous arrêtons sans rien faire d’autre.
Nous sommes maintenant prêts à appeler la méthode asynchrone qui envoie une demande de modification à l’éditeur de Visual Studio. La méthode souhaitée est EditAsync
. Il s’agit d’un membre de la EditorExtensibility
classe, qui permet l’interaction avec l’éditeur Visual Studio en cours d’exécution dans l’IDE. Le Command
type dont votre propre InsertGuidCommand
classe hérite, a un membre Extensibility
qui fournit l’accès à l’objet EditorExtensibility
, afin que nous puissions accéder à la EditorExtensibility
classe avec un appel à this.Extensibility.Editor()
.
La EditAsync
méthode prend un Action<IEditBatch>
paramètre. Ce paramètre est appelé editorSource
,
Appel à EditAsync
utiliser une expression lambda. Pour décomposer cela un peu, vous pouvez également écrire cet appel comme suit :
await this.Extensibility.Editor().EditAsync(
batch =>
{
var editor = textView.Document.AsEditable(batch);
// specify the desired changes here:
editor.Replace(textView.Selection.Extent, newGuidString);
},
cancellationToken);
Vous pouvez considérer cet appel comme spécifiant le code que vous souhaitez exécuter dans le processus de l’éditeur Visual Studio. L’expression lambda spécifie ce que vous souhaitez modifier dans l’éditeur. Il batch
s’agit d’un type IEditBatch
, ce qui implique que l’expression lambda définie ici apporte un petit ensemble de modifications qui doivent être effectuées en tant qu’unité, plutôt que d’être interrompues par d’autres modifications par l’utilisateur ou le service de langage. Si le code s’exécute trop longtemps, ce qui peut entraîner une absence de réponse, il est donc important de conserver les modifications dans cette expression lambda limitée et de comprendre tout ce qui pourrait entraîner des retards.
À l’aide de la AsEditable
méthode sur le document, vous obtenez un objet d’éditeur temporaire que vous pouvez utiliser pour spécifier les modifications souhaitées. Considérez tout dans l’expression lambda comme une demande d’exécution de Visual Studio plutôt que d’exécuter réellement, car comme décrit dans l’extensibilité de l’éditeur Use Visual Studio, il existe un protocole particulier pour gérer ces demandes de modification asynchrones à partir d’extensions, et il existe une possibilité que les modifications ne soient pas acceptées, par exemple si l’utilisateur apporte des modifications en même temps que la création d’un conflit.
Le EditAsync
modèle peut être utilisé pour modifier du texte en général en spécifiant vos modifications après le commentaire « spécifier les modifications souhaitées ici ».