Delen via


Werken met tekst in de editor

Uw extensiecode kan worden geconfigureerd om te worden uitgevoerd als reactie op verschillende toegangspunten (situaties die optreden wanneer een gebruiker communiceert met Visual Studio). Editor-uitbreidbaarheid ondersteunt momenteel drie toegangspunten: listeners, de EditorExtensibility serviceobject en opdrachten.

Gebeurtenislisteners worden geactiveerd wanneer bepaalde acties plaatsvinden in een editorvenster, vertegenwoordigd in code door een TextView. Wanneer een gebruiker bijvoorbeeld iets in de editor typt, treedt er een TextViewChanged gebeurtenis op. Wanneer een editorvenster wordt geopend of gesloten, vinden TextViewOpened en TextViewClosed gebeurtenissen plaats.

Het editorserviceobject is een exemplaar van de EditorExtensibility-klasse, waarmee realtime editorfunctionaliteit beschikbaar wordt gesteld, zoals het uitvoeren van tekstbewerkingen.

Opdrachten worden gestart door de gebruiker door te klikken op een item, dat u kunt plaatsen in een menu, contextmenu of werkbalk.

Een listener voor tekstweergave toevoegen

Er zijn twee soorten listeners, ITextViewChangedListener en ITextViewOpenClosedListener. Samen kunnen deze listeners worden gebruikt om het openen, sluiten en wijzigen van teksteditors te observeren.

Vervolgens maakt u een nieuwe klasse, implementeert u het ExtensionPart basisklasse en ITextViewChangedListener, ITextViewOpenClosedListenerof beide en voegt u een VisualStudioContribution-kenmerk toe.

Implementeer vervolgens de eigenschap TextViewExtensionConfiguration, zoals vereist voor ITextViewChangedListener en ITextViewOpenClosedListener, waardoor de listener van toepassing is bij het bewerken van C#-bestanden:

public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
{
    AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") },
};

De beschikbare documenttypen voor andere programmeertalen en bestandstypen worden vermeld verderop in dit artikelen aangepaste bestandstypen kunnen ook worden gedefinieerd wanneer dat nodig is.

