Расширение текстового редактора Visual Studio - PullRequest
36 голосов
/ 19 июля 2011

Я пытаюсь начать работу с расширениями Visual Studio (2010), и мне трудно найти нужные материалы. У меня есть SDK, но включенные образцы, кажется, такие вещи, как украшения, окна и значки.

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

Кто-нибудь знает, где я могу найти такие вещи?

Ответы [ 2 ]

57 голосов
/ 25 марта 2012

У меня был точно такой же вопрос, и теперь я несколько часов просматриваю Интернет, пока не смог понять и объяснить, как вам нужно начинать с таким расширением.

В моем следующем примере мы будемсоздайте маленькое и немое расширение, которое всегда будет добавлять «Hello» в начало файла кода, когда будет выполнено редактирование.Это очень простой способ, но он должен дать вам представление о том, как продолжить разработку.

Имейте в виду: вы должны полностью разобрать файлы кода - Visual Studio не дает вам никакой информации о том, где классы, методыили что там есть и что они содержат.Это самое большое препятствие, которое необходимо принять при работе с инструментом форматирования кода, и оно не будет рассмотрено в этом ответе. [*]

Для тех, кто пропустил этот ответ, убедитесь, что вы сначала загрузили и установили Visual Studio SDKили вы не найдете тип проекта, упомянутый в первом шаге.

Создание проекта

  1. Начните с создания нового проекта типа "Visual C #> Расширяемость> Проект VSIX "(отображается только в том случае, если в качестве целевой платформы выбран .NET Framework 4). Обратите внимание, что вам может потребоваться выбрать тип проекта «Редактор классификатора» вместо типа «Проект VSIX», чтобы он работал, s.комментарий ниже.

  2. После того, как проект будет создан, откроется файл «source.extension.vsixmanifest», который даст вам возможность указать название продукта, автора,версия, описание, значок и так далее.Я думаю, что этот шаг довольно понятен, вы можете закрыть вкладку сейчас и восстановить ее позже, открыв файл vsixmanifest.

Создание класса слушателя для получения уведомлений о текстеСоздание экземпляра редактора

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

  1. Добавьте новый класс в наш проект и назовите его TextViewCreationListener.Этот класс должен реализовывать интерфейс Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener.Вам нужно добавить ссылку на Microsoft.VisualStudio.Text.UI.Wpf в ваш проект.DLL-библиотека сборки находится в каталоге Visual Studio SDK в VisualStudioIntegration \ Common \ Assemblies \ v4.0 .

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

  3. Нам нужно сделать класс TextViewCreationListener видимым для Visual Studio, указав атрибут [Export(typeof(IWpfTextViewCreationListener))].Добавьте ссылку на System.ComponentModel.Composition в свой проект для атрибута Export.

  4. Кроме того, нам необходимо указать, с какими типами файлов кодФорматер должен быть привязан к текстовому редактору.Нам нравится форматировать только файлы кода, а не текстовые файлы, поэтому мы добавляем атрибут [ContentType("code")] в класс слушателя.Для этого вы должны добавить ссылку на Microsoft.VisualStudio.CoreUtility в ваш проект.

  5. Кроме того, мы хотим изменить только редактируемый код, а не цвета илиукрашения вокруг него (как видно из примеров проектов), поэтому мы добавляем атрибут [TextViewRole(PredefinedTextViewRoles.Editable)] в класс.Опять же, вам нужна новая ссылка, на этот раз Microsoft.VisualStudio.Text.UI .

  6. Пометить класс как внутренний запечатанный.По крайней мере, это моя рекомендация.Теперь ваш класс должен выглядеть примерно так:

    [ContentType("code")]
    [Export(typeof(IWpfTextViewCreationListener))]
    [TextViewRole(PredefinedTextViewRoles.Editable)]
    internal sealed class TextViewCreationListener : IWpfTextViewCreationListener
    {
        public void TextViewCreated(IWpfTextView textView)
        {
        }
    }
    

Создание класса для форматирования кода

