Создание простого расширения Visual Studio 2010 для работы с текстом

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

После изрядного поиска в Google, чтения блогов, копания в MSDN и просмотра сообщений StackOverflow я думаю, что собрал достаточно информации, чтобы реализовать это, но я хотел бы получить отзывы о том, подхожу ли я к вещам прямо перед тем, как начать. взломать :)

Я бы хотел:

  1. Регистрация команд, к которым пользователи могут привязывать горячие клавиши через Инструменты->Параметры->Клавиатура.
  2. Измените текстовый буфер активного окна при вызове команд.
  3. Меня не интересуют меню или панели инструментов, но я знаю, как добавить их через файлы .vsct (есть ли варианты получше?)

Для # 1, кажется, мне нужно сделать полный VSPackage, файл .vsct и так далее - нет красивой и простой точки расширения MEF, с которой я мог бы справиться вместо этого? (Возможно, экспортировать IWpfTextViewCreationListener и возиться с ручной обработкой сочетаний клавиш - но это будет серьезный взлом).

Что касается № 2, я не знаю, как получить ITextBuffer для активного документа. Я мог бы пройти через DTE.ActiveDocument, но я не уверен, как получить из этого ITextBuffer. В качестве альтернативы я мог бы сделать что-то вроде...

var txtMgr = (IVsTextManager)ServiceProvider.GetService(typeof(SVsTextManager));
IVsTextView textViewCurrent;
txtMgr.GetActiveView(true, null, out textView);
IWpfTextView wpfViewCurrent = AdaptersFactory.GetWpfTextView(textView);
ITextBuffer textCurrent = wpfViewCurrent.TextBuffer;

...но это точно похоже на окольный путь?


person snemarch    schedule 03.11.2010    source источник


Ответы (2)


Для обоих из них взгляните на исходный код расширения Align Assignments. Это компонент пакета/MEF, который добавляет команду и обрабатывает ее в активном окне.

Ваш ответ на №1 правильный. Лучший способ выполнять команды — использовать файл .vsct, для которого требуется пакет. Однако все, что означает пакет, — это то, что ваш проект будет создавать dll со встроенными ресурсами (из файла .vsct) и файл .pkgdef, который добавляет ключи реестра в соответствии с атрибутами, которые вы указали в своем пакете. Это (надеюсь) не слишком много накладных расходов.

Для вашего второго вопроса есть более чистый способ. Взгляните на командный фильтр, который прослушивает команды в активном представление, вместо того, чтобы прослушивать их глобально, а затем находить активное представление. Он позволяет оболочке обрабатывать маршрутизацию команд и просто концентрируется на реализации.

person Noah Richards    schedule 04.11.2010
comment
Спасибо! Есть что-то в добавлении фильтра к каждому VsTextView, что меня немного раздражает, но решение является определенно лучше. Жаль, что все еще приходится иметь дело с уродливым наследием com/ole, но, по крайней мере, оно минимально и может быть абстрагировано :) - person snemarch; 04.11.2010

Не совсем уверен, что вы подразумеваете под «текстовым буфером», но если вы имеете в виду либо текущий открытый текстовый файл, либо текущий выбор, вот некоторый код, который у меня есть в пакете для доступа к ним:

EnvDTE.DTE app = (EnvDTE.DTE)GetService(typeof(SDTE)); 
if (app.ActiveDocument != null && app.ActiveDocument.Type == "Text")
{
   EnvDTE.TextDocument text = (EnvDTE.TextDocument)app.ActiveDocument.Object(String.Empty);
   if (!text.Selection.IsEmpty)
   {
      //work with text.Selection.Text
   }
}

Конечно, если вы делаете расширение для редактора, все будет по-другому.

person Kate Gregory    schedule 03.11.2010
comment
Я имею в виду получение ITextBuffer для текущего/активного документа — это новый способ взаимодействия со службами редактирования текста вместо более ограниченных методов DTE/Selection. - person snemarch; 03.11.2010