Visual Studio Extensibility — настройки текстового редактора на пользовательском языке

Я пытаюсь разработать языковую службу в Visual Studio, и до сих пор мне удалось реализовать базовый Tagger для выделения и промежутков:

введите здесь описание изображения

Однако я хотел сделать еще один шаг и добавить свой собственный раздел в «Текстовый редактор», чтобы я мог поддерживать настройки вкладок и тому подобное для языка (показано ниже): введите здесь описание изображения

Мне трудно найти ресурсы для расширения Visual Studio в Интернете, так как вы можете многое сделать, но часто бывает трудно понять, с чего начать. Меня также интересуют индивидуальные услуги по проектам/элементам, но у меня аналогичные проблемы с поиском образца.

Возможно, я близок к этому (из-за пользовательских тегов), я просто не знаю, чем украсить экспортированные типы, или у меня много основной работы. Направление оценили.


person Allen Clark Copeland Jr    schedule 14.03.2015    source источник
comment
Удалось ли вам управлять настройками вкладки согласованным образом для вашего родного языка? Принятый ответ создает пользовательскую страницу параметров, но, очевидно, Visual Studio предоставляет какую-то стандартную страницу параметров для их настройки в согласованном стиле на всех языках (все мои предустановленные языки имеют одну и ту же страницу параметров, подобную той, которая показана в вашем снимок экрана).   -  person Michael Szvetits    schedule 12.06.2017


Ответы (3)


Я нашел этот блог post содержит множество примеров проектов расширения Visual Studio. Среди них есть один проект под названием Страница параметров — VS 2013. Я думаю, это то, что вы ищете:

Страница параметров

Для вашего конкретного случая вы должны настроить следующие атрибуты в классе (взятые из примера) OptionsPagePackage.cs. В частности, эти атрибуты:

Иметь «категорию» в качестве второго передаваемого параметра (соответствующего основной категории в меню «Инструменты»).

[ProvideOptionPageAttribute(typeof(OptionsPageGeneral),"Text Editor","General", 100, 101, true, new string[] { "Change sample general options (C#)" })] 
    [ProvideProfileAttribute(typeof(OptionsPageGeneral), "Text Editor", "General Options", 100, 101, true, DescriptionResourceID = 100)] 
    [ProvideOptionPageAttribute(typeof(OptionsPageCustom), "Text Editor", "Custom", 100, 102, true, new string[] { "Change sample custom options (C#)" })] 
    [InstalledProductRegistration("Text Editor", "My Options Page (C#) Sample", "1.0")] 
    [Guid(GuidStrings.GuidPackage)] 
    public class OptionsPagePackageCS : Package 
    { 
    .....
    }

DescriptionResourceID (100,101,102 и т. д.) определяется в файле xml VsPackage.resx и будет использоваться установщиком vsix для вставки меток в меню инструментов:

<data name="100" xml:space="preserve">
    <value>My Managed Options (C#)</value>
    <comment>Options category</comment>
  </data>
  <data name="101" xml:space="preserve">
    <value>My Options</value>
    <comment>General page</comment>
  </data>
  <data name="102" xml:space="preserve">
    <value>Custom</value>
    <comment>Custom page</comment>
  </data>

Это моя попытка:

введите здесь описание изображения

Просто будьте осторожны, так как использование существующей категории перезапишет существующую. Как вы можете видеть на картинке, для всех остальных языков вариантов нет.

РЕДАКТИРОВАТЬ:

Как указал Александр, чтобы избежать перезаписи существующей конфигурации (если кто-то хочет добавить свою категорию к существующей в меню «Инструменты»), необходимо добавить обратную косую черту к параметру категории в атрибутах, упомянутых выше. Например:

[ProvideOptionPageAttribute(typeof(OptionsPageGeneral),"Text Editor","General", 100, 101, true, new string[] { "Change sample general options (C#)" })]

Становится:

 [ProvideOptionPageAttribute(typeof(OptionsPageGeneral),"Text Editor\\MyOptionPage","General", 100, 101, true, new string[] { "Change sample general options (C#)" })]

В этом случае MyOptionPage будет дочерним элементом текстового редактора и не перезапишет существующую конфигурацию.

Надеюсь, поможет.

person codingadventures    schedule 22.03.2015
comment
Чтобы решить проблему перезаписи категории, я добавил обратную косую черту после «Текстового редактора» и поставил «OILexer», чтобы атрибуты стали такими: [ProvideOptionPageAttribute(typeof(VSOilexerOptions), Text Editor\\OILexer, General, 100, 101, true )] - person Allen Clark Copeland Jr; 22.03.2015
comment
Здорово! добавлю в ответ - person codingadventures; 22.03.2015
comment
Без проблем. Обратите внимание: это было спекулятивное предположение о том, что в дереве атрибутов не было реальной иерархической структуры. Эта «обратная косая черта», по-видимому, не работает более чем на одном уровне. Таким образом, дальнейшая обратная косая черта служит только для устранения неоднозначности элемента, который вы определяете, от других. - person Allen Clark Copeland Jr; 23.03.2015

Документы о создании пользовательских настроек и параметров находятся в разделе:

Настройки и параметры пользователя

По сути, ваше расширение должно также предоставлять пакет для предоставления страницы настраиваемых параметров. Привязка между пакетом и расположением страницы параметров при использовании Managed Package Framework (MPF) выполняется через ProvideOptionPageAttribute, который получает название категории, имя страницы и т. д. См. Создание страниц параметров с помощью классов Managed Package Framework

person Carlos Quintero    schedule 18.03.2015

Есть две основные вещи, которые необходимы для того, чтобы пользовательский язык делал то, что вы хотите:

1) Иметь пользовательскую страницу параметров в меню Инструменты/Параметры/Текстовый редактор/{CustomLanguage}, которая состоит из стандартных диалоговых окон «Общие», «Полосы прокрутки» и «Вкладки» для настроек.

