Действительно, вы правы в том, что в Sublime определение синтаксиса обычно относится к определенному типу файла на основе внешних критериев: расширение, которое имеет файл, первая строка файла (например, bash shebang) или пользователь, специально переопределяющийавтоматическое обнаружение.
Один синтаксис может позволить другому временно «взять под контроль» выделение синтаксиса, но это должно быть осознанное решение, реализованное автором определения базового синтаксиса.Система должна знать, когда ей следует ввести новый синтаксис, когда он должен вернуться к предыдущему и (что наиболее важно), какой синтаксис фактически использовать между ними.
Например, Sublime поставляется с JavaScriptсинтаксис, который применяется к .js
файлам сам по себе, но синтаксис HTML, который поставляется вместе с ним, также содержит правило, позволяющее выделять содержимое соответствующего тега <script>
как JavaScript, передавая управление этому синтаксису и возвращая его обратно.когда появляется включающий тег </script>
.
Таким образом, в вашем случае то, что вы хотите сделать, технически возможно, но, так сказать, не работает "из коробки";вам нужен HTML-синтаксис, который знает, как обрабатывать теги этого типа специально.Такой синтаксис может уже существовать в управлении пакетами.Это также модификация, которую вы можете сделать сами, если хотите.В оставшейся части этого ответа вы узнаете, как это сделать (и внизу есть ссылка на измененный файл).
Основная идея заключается в том, что мы собираемся создать override
файла синтаксиса HTML, который поставляется с Sublime.Как следует из названия, это означает, что файл, который мы создаем, всегда будет использоваться вместо файла, который поставляется с Sublime прозрачно.Однако обратите внимание, что даже если основной файл будет обновлен, ваш измененный файл все равно будет использоваться (и вы не получите прямого предупреждения).Одна из особенностей пакета OverrideAudit (отказ от ответственности: я автор) - сообщить вам, когда это произойдет, чтобы вы могли быть уверены, что не пропустите новые функции или исправления ошибок в базовом пакете.file.
В этих инструкциях также предполагается, что вы используете последнюю стабильную сборку Sublime, которая на данный момент составляет 3176.Новые сборки часто приносят с собой новые синтаксисы, поэтому, если вы используете более старую версию (или более новую версию, если вы из загадочного будущего), основные инструкции остаются прежними, но содержимое файла может отличаться.Как мы увидим, наши изменения основаны на копировании существующих функций.
1.Откройте синтаксис HTML для редактирования
Если он еще не установлен, установите пакет PackageResourceViewer , а затем используйте команду PackageResourceViewer: Open Resource
из палитры команд (обязательноСлучайно выберите вариант extract
) и выберите сначала пакет HTML
, а затем файл HTML.sublime-syntax
.Это открывает файл для редактирования;когда вы сохраняете файл, для вас автоматически создается переопределение.
За кулисами создается папка с именем HTML
в папке Packages
(используйте Preferences > Browse Packages...
, чтобы найти это) и храните копию файла ресурсов внутри.Удаление этого файла восстановит исходный синтаксис.
Вы можете вручную создать переопределение, используя встроенную команду View Package File
, чтобы открыть ресурс HTML/HTML.sublime-syntax
и сохранить его в соответствующем месте.Если вы сделаете это, вам нужно закрыть и снова открыть файл, потому что он будет открыт только для чтения.
2.Сообщите синтаксису, как распознать тег шейдера
В верхней части открытого файла синтаксиса находится набор variables
, который в синтаксисе является способом предоставления именованных регулярных выражений, чтобы упростить чтение следующих шагов,В списке переменных есть переменная с именем javascript_mime_type
, которая определяется следующим образом:
javascript_mime_type: |-
(?ix)(?:
# https://mimesniff.spec.whatwg.org/#javascript-mime-type
(?:application|text)/(?:x-)?(?:java|ecma)script
| text/javascript1\.[0-5]
| text/jscript
| text/livescript
)
Прямо под этим, мы создадим нашу собственную переменную, которая содержит регулярное выражение для соответствия внутренним элементам type
атрибут тега сценария.Примером этого является следующее:
shader_mime_type: |-
(?ix)(?:
x-shader/x-fragment
)
Это может быть, а может и не нуждаться в расширении (я не знаю, как этот тег используется для WebGL).Если существует более одного варианта возможного содержимого, его можно расширить, как в приведенном выше примере JavaScript, чтобы включить дополнительные элементы.
3.Включите контекст, который встраивает синтаксис GLSL
Далее в файле (в сборке 3176 это примерно в строке 315 или около того после внесения вышеуказанного изменения) находится контекст с именем script-javascript
, который содержит правила синтаксиса для знаниякак выделить содержимое тега <script>
на основе JavaScript, и оно выглядит так:
script-javascript:
- meta_content_scope: meta.tag.script.begin.html
- include: script-common
- match: '>'
scope: punctuation.definition.tag.end.html
set:
- include: script-close-tag
- match: (?=\S)
embed: scope:source.js
embed_scope: source.js.embedded.html
escape: (?i)(?=(?:-->\s*)?</script)
Первые несколько строк содержат логику для синтаксиса, выделяющую остальные атрибуты в <script>
, которыеследуйте атрибуту type
.Содержание set
- это магия здесь;они говорят, что если тело тега не пустое, содержимое должно быть подсвечено с помощью embed
с помощью синтаксиса Javascript, и что закрывающий тег </script>
- это то, что экранирует embed
и возвращается к обычному HTML.
Здесь мы создадим наш собственный раздел для зависания сценария glsl
:
script-glsl:
- meta_content_scope: meta.tag.script.begin.html
- include: script-common
- match: '>'
scope: punctuation.definition.tag.end.html
set:
- include: script-close-tag
- match: (?=\S)
embed: scope:source.glsl
embed_scope: source.glsl.embedded.html
escape: (?i)(?=(?:-->\s*)?</script)
Как мы видим, это почти идентично приведенному выше, но используется другая область (болееоб этом ниже).
4.Сообщите тегу script
о наших новых правилах
Мы заложили основу, чтобы теперь все связать.Ниже в файле (в 3176 это примерно строка 390 после вышеуказанных изменений) есть набор правил, озаглавленный script-type-decider
.В этом контексте есть пять правил совпадения, поэтому для краткости мы покажем здесь только первое.
script-type-decider:
- match: (?i)(?={{javascript_mime_type}}(?!{{unquoted_attribute_value}})|'{{javascript_mime_type}}'|"{{javascript_mime_type}}")
set:
- script-javascript
- tag-generic-attribute-meta
- tag-generic-attribute-value
В этом контексте перечислены правила, которые применяются внутри тега <script>
type
атрибут, чтобы увидеть, что должно происходить с содержимым этого конкретного тега.Специально указанное здесь правило использует переменную, описанную выше, чтобы определить, что это тег JavaScript, и использует правило, на которое мы только что посмотрели, для встраивания синтаксиса JavaScript.
Прямо под этим match
(порядок правил имеет значение)мы добавим нашу собственную match
, чтобы подражать этой, используя нашу собственную переменную и набор правил:
- match: (?i)(?={{shader_mime_type}}(?!{{unquoted_attribute_value}})|'{{shader_mime_type}}'|"{{shader_mime_type}}")
set:
- script-glsl
- tag-generic-attribute-meta
- tag-generic-attribute-value
5.Сделайте изменения активными
Со всеми нашими изменениями все, что вам нужно сделать, это save
файл, чтобы сделать их активными.После этого Sublime немедленно перекомпилирует измененный файл синтаксиса и запустит его в действие.Когда это будет сделано, консоль Sublime (View > Show Console
) сообщит generating syntax summary
.Если вы не видите никаких сообщений об ошибках, вы готовы к работе:
Полная версия файла с упомянутыми изменениями:доступно в этой сущности для целей сравнения и использовалось для создания вышеуказанного изображения.Суть изложена в базовом файле в качестве ревизии 1, а модификации - в версии 2, поэтому легко увидеть, какие именно изменения были внесены в файл.
Заключительные замечания
Стоит отметить, что данный пакет на самом деле предоставляет три различных синтаксиса (Cg
, HLSL
и GLSL
).Вышеуказанные модификации синтаксиса обрабатывают только встраивание синтаксиса GLSL
, которое, как я догадался, было тем, к чему вы стремились.
Следуя тем же инструкциям, что и выше, вы можете поменять используемый синтаксис или добавить правила и для остальных (при условии, что вы знаете, что type
должно идти в теге <script>
, чтобы различать их).Те же правила также будут применяться, если есть другой синтаксис, который предоставляет субъективно «лучший» опыт выделения.
Важной частью головоломки является scope
, который используется во встроенном синтаксисе.В приведенном выше примере мы использовали source.glsl
, что определено непосредственно в определении синтаксиса для этого типа файла в используемом вами пакете.
Другие области в этом пакете: source.cg
и source.hlsl
.Самый простой способ определить подходящую область - создать новый файл, использовать соответствующий элемент Set Syntax:
из командной палитры, чтобы установить синтаксис для пустого буфера, и использовать Tools > Developer > Show Scope Name
, чтобы получить всплывающее окно, которое сообщит вам.