Udostępnij za pośrednictwem


Punkty rozszerzenia usługi językowej i edytora

Edytor udostępnia punkty rozszerzeń, które można rozszerzyć jako części składników programu Managed Extensibility Framework (MEF), w tym większość funkcji usługi językowej. Są to główne kategorie punktów rozszerzenia:

  • Typy zawartości

  • Typy klasyfikacji i formaty klasyfikacji

  • Marginesy i paski przewijania

  • Tagi

  • Ozdoby

  • Procesory myszy

  • Programy obsługi porzucania

  • Opcje

  • IntelliSense

Rozszerzanie typów zawartości

Typy zawartości to definicje rodzajów tekstu obsługiwanego przez edytor, na przykład "text", "code" lub "CSharp". Można zdefiniować nowy typ zawartości, deklarując zmienną typu ContentTypeDefinition i nadając nowemu typowi zawartości unikatową nazwę. Aby zarejestrować typ zawartości w edytorze, wyeksportuj go razem z następującymi atrybutami:

  • NameAttribute to nazwa typu zawartości.

  • BaseDefinitionAttribute to nazwa typu zawartości, z którego pochodzi ten typ zawartości. Typ zawartości może dziedziczyć z wielu innych typów zawartości.

    ContentTypeDefinition Ponieważ klasa jest zapieczętowana, można ją wyeksportować bez parametru typu.

    W poniższym przykładzie przedstawiono atrybuty eksportu definicji typu zawartości.

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

Typy zawartości mogą być oparte na zerach lub większej większa liczba istniejących typów zawartości. Są to wbudowane typy:

  • Dowolny: podstawowy typ zawartości. Element nadrzędny wszystkich innych typów zawartości.

  • Tekst: podstawowy typ zawartości innej niż projekcja. Dziedziczy z "dowolnego".

  • Zwykły tekst: w przypadku tekstu innego niż kod. Dziedziczy z "tekstu".

  • Kod: dla kodu wszelkiego rodzaju. Dziedziczy z "tekstu".

  • Inert: wyklucza tekst z dowolnego rodzaju obsługi. Tekst tego typu zawartości nigdy nie będzie miał żadnego rozszerzenia.

  • Projekcja: dla zawartości buforów projekcji. Dziedziczy z "dowolnego".

  • IntelliSense: dla zawartości funkcji IntelliSense. Dziedziczy z "tekstu".

  • Sighelp: pomoc dotycząca podpisu. Dziedziczy z funkcji "intellisense".

  • Sighelp-doc: dokumentacja pomocy dotyczącej podpisu. Dziedziczy z funkcji "intellisense".

    Oto niektóre typy zawartości zdefiniowane przez program Visual Studio i niektóre języki hostowane w programie Visual Studio:

  • Podstawowy

  • C/C++

  • ConsoleOutput

  • CSharp

  • CSS

  • ENC

  • FindResults

  • F#

  • Kod HTML

  • JScript

  • XAML

  • Kod XML

    Aby odnaleźć listę dostępnych typów zawartości, zaimportuj IContentTypeRegistryServiceobiekt , który utrzymuje kolekcję typów zawartości dla edytora. Poniższy kod importuje tę usługę jako właściwość.

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

Aby skojarzyć typ zawartości z rozszerzeniem nazwy pliku, użyj polecenia FileExtensionToContentTypeDefinition.

Uwaga

W programie Visual Studio rozszerzenia nazw plików są rejestrowane przy użyciu ProvideLanguageExtensionAttribute pakietu usługi językowej. Typ FileExtensionToContentTypeDefinition zawartości MEF jest skojarzony z rozszerzeniem nazwy pliku, który został zarejestrowany w ten sposób.

Aby wyeksportować rozszerzenie nazwy pliku do definicji typu zawartości, należy uwzględnić następujące atrybuty:

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

Program IFileExtensionRegistryService zarządza skojarzeniami między rozszerzeniami nazw plików i typami zawartości.

Rozszerzanie typów klasyfikacji i formatów klasyfikacji