Далее нам нужен класс, обрабатывающийлогика форматирования кода, методы сортировки и так далее.Опять же, в этом примере он будет просто добавлять «Hello» в начало файла всякий раз, когда будет выполнено редактирование.

  1. Добавить новый класс с именем Formatter в ваш проект.

  2. Добавить конструктор, который принимает один IWpfTextView аргумент. Помните, что мы хотели передать созданный экземпляр редактора этому классу форматирования в методе TextViewCreated нашего класса слушателя (просто добавьте new Formatter(textView); в метод там).

  3. Сохранить переданный экземпляр в переменной-члене. Это станет удобным при последующем форматировании кода (например, для получения позиции каретки). Также свяжите события Changed и PostChanged свойства TextBuffer экземпляра редактора:

    public Formatter(IWpfTextView view)
    {
        _view = view;
        _view.TextBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(TextBuffer_Changed);
        _view.TextBuffer.PostChanged += new EventHandler(TextBuffer_PostChanged);
    }
    
  4. Событие Changed вызывается каждый раз, когда выполняется редактирование (например, ввод символа, вставка кода или программные изменения). Поскольку он также реагирует на программные изменения, я использую bool, определяющий, изменяет ли наше расширение или пользователь / что-либо еще код в данный момент, и вызываю мой пользовательский метод FormatCode(), только если наше расширение еще не редактируется. В противном случае вы будете рекурсивно вызывать этот метод, что приведет к сбою Visual Studio:

    private void TextBuffer_Changed(object sender, TextContentChangedEventArgs e)
    {
        if (!_isChangingText)
        {
            _isChangingText = true;
            FormatCode(e);
        }
    }
    
  5. Мы должны сбросить эту переменную члена bool в обработчике событий PostChanged снова на false.

  6. Давайте передадим аргументы события Changed нашему пользовательскому методу FormatCode, потому что они содержат то, что изменилось между последним редактированием и сейчас. Эти правки хранятся в массиве e.Changes типа INormalizedTextChangeCollection (см. Ссылку в конце моего поста для получения дополнительной информации об этом типе). Мы перебираем все эти правки и вызываем наш пользовательский метод HandleChange с новым текстом, созданным этим редактором.

    private void FormatCode(TextContentChangedEventArgs e)
    {
        if (e.Changes != null)
        {
            for (int i = 0; i < e.Changes.Count; i++)
            {
                HandleChange(e.Changes[0].NewText);
            }
        }
    }
    
  7. В методе HandleChange мы могли бы на самом деле сканировать ключевые слова, чтобы обрабатывать их определенным образом (помните, что вы должны анализировать любой код на себе!) - но здесь мы просто тупо добавляем «Hello» к запуск файла для тестирования. Например. мы должны изменить TextBuffer нашего экземпляра редактора. Для этого нам нужно создать объект ITextEdit, с помощью которого мы можем манипулировать текстом и впоследствии применять его изменения. Код довольно понятен:

    private void HandleChange(string newText)
    {
        ITextEdit edit = _view.TextBuffer.CreateEdit();
        edit.Insert(0, "Hello");
        edit.Apply();
    }
    

При компиляции этой надстройки экспериментальный куст Visual Studio запускается только с загруженным нашим расширением. Создайте новый файл C # и начните вводить, чтобы увидеть результаты.

Я надеюсь, что это даст вам некоторые идеи, как продолжить эту тему. Я должен сам исследовать это сейчас.

Я настоятельно рекомендую документацию текстовой модели редактора в MSDN, чтобы получить подсказки о том, как вы можете сделать то и это. http://msdn.microsoft.com/en-us/library/dd885240.aspx#textmodel


Сноска

[*] Обратите внимание, что Visual Studio 2015 или новее поставляется с платформой компилятора Rosyln, которая действительно уже анализирует файлы C # и VB.NET для вас (и, возможно, других предустановленных языков тоже) и предоставляет их иерархическую синтаксическую структуру, но Я еще не эксперт в этой теме, чтобы дать ответ о том, как пользоваться этими новыми услугами. Основной прогресс запуска расширения редактора остается таким же, как описано в этом ответе в любом случае. Имейте в виду, что - если вы используете эти службы - вы станете зависимыми от Visual Studio 2015+, и расширение не будет работать в более ранних версиях.

7 голосов
/ 29 июля 2011

просто взгляните на сайт «Начало работы с расширениями редактора» на MSDN http://msdn.microsoft.com/en-us/library/dd885122.aspx

Торстен

...