Сегодня я хочу начать еще одну серию статей, в которой речь пойдет о расширениях для редактора текста в Visual Studio.
Вы спросите “при чем тут JSON”?
Дело в том, что мы будем разрабатывать не некие абстрактные “расширения редактора”, а дорабатывать именно имеющийся редактор для JSON. Да, многие из техник, которые мы будем рассматривать, можно применять для абсолютно любых языковых редакторов, поддерживаемых в Visual Studio, однако часть (например, расширения для механизма Code Insight – подсказок коду) будут полностью JSON-специфичными.
Для тех, кто был на нашем первом Open Tech Talk в EPAM Izhevsk сразу скажу, что эта серия будут как раз по материалам того моего доклада. Так что те, кто на нем был и всё помнят – могут дальше не читать 🙂
Ниже можно будет найти ссылки на последующие статьи:
- JSON on steroids #1. About VS Extensions
- JSON on steroids #2.1. Visual Studio Editor: Content Types
- JSON on steroids #2.2. Visual Studio Editor: ITextBuffer and related types
- JSON on steroids #2.3. Visual Studio Editor: Tags, classifiers and text formating. Part 1
- JSON on steroids #2.3.Visual Studio Editor: Tags, classifiers and text formating. Part 2.
- JSON on steroids #2.3.Visual Studio Editor: Tags, classifiers and text formating. Part 3.
- JSON on steroids #3. JSON parser
А начать я хочу с ответов на 2 вопроса:
- Почему все-таки JSON?
- Какие в принципе расширения можно добавить к редактору VS?
Почему JSON?
Думаю, мало кто будет спорить, с тем, что на сегодняшний день за JSON закрепились 2 основные ниши:
- формат для сериализации (причем, не обязательно в мире JS, хотя аббревиатура JSON = JavaScript Object Notation),
- язык для написания … да чего угодно, от простых конфигурационных файлов, до описания моделей вычислений
Нас, понятное дело будет интересовать второй пункт, т.е. JSON – как основа разных DSLs (Domain Specific Languages).
Вот несколько примеров из достаточно разных областей…
package.json (NPM)
{
"version": "1.0.0",
"name": "asp.net",
"private": true,
"devDependencies": {
"teschtnode": "1.0.0",
"typdom": "0.0.2" },
"repository": {
"url": "https://git.epam.com/EPM-IRD/epm-ird"
}
}
Azure Resource Manager (используется для описание деплоя сервисов в Azure). Здесь, правда не готовый файл, а только шаблон
{
"contentVersion": "",
"parameters": {
"<parameter-name>": {
"type": "<type-of-parameter-value>",
}
},
"variables": {
"<variable-name>": "<variable-value>",
"<variable-object-name>": {
"<variable-complex-type-value>"
}
},
"resources": [
],
"outputs": {
"<outputName>": {
"type": "<type-of-output-value>",
"value": "<output-value-expression>"
}
}
}
MS Teams manifest (описывает расширение для MS Teams – включая встроенные табы, подключаемых ботов и шаблоны для active message)
{
"manifestVersion": "1.1",
"version": "1.0.0",
"id": "0fa05b35-6950-4f4a-be04-e293f091ac50",
"packageName": "app_package",
"developer": {
"name": "Mihail Romanov",
"websiteUrl": "https://epam.com",
"privacyUrl": "https://epam.com",
"termsOfUseUrl": "https://epam.com"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "Some App",
"full": "Some best app"
},
"description": {
"short": "I don't know",
"full": "1111"
},
"accentColor": "#8A038A",
"configurableTabs": [
{
"configurationUrl": "https://info.epam.com",
"canUpdateConfiguration": true,
"scopes": [
"team"
]
}
]
}
Что же делает его таким популярным?
- Простота и лаконичность
- Поддержка во многих редакторах и IDE (под поддержкой имеется в виду: подсветка синтаксиса, Code Insight, проверка “на лету”, …)
- Возможность определить дополнительные ограничения элементов JSON (или, если угодно, описать структуру файла) – воспользовавшись схемой.
О схеме…
Собственно, именно наличие схемы, дает нам возможность дешево создать специализированный язык с поддержкой редактора.
Например, вот такой фрагмент описания
"scopes": {
"type": "array",
"maxItems": 2,
"items": {
"enum": [
"team",
"personal"
]
}
},
Позволяет добавить сразу несколько подсказок в редактор:
- Элемент scopes – является массивом, а значит его значение должно заключаться в квадратные скобки
- элементами массива могут быть только 2 значения: team и personal
Казалось бы чего желать еще?
Однако, даже если остановиться только на подсказках в редакторе кода, мы сразу увидим серьезное ограничение механизма схем – он использует только информацию внутри самой схемы, т.е. заданную статически, на момент написания схемы.
Вот самый простой пример: package.json содержит список зависимых пакетов. Понятно, что было бы здорово иметь возможность осуществлять поиск этих пактов прямо в редакторе (или выбирать из списка доступных на текущий момент).
Очевидно, что описать такое схемой – невозможно.
И вот тут мы подошли ко второму вопросу – а какие возможности расширения для редакторов предоставляет Visual Studio?
Возможности расширения редакторов
Сейчас мы говорим об extension points произвольного редактора – безотносительно языка. Но надо понимать, что для некоторых языков могут быть доступны дополнительные средства, упрощающие такую работу (например, удобный парсер языка, или упрощенное API для создания Code Insight), а у других – нет.
Классификация (Classification types) и раскраска текста (classification formats)
Самое первое и очевидное, что при ходит на ум при словах “поддержка языка XXX в редакторе” это расцветка синтаксиса.
В Visual Studio для этого используется механизм классификации – когда парсер разбивает весь текст на отдельные токены, он присваивает каждому токену некий класс:
После этого можно задать свои настройки шрифта (цвет, размер, фон, начертание) для каждого класса
IntelliSense
Следующим обычно называют механизмы IntelliSense (а также Code Insight/Code Completion/…), или подсказок/помощников по коду.
Однако Microsoft под термином IntelliSense понимает сразу несколько механизмов.
- Statement Completion – или варианты завершения ввода. Сюда входят подсказки по операторам и переменным, списки полей, методов и свойств, объектов а также более изощренные варианты (например умные подсказки для текстовых литералов, …)
- Signature Help – это подсказки по составу аргументов текущего набираемого метода
- Quick Info – подсказки по методам, полям, объектам, всплывающие при наведении на элемент
- Light bulbs – это “лампочки” всевозможных “рефакторингов на месте”
Поля редактора (Margins)
Этот механизм позволяет нам размещать на полях редактора свою информацию или даже элементы управления
Разметка текста (Tags) и “украшения” (Adornments)
Этот механизм позволяет выбрать произвольный фрагмент текста (никак не связанный с классами языка) и дополнить его некоей визуализацией.
Вот только несколько примеров…
- Выделение найденных фрагментов при поиске
- Сворачивание фрагментов текста
- Подчеркивание ошибок и предупрежденеий
- “Preview” цвета, для разных форм его описания
- Code Lens – информация, а также разные интерактивные элементы, например, запуск тестов, относящаяся к конкретному фрагменту кода (методу, классу, …)
События мыши (Mouse processors) и Drag-and-drop (Drop handlers)
Наконец, в некоторых специальных случаях могут потребоваться более “низкоуровневые” инструменты, такие как
- события мыши (например, при наведении мышью на тот или иной элемент текста)
- события Drag-and-Drop (например, при перетаскивании в окно с текстом файла, вставить в указанное место путь до него)
Итак…
Мы слегка прошлись по тому, что предоставляет Visual Studio в плане создания собственных редакторов или расширения существующих
Все примеры кода к данному циклу будут собираться тут https://github.com/MihailRomanov/TechTalks_JSON_on_steroids/tree/master/Sample
Ну а в следующей статье мы поговорим о разработке расширений в целом, и о том, что нам понадобиться для работы с редактором JSON.