Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Python
Code

Как создать плагин

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Jenyia (you can also view the original English article)

Sublime Text 2 - это настраиваемый текстовый редактор, который все больше привлекает внимание кодеров, ищущих мощный, быстрый и современный инструмент. Сегодня мы собираемся воссоздать мой популярный плагин Sublime, который отправляет CSS через API Nettuts + Prefixr для упрощенного кросс-браузерного CSS.

Когда закончите, у вас будет четкое представление о том, как написан плагин Sublime Prefixr, и быть готовым начать писать свои собственные плагины для редактора!


Предисловие: терминология и справочный материал

Модель расширения для Sublime Text 2 довольно полнофункциональна.

Модель расширения для Sublime Text 2 довольно полнофункциональна. Есть способы изменить подсветку синтаксиса, фактический хром редактора и все меню. Кроме того, можно создавать новые системы сборки, автозавершения, определения языков, фрагменты, макросы, привязки клавиш, привязки и плагины мыши. Все эти различные типы модификаций реализуются через файлы, которые организованы в пакеты.

Пакет - это папка, которая хранится в вашем каталоге Packages. Вы можете получить доступ к своему каталогу пакетов, нажав на пункт меню Preferences > Browse Packages .... Также возможно объединить пакет в один файл, создав zip-файл и изменив расширение на .sublime-package.  В этом уроке мы обсудим несколько дополнительных вопросов.

Sublime поставляется в комплекте с множеством различных пакетов. Большинство пакетов в комплекте имеют специфику языка. Они содержат определения языков, автодоставки и системы сборки. В дополнение к языковым пакетам есть еще два пакета: Default и User. Пакет
Default (по умолчанию) содержит все стандартные привязки клавиш, определения меню, настройки файлов и целую кучу плагинов, написанных на Python. Пакет User отличается тем, что он всегда загружен последним. Это позволяет пользователям переопределять значения по умолчанию, настраивая файлы в своем User пакете.

Во время написания плагина ссылка Sublime Text 2 API будет иметь важное значение.

Во время написания плагина ссылка Sublime Text 2 API будет иметь важное значение. Кроме того, пакет Default служит хорошей ссылкой для выяснения того, как делать вещи и что возможно. Большая часть функциональности редактора отображается через команды. Любая операция, отличная от ввода символов, выполняется с помощью команд. Просмотрев вкладку Preferences> Key Bindings - Defaultmenu, вы можете найти сокровищницу встроенных функций.

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


Шаг 1 - Запуск плагина

Sublime поставляется с функциональностью, которая генерирует каркас кода Python, необходимый для написания простого плагина. Выберите пункт меню Tools > New Plugin, и новый буфер будет открыт с помощью этого шаблона.

Здесь вы можете увидеть, что два модуля Sublime Python импортируются для использования API и создается новый класс команд.  Прежде чем редактировать это и начать создавать свой собственный плагин, давайте сохраним файл и запустим встроенные функции.

Когда мы сохраним файл, мы создадим новый пакет для его сохранения. Нажмите ctrl+s (Windows / Linux) или cmd+s (OS X), чтобы сохранить файл. Диалоговое окно сохранения откроется для пакета User. Не сохраняйте файл там, но вместо этого найдите папку и создайте новую папку с именем Prefixr.

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

