Подтвердить что ты не робот

Расширение текстового редактора Visual Studio

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

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

Кто-нибудь знает, где я могу найти этот материал?

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Добавьте в свой проект новый класс Formatter.

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

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

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

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

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

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

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

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

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

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


Сноска

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