Ervan uitgaande dat u besluit beide listeners te implementeren, moet de voltooide klassedeclaratie er als volgt uitzien:

  [VisualStudioContribution]                
  public sealed class TextViewOperationListener :
      ExtensionPart, // This is the extension part base class containing infrastructure necessary to use VS services.
      ITextViewOpenClosedListener, // Indicates this part listens for text view lifetime events.
      ITextViewChangedListener // Indicates this part listens to text view changes.
  {
      public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
      {
          // Indicates this part should only light up in C# files.
          AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") },
      };
      ...

Aangezien zowel ITextViewOpenClosedListener als ITextViewChangedListener de eigenschap TextViewExtensionConfiguration declareren, is de configuratie van toepassing op beide listeners.

Wanneer u uw extensie uitvoert, ziet u het volgende:

Elk van deze methoden wordt doorgegeven aan een ITextViewSnapshot met de status van de tekstweergave en het tekstdocument op het moment dat de gebruiker de actie heeft aangeroepen en een CancellationToken dat IsCancellationRequested == true heeft wanneer de IDE een actie in behandeling wil annuleren.

Definiëren wanneer uw extensie relevant is

Uw extensie is doorgaans alleen relevant voor bepaalde ondersteunde documenttypen en -scenario's, en daarom is het belangrijk om de toepasbaarheid duidelijk te definiëren. U kunt AppliesTo-configuratie) op verschillende manieren gebruiken om de toepasbaarheid van een extensie duidelijk te definiëren. U kunt opgeven welke bestandstypen, zoals codetalen die de extensie ondersteunt, en/of de toepasselijkheid van een extensie verder verfijnen door te vergelijken met een patroon op basis van de bestandsnaam of het pad.

Programmeertalen opgeven met de configuration AppliesTo

De AppliesTo-configuratie geeft de programmeertaalscenario's aan waarin de extensie moet worden geactiveerd. Het is geschreven als AppliesTo = new[] { DocumentFilter.FromDocumentType("CSharp") }, waarbij het documenttype een bekende naam is van een taal die is ingebouwd in Visual Studio, of aangepast is gedefinieerd in een Visual Studio-extensie.

Sommige bekende documenttypen worden weergegeven in de volgende tabel:

DocumentType Beschrijving
"CSharp" C#
"C/C++" C, C++, headers en IDL
"TypeScript" TypeScript- en JavaScript-typetalen.
"HTML" HTML
"JSON" JSON
"tekst" Tekstbestanden, waaronder hiërarchische afstammelingen van 'code', die afstammen van 'tekst'.
"code" C, C++, C#, enzovoort.

DocumentTypes zijn hiërarchisch. C# en C++ komen dus beide af van 'code', dus als u 'code' declareren, wordt uw extensie geactiveerd voor alle codetalen, C#, C, C++, enzovoort.

Een nieuw documenttype definiëren

U kunt een nieuw documenttype definiëren, bijvoorbeeld ter ondersteuning van een aangepaste codetaal, door een statische eigenschap DocumentTypeConfiguration toe te voegen aan elke klasse in het extensieproject en de eigenschap te markeren met het kenmerk VisualStudioContribution.

DocumentTypeConfiguration kunt u een nieuw documenttype definiëren, opgeven dat het een of meer andere documenttypen over neemt en een of meer bestandsextensies opgeven die worden gebruikt om het bestandstype te identificeren:

using Microsoft.VisualStudio.Extensibility.Editor;

internal static class MyDocumentTypes
{
    [VisualStudioContribution]
    internal static DocumentTypeConfiguration MarkdownDocumentType => new("markdown")
    {
        FileExtensions = new[] { ".md", ".mdk", ".markdown" },
        BaseDocumentType = DocumentType.KnownValues.Text,
    };
}

Definities van documenttypen worden samengevoegd met inhoudstypedefinities die worden geleverd door verouderde Visual Studio-uitbreiding, waarmee u extra bestandsextensies kunt toewijzen aan bestaande documenttypen.

Documentkiezers

Naast DocumentFilter.FromDocumentTypekunt u DocumentFilter.FromGlobPattern de toepasselijkheid van de extensie verder beperken door deze alleen te activeren wanneer het bestandspad van het document overeenkomt met een glob-patroon (jokerteken):

[VisualStudioContribution]                
public sealed class TextViewOperationListener
    : ExtensionPart, ITextViewOpenClosedListener, ITextViewChangedListener
{
    public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
    {
        AppliesTo = new[]
        {
            DocumentFilter.FromDocumentType("CSharp"),
            DocumentFilter.FromGlobPattern("**/tests/*.cs"),
        },
    };
[VisualStudioContribution]                
public sealed class TextViewOperationListener
    : ExtensionPart, ITextViewOpenClosedListener, ITextViewChangedListener
{
    public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
    {
        AppliesTo = new[]
        {
            DocumentFilter.FromDocumentType(MyDocumentTypes.MarkdownDocumentType),
            DocumentFilter.FromGlobPattern("docs/*.md", relativePath: true),
        },
    };

De parameter pattern vertegenwoordigt een glob-patroon dat overeenkomt met het absolute pad van het document.

Glob-patronen kunnen de volgende syntaxis hebben:

  • * om nul of meer tekens in een padsegment te matchen
  • ? om overeen te komen met één teken in een padsegment
  • ** komt overeen met een willekeurig aantal padsegmenten, inclusief geen enkele
  • {} om voorwaarden te groeperen (bijvoorbeeld **​/*.{ts,js} overeenkomt met alle TypeScript- en JavaScript-bestanden)
  • [] om een bereik van tekens te declareren dat binnen een padsegment overeenkomt (bijvoorbeeld example.[0-9] met example.0, example.1, ...)
  • [!...] om een reeks tekens te negeren in een padsegment (bijvoorbeeld example.[!0-9] om overeen te komen met example.a, example.b, maar niet example.0)

Een backslash (\) is niet geldig binnen een glob patroon. Zorg ervoor dat u een backslash in een slash converteert bij het maken van een glob-patroon.

Functionaliteit van access-editor

Uw editoruitbreidingsklassen nemen over van ExtensionPart-. De klasse ExtensionPart maakt de eigenschap Extensibility beschikbaar. Met deze eigenschap kunt u een exemplaar van de EditorExtensibility-object aanvragen. U kunt dit object gebruiken om toegang te krijgen tot realtime editorfunctionaliteit, zoals het uitvoeren van bewerkingen.

EditorExtensibility editorService = this.Extensibility.Editor();

Toegang tot de bewerkingsstatus binnen een opdracht

ExecuteCommandAsync() in elke Command wordt een IClientContext doorgegeven die een momentopname van de status van de IDE bevat op het moment dat de opdracht werd aangeroepen. U kunt het actieve document openen via de ITextViewSnapshot-interface, die u van het EditorExtensibility object ontvangt door de asynchrone methode aan te roepen GetActiveTextViewAsync:

using ITextViewSnapshot textView = await this.Extensibility.Editor().GetActiveTextViewAsync(clientContext, cancellationToken);

Zodra u ITextViewSnapshothebt, hebt u toegang tot de editorstatus. ITextViewSnapshot is een onveranderbare weergave van de editorstatus op een bepaald moment, dus u moet de andere interfaces in het Editor-objectmodel gebruiken om wijzigingen aan te brengen.