Atom — это фантастический редактор, который поставляется по умолчанию со всем, что вам нужно для разработки проекта … за исключением, может быть, одной вещи — той детали, которую вы хотели бы видеть в Atom. Это может быть что угодно: сочетание клавиш, чтобы писать быстрее; важная особенность; или даже подсветку синтаксиса для языка, который вы используете, но он не поддерживается по умолчанию.
Хорошей новостью является то, что Atom готов принять множество пакетов. Вы можете расширить возможности по умолчанию с помощью этих пакетов, написанных сообществом. Но что, если вы не найдете пакет, который ищете?
Написание собственного пакета не так сложно, так почему бы и нет? В этом уроке мы увидим, как создать собственный пакет для Atom, на примере пакета с подсветкой синтаксиса.
Что мы будем строить
Недавно я хотел разработать несколько программ на языке Scilab . Так как это язык, используемый в математике, на самом деле это не тот тип языка, который мы находим в Atom по умолчанию, и не было пакета для его синтаксиса. Вот почему я решил написать свой собственный пакет: language-scilab .
Здесь мы напишем аналогичный пакет, для языка, который вы хотите. Сначала мы увидим, как инициализировать новый пакет с помощью действительного файла package.json
Затем мы напишем несколько правил, чтобы выделить наш язык. Наконец, мы увидим, как опубликовать наш пакет, чтобы любой пользователь Atom мог его использовать.
Инициализация нового пакета Atom
Atom использует папку конфигурации для хранения всех ваших личных параметров, а также установленных вами пакетов. Эта папка называется .atom
/home/user/.atom
Все устанавливаемые вами пакеты находятся в подпапках packages
Каждый пакет имеет свою собственную папку. Поэтому первым шагом для создания вашего пакета является создание вашей папки, названной в честь вашего пакета. В нашем примере я создаю папку language-mylanguage
На данный момент ваш пакет является недействительным. Для распознавания Atom ему нужен файл package.json
Этот файл содержит некоторую информацию, такую как имя вашего пакета или хранилище, где мы можем его найти. Ниже приведен файл package.json
language-mylanguage
{
"name": "language-mylanguage",
"version": "0.0.0",
"description": "Mylanguage language support in Atom",
"engines": {
"atom": "*"
},
"dependencies": {},
"repository": {
"type": "git",
"url": "https://github.com/JeremyHeleine/language-mylanguage.git"
},
"bugs": {
"url": "https://github.com/JeremyHeleine/language-mylanguage/issues"
},
"license": "MIT"
}
Мы находим несколько записей в этом файле. Во-первых, name
Вы можете (и должны) добавить описание вместе с записью description
Запись о version
major.minor.bug
Здесь мы указываем 0.0.0
Даже если вы знаете, что разрабатываете версию 1.0.0 или 0.1.0 или свой пакет, укажите 0.0.0
Мы увидим почему, когда мы опубликуем наш пакет.
Запись о engines
В том же духе мы находим запись dependencies
Он должен использоваться, если вы создаете плагин для другого пакета.
Затем мы находим запись в repository
Это URL, указывающий, где находится публичный репозиторий вашего пакета. Если вы хотите опубликовать свой пакет, вам нужна эта запись. Вы можете оставить его пустым, если вы не хотите создавать свой публичный репозиторий прямо сейчас, но подумайте о его заполнении перед публикацией.
Запись об bugs
Здесь мы используем страницу по умолчанию, которую предлагает GitHub для каждого репозитория. Наконец, имя лицензии может быть указано вместе с записью license
Другие записи могут быть заполнены, если они вам нужны. Они не обязательны. Все доступные записи можно найти в документации Atom .
Теперь, когда у вашего пакета есть действительный файл package.json
Однако сейчас это совершенно бесполезно, поэтому пришло время сделать его полезным, предоставив ему некоторые функции.
Обратите внимание, что Atom не будет загружать ваш пакет сейчас: он загружает все установленные пакеты при запуске. Однако вы можете заставить Atom перезагрузить пакеты с помощью View/Reload
Это полезно для просмотра изменений, которые вы только что сделали в вашем пакете.
Создание пакета с подсветкой синтаксиса
Чтобы добавить новые правила подсветки синтаксиса, вам нужно создать подпапку с именем grammars
В этой папке создайте новый файл CSON с именем языка, который вы хотите поддерживать (например, mylanguage.cson
Этот файл будет содержать все ваши правила подсветки синтаксиса.
Основная информация
Прежде чем определить синтаксис нашего языка, мы должны сказать Atom, как идентифицировать этот язык. Это может быть достигнуто благодаря трем записям в вашем недавно созданном файле CSON:
'scopeName': 'source.mylanguage'
'name': 'Mylanguage'
'fileTypes': ['ext1', 'ext2']
Запись scopeName
Обычно мы соблюдаем соглашение, использованное выше.
Запись name
Наконец, запись fileTypes
Каждый раз, когда вы открываете файл с помощью одного из этих расширений, Atom автоматически выбирает подсветку синтаксиса.
Синтаксические правила
Все правила для вашего языка должны быть объявлены в четвертой записи: patterns
Здесь мы увидим два типа правил, которые мы можем добавить. Однако любое добавленное правило должно быть объявлено между {}
patterns
'scopeName': 'source.mylanguage'
'name': 'Mylanguage'
'fileTypes': ['ext1', 'ext2']
'patterns': [
{
# First rule
},
{
# Second rule
},
# …
{
# Last rule
}
]
Соответствие элементу синтаксиса
Давайте построим наше первое правило с помощью match
Это правило будет определять любое число, например 4
7.2
.568
{
'match': '\\b(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))\\b'
'name': 'constant.numeric.mylanguage'
}
Запись о match
Затем, каждый раз, когда Atom видит текст, соответствующий этому регулярному выражению, он инкапсулирует его в элемент span
name
Вы можете добавить несколько имен классов, каждое из которых разделено точкой.
Вы должны заметить, что регулярное выражение содержит больше обратных косых черт, чем обычно. Фактически, мы можем использовать каждый специальный символ, такой как \b
Однако, поскольку ваше регулярное выражение — не что иное, как строка, если вы просто наберете \b
b
Нам нужна строка \b
Вот почему нам нужно избежать обратной косой черты. На практике это означает, что вам нужно удваивать каждый вводимый обратный слеш, и \b
\\b
Вы можете добавить любые имена классов, которые вы хотите в записи name
Однако есть некоторые соглашения, которым нужно следовать. Как правило, укажите тип элемента, который вы хотите выделить, и завершите его названием языка. Есть много разных типов, которые все используются разными редакторами. TextMate перечисляет их в своей документации по соглашениям об именах .
Если вы используете эти соглашения, другие разработчики могут лучше понять, что вы делаете. Но есть и другая причина, почему стоит соблюдать эти условности: темы.
В Atom это тема, которая решает, какой стиль будет отображаться для элемента, который вы хотите выделить. Эти темы стараются быть совместимыми с большим количеством языков, поэтому они используют эти соглашения.
Таким образом, в приведенном выше примере нам не нужно добавлять CSS для стилизации наших чисел. Поскольку мы используем соглашение, наша тема автоматически обнаруживает его. Лучше: так как это соглашение используется для каждого языка, числа на нашем языке будут отображаться так же, как числа отображаются на других языках.
Сопоставление нескольких элементов в одном правиле
name
Это здесь, чтобы выделить весь текст, подтверждающий регулярное выражение. Но что, если вы хотите выделить несколько элементов в одном правиле?
Давайте рассмотрим пример с объявлением функции, подобным следующему:
function nameOfTheFunction() {
}
Мы хотим выделить слово function
Если мы можем сопоставить ключевое слово function
Вот почему нам нужно выделить эти два элемента в одном правиле. Это может быть достигнуто с помощью следующего правила:
{
'match': '\\b(function)\\s+(\\w+)\\s*\\(.*\\)'
'captures':
'1':
'name': 'keyword.control.mylanguage'
'2':
'name': 'entity.name.function.mylanguage'
'name': 'meta.function.mylanguage'
}
Запись name
Однако теперь мы находим запись captures
Наше регулярное выражение содержит захват круглых скобок вокруг function
Как и на других языках, эти записи могут быть получены благодаря записи captures
1
function
2
Мы применяем правильные имена классов к ним с name
С помощью объявления функции выше мы получаем следующее в Atom:
<span class="meta function mylanguage">
<span class="keyword control mylanguage">function</span>
<span class="entity name function mylanguage">nameOfTheFunction</span>
…
</span>
Соответствие началу и концу правила
Иногда легче определить начало и конец элемента, чем сам элемент. Это верно для строк, например:
{
'begin': '\''
'end': '\''
'name': 'string.quoted.single.mylanguage'
}
С этим правилом Atom будет искать первую цитату, чтобы начать строку. Затем следующая найденная кавычка будет концом строки, как и ожидалось (поиск некорректен). Вы можете указать необходимые регулярные выражения в качестве разделителей begin
end
Как всегда, запись name
Например, с этим:
var best_site = 'SitePoint';
… вы получаете это:
var best_site = <span class="string quoted single mylanguage">'SitePoint'</span>;
Захват элементов также возможен. Выделение кавычек является, например, обычной задачей. Для этого вы можете использовать beginCaptures
endCaptures
Они работают точно так же, как и captures
Единственное отличие состоит в том, что с match
beginCaptures
begin
endCaptures
end
С той же строкой JavaScript, что и выше, вы получите следующее:
{
'begin': '\''
'beginCaptures':
'0':
'name': 'punctuation.definition.string.begin.mylanguage'
'end': '\''
'endCaptures':
'0':
'name': 'punctuation.definition.string.end.mylanguage'
'name': 'string.quoted.single.mylanguage'
}
Наконец, вы также можете захватывать элементы, расположенные между разделителями. Поскольку var best_site =
<span class="string quoted single mylanguage">
<span class="punctuation definition string begin mylanguage">'</span>
SitePoint
<span class="punctuation definition string end mylanguage">'</span>
</span>;match
captures
Эта новая запись представляет собой массив, в котором перечислены элементы, которые вы хотите выделить внутри текущего выделения. Это регулярное выражение для выполнения только между вашими разделителями. В приведенном ниже примере мы избегаем patterns
\'
Вы можете добавить столько шаблонов, сколько захотите. С помощью приведенного выше правила, если мы хотим выделить следующий код JavaScript:
{
'begin': '\''
'beginCaptures':
'0':
'name': 'punctuation.definition.string.begin.mylanguage'
'end': '\''
'endCaptures':
'0':
'name': 'punctuation.definition.string.end.mylanguage'
'name': 'string.quoted.single.mylanguage'
'patterns': [
{
'match': '\\''
'name': 'constant.character.escape.mylanguage'
}
]
}
… мы получим это:
var best_site = 'It\'s SitePoint';
Публикация пакета Atom
Так что теперь наш пакет отлично работает … для нас. Если вам нужен ваш пакет, есть вероятность, что другие разработчики также нуждаются в нем. В таком случае, почему бы не поделиться своей работой, чтобы каждый мог насладиться ею?
Самое первое, что нужно сделать перед публикацией пакета, это проверить, существует ли уже пакет с таким же именем, как у вас. Для этого вы можете искать это имя в самом Atom (в настройках, где вы можете устанавливать пакеты). Вы также можете проверить URL var best_site =
<span class="string quoted single mylanguage">
<span class="punctuation definition string begin mylanguage">'</span>
It<span class="constant character escape mylanguage">\'</span>s SitePoint
<span class="punctuation definition string end mylanguage">'</span>
</span>;
Для публикации вашего пакета вам понадобится общедоступный репозиторий, подобный тем, которые вы можете создать на GitHub. Изучите приведенные выше советы о том, как указать URL-адрес вашего хранилища в файле https://atom.io/packages/name-of-your-package
Теперь вы готовы опубликовать свой пакет. В терминале перейдите в папку вашего пакета и введите package.json
Вы также можете опубликовать мажорную или минорную версию, заменив apm publish minor
minor
major
Эта команда сделает несколько вещей. Если вы используете его впервые, он начнется с регистрации имени вашего пакета. Затем он извлечет номер текущей версии и увеличит его. Вот почему мы указали patch
0.0.0
apm-publish
0.1.0
Затем команда создает соответствующий тег Git и отправляет эти изменения. Для этого шага, ваши учетные данные будут необходимы.
Наконец, ваша посылка опубликована без необходимости иметь что-либо еще.
Вы можете minor
apm unpublish name-of-the-package
Будьте осторожны, если вы также хотите удалить свой репозиторий GitHub: вы должны отменить публикацию вашего пакета перед удалением вашего репозитория. Если вы сначала удалите свой репозиторий, вы не сможете отменить публикацию пакета.
Заключительные слова
Атом очень мощный редактор. С помощью пакетов вы можете улучшить его и добавить необходимые функции. Теперь вы знаете, как создавать свои и как их публиковать.
Поскольку Atom очень гибок, вы можете делать много разных вещей с пакетами. Это также означает, что мы не можем описать в одной статье, как написать пакет любого типа. Вот почему мы видели здесь только то, как создать пакет с подсветкой синтаксиса. Однако инициализация и публикация вашего пакета всегда будут выполняться одинаково.
Если у вас есть какие-либо вопросы или комментарии, пожалуйста, ответьте ниже. Вы создали свой пакет? Расскажите нам об этом!