Теперь, когда плагин сохранен, давайте попробуем его. Откройте консоль Sublime, нажав ctrl + `. Это консоль Python, которая имеет доступ к API. Введите следующий Python, чтобы проверить новый плагин:

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


Шаг 2 - Типы команд и присвоение имен

Для плагинов Sublime предоставляет три разных типа команд.

  •  Текстовые команды обеспечивают доступ к содержимому выбранного файла/буфера через объект View
  • Команды окна предоставляют ссылки на текущее окно через объект Window
  • Команды приложения не имеют ссылки на какое-либо конкретное окно или файл/буфер и используются реже

Поскольку мы будем манипулировать содержимым файла/буфера CSS с помощью этого плагина, мы собираемся использовать класс sublime_plugin.TextCommand в качестве основы для нашей пользовательской команды Prefixr. Это приводит нас к теме названия классов команд.

В каркасе плагина, предоставленном Sublime, вы заметите класс:

Когда мы хотели запустить команду, мы выполнили следующий код в консоли

Sublime будет принимать любой класс, который расширяет один из классов sublime_plugin
(TextCommand, WindowCommand или ApplicationCommand), удалите Command суффикса, а затем преобразуйте значение CamelCaseinto в underscore_notation  для имени команды.

Таким образом, для создания команды с именем prefixr, класс должен быть PrefixrCommand.


Шаг 3 - Выбор текста   

Одной из наиболее полезных функций Sublime является возможность множественного выбора.

Теперь, когда мы правильно включили наш плагин, мы можем начать процесс присвоения CSS из текущего буфера и отправки его в API Prefixr. Одной из наиболее полезных функций Sublime является возможность множественного выбора. Когда мы присваиваем выделенный текст, нам нужно написать наш плагин в ручку не только для первого выбора, но и для всех.

Поскольку мы пишем текстовую команду, у нас есть доступ к текущему представлению через self.view. Метод sel() объекта View возвращает итерируемый RegionSet текущего выбора. Начнем с сканирования этих фигурных скобок. Если фигурных скобок нет, мы можем развернуть выделение на окружающие фигурные скобки, чтобы обеспечить префикс целого блока. Независимо от того, был ли наш выбор включенными фигурными фигурными скобками, также будет полезно узнать, можем ли мы настроить прописные и форматирование на результат, который мы получаем от  Prefixr API.

Этот код заменяет содержимое метода каркаса run().

Если мы не нашли фигурных скобок, мы прокручиваем каждый выбор и корректируем выбор ближайшего закрытия фигурных скобок. Затем мы используем встроенную команду expand_selection с аргументом to в brackets, чтобы убедиться, что у вас есть полное содержимое каждого выбранного блока CSS.

Если вы хотите проверить вашу работу до сих пор, сравните источник с файлом Prefixr-1.py в zip-файле исходного кода.


Шаг 4 - Работа потоков

Чтобы предотвратить плохое соединение от прерывания другой работы, нам нужно убедиться, что вызовы API Prefixr происходят в фоновом режиме.

На этом этапе выбор был расширен, чтобы получить полное содержимое каждого блока CSS. Теперь нам нужно отправить их в Prefixr API. Это простой HTTP-запрос, который мы будем использовать для модулей urllib и urllib2. Тем не менее, прежде чем мы начнем снимать веб-запросы, нам нужно подумать о том, как потенциально отстающий веб-запрос может повлиять на производительность редактора. Если по какой-либо причине пользователь работает с высокой задержкой или медленным подключением, запросы к Prefixr API могут легко занять пару секунд или более.

Чтобы предотвратить плохое соединение от прерывания другой работы, нам нужно убедиться, что вызовы Prefixr API происходят в фоновом режиме. Если вы ничего не знаете о потоковой передаче, очень простое объяснение заключается в том, что потоки - это способ для программы планировать несколько наборов кода для запуска, казалось бы, в одно и то же время. Это важно в нашем случае, потому что он позволяет коду, который отправляет данные и ожидает ответа от Prefixr API, препятствует замораживанию остальной части пользовательского интерфейса Sublime.


Шаг 5 - Создание потоков

Мы будем использовать Python threading module для создания потоков. Чтобы использовать модуль потоковой передачи, мы создаем новый класс, который расширяет threading.Thread, называемый PrefixrApiCall. Классы, которые расширяют threading.Thread включают метод run(), который содержит весь код для выполнения в потоке.

Здесь мы используем метод __init __ () потока, чтобы установить все значения, которые понадобятся во время веб-запроса. Метод run() содержит код для настройки и выполнения HTTP-запроса для Prefixr API. Поскольку потоки работают одновременно с другим кодом, невозможно напрямую вернуть значения. Вместо этого мы устанавливаем self.result на результат вызова.

Поскольку мы только начали использовать еще несколько модулей в нашем плагине, мы должны добавить их в операторы импорта в верхней части скрипта.

Теперь, когда у нас есть потоковый класс для выполнения HTTP-вызовов, нам нужно создать поток для каждого выбора. Для этого мы возвращаемся к методу run() нашего класса PrefixrCommand и используем следующий цикл:

Мы отслеживаем каждый поток, который мы создаем, а затем вызываем метод start() для запуска каждого из них.

Если вы хотите проверить вашу работу до сих пор, сравните источник с файлом Prefixr-2.py в zip-файле исходного кода.


Шаг 6 - Подготовка к результатам

Теперь, когда мы начали выполнять запросы Prefixr API, перед обработкой ответов нам нужно настроить несколько последних деталей.

Во-первых, мы очищаем все выборки, потому что раньше мы их модифицировали. Позже мы вернем их в разумное состояние.

Кроме того, мы запускаем новый объект Edit. Эта группа операций для отмены и повтора. Мы указываем, что мы создаем группу для команды prefixr.

В качестве последнего шага мы вызываем метод, который будем писать далее, который будет обрабатывать результат запросов API.


Шаг 7 - Обработка потоков

На этом этапе наши потоки работают или, возможно, даже завершены. Затем нам нужно реализовать метод handle_threads(), на который мы только что ссылались. Этот метод будет проходить через список потоков и искать потоки, которые больше не работают.

Если поток все еще работает, добавим его в список потоков, чтобы проверить его позже. Если результат был неудачным, мы игнорируем его, однако для хороших результатов мы вызываем новый метод replace(), который мы будем писать в ближайшее время.

Если есть какие-то потоки, которые все еще работают, нам нужно проверить  их снова в ближайшее время. Кроме того, это приятное улучшение пользовательского интерфейса, чтобы обеспечить индикатор активности, чтобы показать, что наш плагин все еще работает.

В первом разделе кода используется простое целочисленное значение, хранящееся в переменной i,  для перемещения = назад и вперед между двумя скобками. Последняя часть является самой важной. Это говорит Sublime снова запустить метод handle_threads() с новыми значениями за 100 миллисекунд. Это похоже на функцию setTimeout() в JavaScript.

Ключевое слово lambda - это функция Python, которая позволяет нам создать новую неназванную или анонимную функцию

Метод sublime.set_timeout() требует функции или метода и количества миллисекунд, пока он не будет выполнен. Без lambda мы могли бы сказать, что мы хотели запустить handle_threads(), но мы не смогли бы указать параметры.

Если все потоки завершены, нам не нужно устанавливать другой тайм-аут, но вместо этого мы завершаем нашу группу отмены и обновляем пользовательский интерфейс, чтобы пользователь знал, что все сделано.

Если вы хотите проверить вашу работу до сих пор, сравните источник с файлом Prefixr-3.py в zip-файле исходного кода.


Шаг 8 - Выполнение замены

При обработке наших потоков нам просто нужно написать код, который заменяет исходный CSS результатом из  Prefixr API. Как мы упоминали ранее, мы собираемся написать метод под названием replace().

Этот метод принимает ряд параметров, включая объект Edit для отмены, поток, который захватил результат из API Prefixr, если исходный выбор включал фигурные скобки и, наконец, смещение выбора.

Смещение необходимо при работе с несколькими вариантами выбора. Когда мы заменим блок CSS префиксом CSS, длина этого блока будет увеличиваться. Смещение гарантирует, что мы заменим правильный контент для последующих выборов, так как текстовые позиции сдвигаются при каждой замене.

Следующим шагом будет подготовка результата из Prefixr API, который нужно удалить в качестве замены CSS. Это включает в себя преобразование окончаний строк и отступов в соответствии с текущим документом и исходным выбором.

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

Если вы хотите проверить свою работу до сих пор, сравните источник с файлом Prefixr-4.py в zip-файле исходного кода.


Шаг 9 - Манипуляция пробелами

Мы использовали два пользовательских метода во время процесса замены, чтобы подготовить новый CSS для документа. Эти методы принимают результат Prefixr и изменяют его в соответствии с текущим документом.

normalize_line_endings() берет строку и гарантирует соответствие строк окончанию текущего файла. Мы используем класс Settings из Sublime API для получения правильных окончаний строк.

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

В противном случае мы начнем с определения уровня отступа исходного CSS. Это делается путем поиска пробелов в начале выбора. Это делается путем поиска пробелов в начале выбора.

Затем мы обрезаем пробел из префикса CSS и используем текущие настройки просмотра, чтобы отделить CSS до исходного уровня с помощью вкладок или пробелов в зависимости от текущих настроек редактора.

Мы заканчиваем метод, используя исходное начальное и конечное пустое пространство, чтобы гарантировать, что новый префикс CSS подходит именно к оригиналу.

С помощью метода fix_whitespace() мы использовали (re)модуль регулярного выражения Python, поэтому нам нужно добавить его в список импорта в верхней части скрипта.

И с этим мы завершили процесс написания команды prefixr. Следующий шаг - сделать команду легкой для запуска, предоставив комбинацию клавиш и запись в меню.


Шаг 10 - Привязки клавиш

Большинство настроек и модификаций, которые могут быть сделаны для Sublime, выполняются через файлы JSON, и это верно для привязки клавиш. Привязка клавиш обычно зависит от ОС, а это значит, что для вашего плагина необходимо создать три файла привязки ключей. Файлы должны быть названы Deafult (Windows).sublime-keymap, Default (Linux).sublime-keymap и Default (OSX).sublime-keymap.

Файлы .sublime-keymap содержат массив JSON, который содержит объекты JSON для указания привязок клавиш. Объекты JSON должны содержатьkeys и command ключ и могут также содержать ключ args, если команда требует аргументов. Самое сложное в выборе привязки ключей - это то, что привязка ключей еще не используется. Это можно сделать, перейдя в меню Preferences > Key Bindings – Default и поиск ключевого слова, который вы хотите использовать. Как только вы найдете подходящую неиспользуемую привязку, добавьте ее в .sublime-keymap файл.

Обычно привязки клавиш Linux и Windows одинаковы. Ключ cmd в OS X указан строкой super в .sublime-keymap файлах. При портировании привязки ключей к операционным системам обычно используется ключ ctrl на Windows и Linux для super на OS X. Однако это может быть не самым естественным движением руки, поэтому, если возможно, попробуйте и проверьте ваши комбинации клавиш на реальной клавиатуре.


Шаг 11 - Записи в меню

Одна из более классных вещей в расширении Sublime заключается в том, что можно добавлять элементы в структуру меню, создавая .sublime-menu файлы. Файлы меню должны быть названы конкретными именами, чтобы указать, на какое меню они влияют:

  • Main.sublime-menu управляет основным программным меню
  • Side Bar.sublime-menu управляет щелчком правой кнопки мыши по файлу или папке на боковой панели
  • Context.sublime-menu управляет щелчком правой кнопки мыши по редактируемому файлу

Существует целый ряд других файлов меню, которые влияют на различные другие меню во всем интерфейсе. Просмотр пакетов Deafult - это самый простой способ узнать обо всех этих проблемах.

Для Prefixr мы хотим добавить пункт меню в меню Edit и некоторые записи в меню Preferences для настроек. Следующий пример - структура JSON для записи меню Edit. Я опустил записи в меню Preferences, так как они довольно многословны, вложенные на несколько уровней.

Один кусок, на который нужно обратить внимание, - это id ключи. Указав id существующей записи меню, можно добавить запись без переопределения существующей структуры. Если вы откроете файл Main.sublime-menu из пакета Default и просмотрите его, вы можете определить, в какой id хотите добавить вашу запись.

На данный момент ваш пакет Prefixr должен выглядеть почти идентично официальной версии GitHub.


Шаг 12 - Распределение пакета

Теперь, когда вы нашли время, чтобы написать полезный плагин Sublime, настало время ему попасть в руки других пользователей.

Sublime поддерживает распространение zip-файла каталога пакетов в качестве простого способа совместного использования пакетов. Просто закройте папку вашего пакета и измените расширение на .sublime-package. Теперь другие пользователи могут поместить это в свой каталог установленных пакетов и перезапустить Sublime для установки пакета.

Наряду с легкой доступностью для большого количества пользователей, наличие пакета через пакет управления пакетами позволяет пользователям автоматически обновляться до последних обновлений.

Хотя это, безусловно, может работать, есть также менеджер пакетов для Sublime, называемый Package Control, который поддерживает основной список пакетов и автоматическое обновление. Чтобы ваш пакет был добавлен к каналу по умолчанию, просто запустите его на GitHub или BitBucket, а затем разветвите файл канала (на GitHub или BitBucket), добавьте репозиторий и отправьте запрос на перенос. После принятия запроса на перенос ваш пакет будет доступен тысячам пользователей, использующих Sublime. Наряду с легкой доступностью для большого количества пользователей, наличие пакета через пакет управления пакетами позволяет пользователям автоматически обновляться до последних обновлений.

Если вы не хотите размещать на GitHub или BitBucket, существует система custom/JONON channel/repository, которую можно использовать для размещения в любом месте, при этом все же предоставляя пакет всем пользователям. Он также предоставляет расширенные функции, такие как указание доступности пакетов ОС. Дополнительную информацию см. На странице PackageControl.


Идите напишите несколько плагинов!

Теперь, когда мы рассмотрели шаги, чтобы написать плагин Sublime, пришло время для вас погрузиться! Сообщество плагинов Sublime создает и публикует новые функции почти каждый день. С каждым выпуском Sublime становится все более мощным и универсальным. Sublime Text Forum - отличное место, где можно получить помощь и поговорить с другими о том, что вы создаете.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.