Można użyć typów klasyfikacji, aby zdefiniować rodzaje tekstu, dla których chcesz zapewnić inną obsługę (na przykład kolorowanie tekstu "słowo kluczowe" niebieski i tekst "komentarz" zielony). Zdefiniuj nowy typ klasyfikacji, deklarując zmienną typu ClassificationTypeDefinition i nadając jej unikatową nazwę.

Aby zarejestrować typ klasyfikacji w edytorze, wyeksportuj go razem z następującymi atrybutami:

  • NameAttribute: nazwa typu klasyfikacji.

  • BaseDefinitionAttribute: nazwa typu klasyfikacji, z którego ten typ klasyfikacji dziedziczy. Wszystkie typy klasyfikacji dziedziczą z "tekstu", a typ klasyfikacji może dziedziczyć z wielu innych typów klasyfikacji.

    ClassificationTypeDefinition Ponieważ klasa jest zapieczętowana, można ją wyeksportować bez parametru typu.

    W poniższym przykładzie przedstawiono atrybuty eksportu definicji typu klasyfikacji.

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

Zapewnia IStandardClassificationService dostęp do standardowych klasyfikacji. Wbudowane typy klasyfikacji obejmują następujące elementy:

  • "tekst"

  • "język naturalny" (pochodzi z "tekstu")

  • "język formalny" (pochodzi z "tekstu")

  • "string" (pochodzi z "literału")

  • "znak" (pochodzi z "literału")

  • "numeryczne" (pochodzi z "literału")

    Zestaw różnych typów błędów dziedziczy z ErrorTypeDefinition. Obejmują one następujące typy błędów:

  • "błąd składniowy"

  • "Błąd kompilatora"

  • "inny błąd"

  • "Ostrzeżenie"

    Aby odnaleźć listę dostępnych typów klasyfikacji, zaimportuj IClassificationTypeRegistryServiceelement , który utrzymuje kolekcję typów klasyfikacji dla edytora. Poniższy kod importuje tę usługę jako właściwość.

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

Możesz zdefiniować definicję formatu klasyfikacji dla nowego typu klasyfikacji. Utwórz klasę z ClassificationFormatDefinition klasy i wyeksportuj ją z typem EditorFormatDefinition, wraz z następującymi atrybutami:

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

Aby odnaleźć listę dostępnych formatów, zaimportuj IEditorFormatMapServiceobiekt , który przechowuje kolekcję formatów dla edytora. Poniższy kod importuje tę usługę jako właściwość.

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

Rozszerzanie marginesów i pasków przewijania

Marginesy i paski przewijania to główne elementy widoku edytora oprócz samego widoku tekstu. Oprócz standardowych marginesów wyświetlanych wokół widoku tekstu można podać dowolną liczbę marginesów.

Zaimplementuj IWpfTextViewMargin interfejs w celu zdefiniowania marginesu. Należy również zaimplementować interfejs, IWpfTextViewMarginProvider aby utworzyć margines.

Aby zarejestrować dostawcę marginesu w edytorze, należy wyeksportować dostawcę wraz z następującymi atrybutami:

  • NameAttribute: nazwa marginesu.

  • OrderAttribute: kolejność wyświetlania marginesu względem innych marginesów.

    Są to wbudowane marginesy:

    • "Wpf Horizontal Scrollbar"

    • "Wpf Pionowy pasek przewijania"

    • "Margines numeru wiersza Wpf"

      Marginesy poziome, które mają atrybut order, After="Wpf Horizontal Scrollbar" są wyświetlane poniżej wbudowanego marginesu, a marginesy poziome, które mają atrybut Before ="Wpf Horizontal Scrollbar" kolejności, są wyświetlane powyżej wbudowanego marginesu. Prawe pionowe marginesy, które mają atrybut order, After="Wpf Vertical Scrollbar" są wyświetlane po prawej stronie paska przewijania. Lewe marginesy pionowe, które mają atrybut order z lewej strony marginesu After="Wpf Line Number Margin" numeru wiersza (jeśli jest widoczny).

  • MarginContainerAttribute: rodzaj marginesu (lewy, prawy, górny lub dolny).

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), dla którego margines jest prawidłowy.

    W poniższym przykładzie przedstawiono atrybuty eksportu dla dostawcy marginesu dla marginesu, który pojawia się po prawej stronie marginesu numeru wiersza.

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

