Поддержка пользовательских расширений файлов в пользовательской языковой службе Visual Studio

Я работаю над пользовательской языковой службой Visual Studio, и у меня есть несколько вопросов относительно того, как расширения файлов связаны с конкретной языковой службой.

Исходные файлы для языка "Example Language" имеют два основных расширения файлов: .e1 и .e2. В моем расширении есть класс ExampleLanguagePackage, который расширяет Package.

  1. Когда вы используете команду «Открыть файл» и выбираете файл C# (например), кнопка «Открыть» имеет стрелку раскрывающегося списка, которая позволяет вам выбрать «Открыть с помощью...». Когда вы нажимаете эту кнопку, вам предлагаются варианты открытия файла в «Редакторе CSharp (по умолчанию)», «Редакторе CSharp с кодировкой» или в любом из нескольких других вариантов. Как я могу предоставить аналогичную функцию для своего языка, предлагая варианты «Пример языка (по умолчанию)» и «Пример языка с кодировкой»?

  2. Когда вы открываете Инструменты Параметры... Расширение файла текстового редактора, у вас есть возможность привязать (например) расширение .foo к «Microsoft Visual C#» или любой из нескольких других параметров. Как я могу расширить эту страницу, чтобы пользовательские расширения файлов могли быть связаны с «примером языка»?

  3. На что еще следует обратить внимание при регистрации этих предметов?


person Sam Harwell    schedule 07.03.2013    source источник


Ответы (1)


Большинство из этих проблем решается путем добавления пользовательской реализации IVsEditorFactory для вашего языка и с помощью комбинации регистрационных атрибутов для его регистрации. Фактическая реализация этого интерфейса выходит за рамки этого вопроса, но документация для самого интерфейса (и связанная с этой страницей) вместе с примером DjangoEditorFactory в реализации Python Tools for Visual Studio помог мне с начальной реализацией.

Для поддержки языка примеров я сделаю следующие предположения.

  • You've implemented an abstract class ExampleEditorFactory which provides the core implementation of IVsEditorFactory. The class should have a protected constructor with a bool argument to specify whether the factory should prompt the user for an encoding (similar to one of the constructors of the DjangoEditorFactory).
    • You have a class ExampleEditorFactoryWithoutEncoding which extends ExampleEditorFactory and constructs the base class specifying false for the promptForEncoding argument. This class should be marked with the [Guid] attribute.
    • У вас есть класс ExampleEditorFactoryWithEncoding, который расширяет ExampleEditorFactory и создает базовый класс, определяющий true в качестве аргумента promptForEncoding. Этот класс должен быть помечен атрибутом [Guid]. .
  • You have added the following entries to your VSPackage.resx resources file. The constants can be changed, but be aware that I have used the constant values 101 and 102 below.
    • 101 = Пример языка

    • 102 = Пример языка с кодировкой

Регистрация фабрик редактора

Первое, что нужно сделать, это зарегистрировать свои фабрики редакторов. Это делается в двух частях.

Сначала используйте ProvideEditorFactoryAttribute. Этот атрибут связывает идентификатор ресурса для отображаемого имени фабрики с самим типом фабрики.

[ProvideEditorFactory(typeof(ExampleEditorFactoryWithoutEncoding), 101)]
[ProvideEditorFactory(typeof(ExampleEditorFactoryWithEncoding), 102)]

Затем в Initialize метод ExampleLanguagePackage, добавьте вызовы RegisterEditorFactory< /a> после вызова base.Initialize().

protected override void Initialize()
{
    base.Initialize();

    RegisterEditorFactory(new ExampleEditorFactoryWithoutEncoding(this));
    RegisterEditorFactory(new ExampleEditorFactoryWithEncoding(this));
}

Свяжите логическое представление с фабриками редактора

Я не нашел всей необходимой информации о вариантах использования для ProvideEditorLogicalViewAttribute, но важно включить по крайней мере следующее. Убедитесь, что логические представления зарегистрированы в обеих созданных вами фабриках.

[ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithoutEncoding), VSConstants.LOGVIEWID.TextView_string)]
[ProvideEditorLogicalView(typeof(ExampleEditorFactoryWithEncoding), VSConstants.LOGVIEWID.TextView_string)]

Если этот шаг не выполнен, функция, при которой двойной щелчок в окне вывода может привести к строке кода, не будет работать должным образом. Например, предположим, что окно вывода содержит строку, подобную следующей.

c:\dev\file.e1(14,3): unexpected expression

Связывание логического представления TextView позволяет среде IDE использовать вашу фабрику, когда вы дважды щелкните эту строку вывода, чтобы перейти к строке 14, столбцу 3 файла c:\dev\file.e1. В противном случае для открытия новой копии вашего документа будет использоваться другая фабрика, и в новом окне, вероятно, будут отсутствовать многие функции.

Свяжите стандартные расширения файлов .e1 и .e2 с фабриками редактора.

Этот шаг обеспечивает поддержку Open With... для файлов .e1 и .e2, описанных в исходном вопросе 1. Этот шаг выполняется с помощью ProvideEditorExtensionAttribute.

Приоритет по умолчанию для основной фабрики — 50. Фабрика с явным кодированием должна иметь приоритет меньше этого, и 49 кажется хорошим выбором. Обратите внимание, что нет необходимости указывать именованный параметр NameResourceID, поскольку он уже был указан при использовании ProvideEditorFactoryAttribute выше (сгенерированные ключи реестра идентичны).

[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e1", 50)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".e2", 50)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e1", 49)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".e2", 49)]

Свяжите расширение .* с фабриками редактора

Этот шаг обеспечивает поддержку Open With... для всех остальных файлов и добавляет поддержку параметров расширения файла, описанных в исходном вопросе 2. На этом шаге также используется атрибут ProvideEditorExtensionAttribute, но используется гораздо более низкое значение приоритета, чтобы гарантировать, что редакторы по умолчанию для других типов файлов не переопределяются настройкой. Как и в предыдущем шаге, фабрика с явной кодировкой имеет более низкий приоритет.

[ProvideEditorExtension(typeof(ExampleEditorFactoryWithoutEncoding), ".*", 2)]
[ProvideEditorExtension(typeof(ExampleEditorFactoryWithEncoding), ".*", 1)]

Заключительные заметки

Этот ответ не охватывает несколько деталей.

person Sam Harwell    schedule 07.03.2013
comment
Этот ответ, вероятно, должен привлечь больше внимания, но, похоже, авторов плагинов MSVS не так много :).. - person FailedDev; 20.08.2013
comment
Не могли бы вы пролить свет на этот вопрос? stackoverflow.com/ вопросы/18400139/ - person FailedDev; 23.08.2013
comment
Это решение работает, но создает следующее предупреждение в файле журнала расширений PkgDef столкнулся с конфликтом данных в разделе «HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0_Config\Editors\{7a909145-7ac8-4d8f-8498-xxxxxxxxxxx}» для значения «Пакет '. Вероятно, это связано с тем, что [ProvideEditorFactory(.....)] дважды регистрирует редактор. Все еще исследует - person Sunil Purushothaman; 12.06.2015