2) Вы хотите, чтобы встроенный редактор кода автоматически использовал ваши пользовательские настройки при редактировании контента на вашем языке. {Пользовательский язык}.

У меня была куча расширений пакетов, которые я создал для QMBasic, который представляет собой многозначный язык для базы данных QM, похожей на Pick. У меня был intellisense с раскраской синтаксиса, сопоставлением фигурных скобок и поставщиками автоматического завершения, работающими как шарм. Я не мог понять, почему не было страниц опций для моего нового пользовательского «Типа контента», на который я ссылался снова и снова. Оказывается, документация и Visual Studio ссылаются на такие вещи, как Content Type и Language Service, и вы предполагаете, что они одинаковы, но это не так. Тип контента в основном используется частью MEF Visual Studio для предоставления точек расширения, которые используются при редактировании определенного типа «Типа контента» или языка в этом случае. Это прекрасно работает.

Visual Studio прекрасно справляется со всеми этими задачами без регистрации «Языковой службы», которая является реальной уловкой для создания настраиваемых страниц параметров И получения их значений для использования редактором. Чтобы получить настраиваемые страницы параметров, созданные для вашего языка, вам просто нужно создать Guid для языка, а затем зарегистрировать его в определении вашего пакета. Так.

[ProvideLanguageService(QMBasicEditor.GuidList.guidQMBasicLanguageServiceIdString, "QMBasic", languageResourceID: 204, RequestStockColors = true, ShowDropDownOptions = true, ShowSmartIndent = true, DefaultToInsertSpaces = true)]

Точно так же Visual Studio затем создаст для вас диалоговые страницы «Общие», «Полосы прокрутки» и «Вкладки» в разделе «Инструменты/Параметры/Текстовый редактор/QMBasic», а также сохранит для вас пользовательские настройки в реестре.

Однако вы обнаружите, что редактор НЕ будет использовать эти новые настройки автоматически. Visual Studio, кажется, проводит различие между Content Type и LanguageName, которое вы видите в определении ProvideLanguageService выше.

Я использую EditorFactory для создания окон редактирования кода для QMBasic, и они создают VSTextBuffers типа контента «QMBasic».

pTextBuffer  =_IVsEditorAdaptersFactoryService.CreateVsTextBufferAdapter(_IOleServiceProvider, _QMBasicContentType);

что я думал будет достаточно, но увы это не так. Интерфейс IVSTextBuffer предоставляет изящный маленький вспомогательный метод SetLanguageService, который вы должны использовать, который предоставляет эту магию. В моей фабрике редакторов это было так же просто, как

pTextBuffer.SetLanguageServiceID(GuidList.guidQMBasicLanguageServiceId);

и это все, что потребовалось. Встроенный редактор кода теперь использует пользовательские настройки на страницах параметров, как я и ожидал.

person jrstokka    schedule 01.01.2019