Rozszerzanie tagów

Tagi to sposób kojarzenia danych z różnymi rodzajami tekstu. W wielu przypadkach skojarzone dane są wyświetlane jako efekt wizualny, ale nie wszystkie tagi mają wizualną prezentację. Możesz zdefiniować własny rodzaj tagu, implementując ITag. Należy również zaimplementować ITagger<T> w celu zapewnienia tagów dla danego zestawu zakresów tekstu i elementu ITaggerProvider w celu zapewnienia sztyletu. Należy wyeksportować dostawcę tagger wraz z następującymi atrybutami:

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), dla którego tag jest prawidłowy.

  • TagTypeAttribute: rodzaj tagu.

    W poniższym przykładzie przedstawiono atrybuty eksportu dla dostawcy tagger.

<CodeContentPlaceHolder>8 Następujące rodzaje tagów są wbudowane:

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

Tagi i ZnacznikFormatDefinitions

Możesz rozszerzyć klasę, MarkerFormatDefinition aby zdefiniować wygląd tagu. Musisz wyeksportować klasę EditorFormatDefinition(jako )z następującymi atrybutami:

  • NameAttribute: nazwa używana do odwołowania się do tego formatu

  • UserVisibleAttribute: powoduje to wyświetlenie formatu w interfejsie użytkownika

    W konstruktorze zdefiniujesz nazwę wyświetlaną i wygląd tagu. BackgroundColor definiuje kolor wypełnienia i ForegroundColor definiuje kolor obramowania. Jest DisplayName to lokalizowalna nazwa definicji formatu.

    Poniżej przedstawiono przykład definicji formatu:

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

Aby zastosować tę definicję formatu do tagu, należy odwołać się do nazwy ustawionej w atrybucie name klasy (a nie nazwy wyświetlanej).

Uwaga

Aby zapoznać się z przykładem elementu , zobacz klasę MarkerFormatDefinitionHighlightWordFormatDefinition w przewodniku: wyróżnianie tekstu.

Rozszerzanie zdobień

Ozdoby definiują efekty wizualne, które można dodać do tekstu wyświetlanego w widoku tekstowym lub do samego widoku tekstu. Możesz zdefiniować własne ozdoby jako dowolny typ UIElement.

W klasie adornment należy zadeklarować element AdornmentLayerDefinition. Aby zarejestrować warstwę ozdobną, wyeksportuj ją razem z następującymi atrybutami:

  • NameAttribute: nazwa ozdoby.

  • OrderAttribute: kolejność ozdoby w odniesieniu do innych warstw ozdobnych. Klasa PredefinedAdornmentLayers definiuje cztery warstwy domyślne: Zaznaczenie, Konspektowanie, Daszek i Tekst.

    W poniższym przykładzie przedstawiono atrybuty eksportu w definicji warstwy ozdobności.

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

Należy utworzyć drugą klasę, która implementuje IWpfTextViewCreationListener i obsługuje jego TextViewCreated zdarzenie, tworząc wystąpienie elementu ozdobnego. Należy wyeksportować tę klasę razem z następującymi atrybutami:

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), dla którego ozdoba jest prawidłowa.

  • TextViewRoleAttribute: rodzaj widoku tekstowego, dla którego ta ozdoba jest prawidłowa. Klasa PredefinedTextViewRoles ma zestaw wstępnie zdefiniowanych ról widoku tekstu. Na przykład Document jest używany głównie w przypadku widoków tekstowych plików. Interactive Jest używany w przypadku widoków tekstowych, które użytkownik może edytować lub nawigować przy użyciu myszy i klawiatury. Przykłady widoków Interactive to widok tekstowy edytora i okno Dane wyjściowe .

    W poniższym przykładzie pokazano atrybuty eksportu u dostawcy adornmentu.

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

