Пишем свой первый плагин для Brackets
Brackets поставляется с небольшим числом плагинов «из коробки». По этой причине, первое что новые пользователи обычно делают, это установка дополнительных расширений. Но через какое-то время, вы вероятно, словите себя на мысли «если бы только в Brackets была функция…». К счастью, Brackets это редактор с открытым исходным кодом. Он сам по себе является веб-приложением: он построен на любимых нами технологиях (HTML, CSS, JS) и если вы веб-разработчик, то можете помочь его развитию, написав расширение. И это гораздо проще, чем вы могли бы себе представить.
Hello World
Строго говоря, расширение это не более чем папка, содержащая JS-файл с именем main.js, который выполняется при запуске Brackets. Найти папку с расширениями можно при выборе пункта меню «Помощь — Показать директорию расширений».
Откройте папку с расширениями и внутри /user создайте новую папку «myFirstExtension». Внутри этой папки создайте файл main.js. Для быстрого старта попробуем вставить простой HelloWorld-код:
define(function (require, exports, module) {
console.log('Hello myFirstExtension!');
});
Перезапустите Brackets через меню «Отладка — Перезагрузить» и вызовите инструменты разработчика (F12 или «Отладка — Показать инструменты разработчика») чтобы увидеть результат работы своего расширения.
JavaScript-модули в Brackets работают через обертку над CommonJS. Понимание CommonJS выходит за рамки данного руководства, но все что нам нужно знать, это то, что весь код в теле анонимной функции внутри define () выполнится при запуске приложения.
Hello alert
Скорее всего вы хотели бы сделать расширение, которое выполняло бы некоторых код не во время загрузки Brackets, а при выборе пункта меню пользователем. Подобное поведение реализуется с помощью менеджера команд. Как и практически все в Brackets, сам диспетчер команд — это модуль. Чтобы получить доступ к модулю, нужно просто вызвать brackets.getModule ().
define(function (require, exports, module) {
var CommandManager = brackets.getModule('command/CommandManager');
// Функция, выполняемая при нажатии на пункт меню
function handleHelloWorld() {
window.alert('Hello, world!');
}
// Во-первых, зарегистрируем команду, которая свяжет ID и функцию handleHelloWorld
var COMMAND_ID = 'helloworld.sayhello'; // package-style для избежания коллизий
var COMMAND_NAME = 'Hello World';
CommandManager.register(COMMAND_NAME, COMMAND_ID, handleHelloWorld);
// Во-вторых, создадим пункт меню и привяжем его к команде
var Menus = brackets.getModule('command/Menus');
var fileMenu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
fileMenu.addMenuItem(COMMAND_ID);
});
Hello document
Теперь попробуем сделать что-то условно полезное. В Brackets есть замечательная функция Extract, которая позволяет нарезать картинки, получать CSS-свойства и копировать текст прямо из PSD-файла. Однако текст передается в виде HTML-сущностей, что не всегда удобно.
1052; 1086; 1080; 1082; 1085; 1080; 1075; 1080;
Попробуем написать расширение, которое будет конвертировать эти символы в обычный текст. Декодировать будем с помощью JS-функции.
В Brackets, открытые файлы представлены в качестве экземпляров класса Document. Для получения ссылки на текущий документ (файл, открытый пользователем для редактирования), мы должны использовать модуль EditorManager.
function handleDecodeHtml() {
var editor = EditorManager.getFocusedEditor(); // текущий документ
var selectedText = editor.getSelectedText(); // получаем выделенный текст
var newText = decodeHtmlEntity(selectedText); // конвертируем
var selection = editor.getSelection();
editor.document.replaceRange(newText, selection.start, selection.end); // заменяем
}
ReplaceRange добавляет, заменяет или удаляет текст. Если указан диапазон, то текст в этом диапазоне будет заменены на новый. Если третий аргумент не указан, то новый текст будет вставлен без замены выделенного.
На этом все. Осталось «прописаться» в меню «Правка», в контекстное меню и добавить горячие клавиши.
define(function (require, exports, module) {
var CommandManager = brackets.getModule('command/CommandManager');
var Menus = brackets.getModule('command/Menus');
var Menu = Menus.getMenu(Menus.AppMenuBar.EDIT_MENU); // меню "Правка"
var ContextMenu = Menus.getContextMenu(Menus.ContextMenuIds.EDITOR_MENU);
var KeyManager = brackets.getModule('command/KeyBindingManager');
// ...
var COMMAND_ID = 'decodehtmlentity.convert';
CommandManager.register('Decode HTML Entity', COMMAND_ID, handleDecodeHtml);
Menu.addMenuItem(COMMAND_ID);
KeyManager.addBinding(COMMAND_ID, 'Ctrl-Alt-D'); // Ctrl автоматически заменяется на CMD для Mac
ContextMenu.addMenuItem(COMMAND_ID);
});
Hello publishing
Чтобы опубликовать приложение, необходимо добавить package.json в папку с main.js. Формат package довольно простойи будет знаком тем, у кого есть опыт работы с Node.js и npm.
{
"name": "brackets.decode-html-entity",
"title": "Decode HTML Entity",
"description": "This extension uses to decode any HTML-encoded string.",
"version": "0.1.0",
"engines": {
"brackets": ">=1.7.0"
},
"license": "MIT",
"i18n": ["en", "ru"],
"package-i18n": {
"ru": {
"description": "Это расширение используется для декодирования HTML-сущностей."
}
}
}
Заархивируйте папку с расширением (на гитхабе есть кнопка «Download ZIP»), авторизуйтесь на сайте brackets-registry и опубликуйте свое расширение путем загрузки zip-файла в реестр.
» Исходный код плагина доступен на гитбахе.
Комментарии (2)
6 сентября 2016 в 11:35 (комментарий был изменён)
0↑
↓
Только хотел написать о сомнительной актуальности Brackets, пошёл проверять — оказалось, туда три дня назад крупное обновление смерджили и теперь там Node.js 6.
Четыре дня назад они на Node.js 0.10.24 и npm 1.2.11 сидели =).
6 сентября 2016 в 11:41
0↑
↓
JavaScript-модули в Brackets работают через обертку над CommonJS.
define(function (require, exports, module) { console.log('Hello myFirstExtension!'); });
Вроде бы это RequireJS (жив, курилка) в полный рост. Хотя эта форма используется для того, чтобы внутри анонимной функции писать совместимый с CommonJS (
require('some/module')
,exports.somModule = 42
) код, да, но это не CJS-модули.