Negocjacja przestrzeni jest taka, która zajmuje miejsce na tym samym poziomie co tekst. Aby utworzyć ten rodzaj ozdoby, należy zdefiniować klasę tagów dziedziczoną z SpaceNegotiatingAdornmentTagklasy , która definiuje ilość miejsca zajmowanego przez ozdobę.

Podobnie jak we wszystkich ozdobach, należy wyeksportować definicję warstwy ozdobności.

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

Aby utworzyć wystąpienie ozdoby negocjowania przestrzeni, należy utworzyć klasę, która implementuje ITaggerProviderelement , oprócz klasy implementujące IWpfTextViewCreationListener (podobnie jak w przypadku innych rodzajów ozdobników).

Aby zarejestrować dostawcę tagger, należy wyeksportować go razem z następującymi atrybutami:

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), dla której ozdoba jest prawidłowa.

  • TextViewRoleAttribute: rodzaj widoku tekstowego, dla którego ten tag lub ozdoba jest prawidłowy. Klasa PredefinedTextViewRoles ma zestaw wstępnie zdefiniowanych ról widoku tekstu. Na przykład Document jest używany głównie w przypadku widoków tekstowych plików. Interactive Jest używany w przypadku widoków tekstowych, które użytkownik może edytować lub nawigować przy użyciu myszy i klawiatury. Przykłady widoków Interactive to widok tekstowy edytora i okno Dane wyjściowe .

  • TagTypeAttribute: rodzaj zdefiniowanego tagu lub ozdoby. Musisz dodać sekundę TagTypeAttribute dla elementu SpaceNegotiatingAdornmentTag.

    W poniższym przykładzie przedstawiono atrybuty eksportu u dostawcy tagger dla tagu ozdobnego negocjowania przestrzeni.

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

Rozszerzanie procesorów myszy

Możesz dodać specjalną obsługę danych wejściowych myszy. Utwórz klasę dziedziczą z MouseProcessorBase i przesłaniają zdarzenia myszy dla danych wejściowych, które mają być obsługiwane. Należy również zaimplementować IMouseProcessorProvider w drugiej klasie i wyeksportować go razem z elementem ContentTypeAttribute określającym rodzaj zawartości (na przykład "tekst" lub "kod"), dla której procedura obsługi myszy jest prawidłowa.

W poniższym przykładzie przedstawiono atrybuty eksportu u dostawcy procesora myszy.

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

Rozszerzanie procedur obsługi upuszczania

Zachowanie procedur obsługi upuszczania można dostosować dla określonego rodzaju tekstu, tworząc klasę implementającą i drugą klasę, która implementuje IDropHandlerIDropHandlerProvider tworzenie procedury obsługi upuszczania. Należy wyeksportować procedurę obsługi upuszczania wraz z następującymi atrybutami:

  • DropFormatAttribute: format tekstu, dla którego ta procedura obsługi upuszczania jest prawidłowa. Następujące formaty są obsługiwane w kolejności priorytetu od najwyższego do najniższego:

    1. Dowolny format niestandardowy

    2. FileDrop

    3. EnhancedMetafile

    4. Waveaudio

    5. Riff

    6. Dif

    7. Ustawienia regionalne

    8. Palety

    9. PenData

    10. Serializacji

    11. Link symboliczny

    12. Xaml

    13. Pakiet XamlPackage

    14. Tiff

    15. Bitmapy

    16. Dib

    17. MetaplikPicture

    18. CSV

    19. System.string

    20. HTML Format

    21. Unicodetext

    22. Tekst OEM

    23. Text

  • NameAttribute: nazwa procedury obsługi upuszczania.

  • OrderAttribute: kolejność procedury obsługi upuszczania przed lub po domyślnej procedurze obsługi upuszczania. Domyślna procedura obsługi upuszczania dla programu Visual Studio nosi nazwę "DefaultFileDropHandler".

    W poniższym przykładzie przedstawiono atrybuty eksportu u dostawcy programu obsługi upuszczania.

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

Rozszerzanie opcji edytora

Można zdefiniować opcje, które mają być prawidłowe tylko w określonym zakresie, na przykład w widoku tekstowym. Edytor udostępnia ten zestaw wstępnie zdefiniowanych opcji: opcje edytora, opcje widoku i opcje widoku Windows Presentation Foundation (WPF). Te opcje można znaleźć w systemach DefaultOptions, DefaultTextViewOptionsi DefaultWpfViewOptions.

Aby dodać nową opcję, utwórz klasę z jednej z tych klas definicji opcji:

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

Rozszerzanie funkcji IntelliSense

IntelliSense to ogólny termin dla grupy funkcji, które udostępniają informacje o tekście ustrukturyzowanym i uzupełnianiu instrukcji. Te funkcje obejmują uzupełnianie instrukcji, pomoc w podpisie, szybkie informacje i żarówki. Uzupełnianie instrukcji ułatwia użytkownikom poprawne wpisywanie słowa kluczowego języka lub nazwy elementu członkowskiego. Pomoc dotycząca podpisu wyświetla podpis lub podpisy metody, którą właśnie wpisał użytkownik. Szybkie informacje wyświetla pełny podpis dla nazwy typu lub elementu członkowskiego, gdy mysz będzie na nim spoczywać. Żarówka udostępnia dodatkowe akcje dla niektórych identyfikatorów w niektórych kontekstach, na przykład zmiana nazwy wszystkich wystąpień zmiennej po zmianie nazwy jednego wystąpienia.

Projekt funkcji IntelliSense jest bardzo taki sam we wszystkich przypadkach:

  • Broker funkcji IntelliSense jest odpowiedzialny za ogólny proces.

  • Sesja intelliSense reprezentuje sekwencję zdarzeń między wyzwalaniem prezentera a zatwierdzeniem lub anulowaniem zaznaczenia. Sesja jest zwykle wyzwalana przez gest użytkownika.

  • Kontroler IntelliSense jest odpowiedzialny za podjęcie decyzji o rozpoczęciu i zakończeniu sesji. Decyduje również o tym, kiedy należy zatwierdzać informacje i kiedy należy anulować sesję.

  • Źródło funkcji IntelliSense udostępnia zawartość i decyduje o najlepszym dopasowaniu.

  • Prezenter intelliSense jest odpowiedzialny za wyświetlanie zawartości.

    W większości przypadków zalecamy podanie co najmniej źródła i kontrolera. Możesz również podać prezenter, jeśli chcesz dostosować ekran.

Implementowanie źródła funkcji IntelliSense

Aby dostosować źródło, należy zaimplementować jeden (lub więcej) następujących interfejsów źródłowych:

Ważne

ISmartTagSource jest przestarzały na rzecz ISuggestedActionsSource.

Ponadto należy zaimplementować dostawcę tego samego rodzaju:

Ważne

ISmartTagSourceProvider jest przestarzały na rzecz ISuggestedActionsSourceProvider.

Należy wyeksportować dostawcę wraz z następującymi atrybutami:

  • NameAttribute: nazwa źródła.

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), do którego ma zastosowanie źródło.

  • OrderAttribute: kolejność wyświetlania źródła (w odniesieniu do innych źródeł).

  • W poniższym przykładzie przedstawiono atrybuty eksportu u dostawcy źródła uzupełniania.

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

Aby uzyskać więcej informacji na temat implementowania źródeł funkcji IntelliSense, zobacz następujące przewodniki:

Implementowanie kontrolera IntelliSense

Aby dostosować kontroler, należy zaimplementować IIntellisenseController interfejs. Ponadto należy zaimplementować dostawcę kontrolera wraz z następującymi atrybutami:

  • NameAttribute: nazwa kontrolera.

  • ContentTypeAttribute: rodzaj zawartości (na przykład "tekst" lub "kod"), do którego stosuje się kontroler.

  • OrderAttribute: kolejność wyświetlania kontrolera (w odniesieniu do innych kontrolerów).

    W poniższym przykładzie przedstawiono atrybuty eksportu u dostawcy kontrolera uzupełniania.

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

Aby uzyskać więcej informacji na temat używania kontrolerów Funkcji IntelliSense, zobacz następujące przewodniki: