У меня есть Файл возвышенного синтаксиса Smalltalk (YAML) для Sublime Text 3, и я хотел бы добавить поддержку выделения для встроенного кода C.
Код inline C
(который всегда начинается с ^%\{
и заканчивается на %\}$
) среди кода smalltalk.
Простой пример (немного C
, но нужен простой случай):
sigABRT
"return the signal number for SIGABRT - 0 if not supported by OS
(the numeric value is not the same across unix-systems)"
%{ /* NOCONTEXT */
#ifdef SIGABRT
RETURN ( __mkSmallInteger(SIGABRT) );
#else
RETURN ( __mkSmallInteger(0) );
#endif
%}
!
В Sublime text появилась новая функция embed
(даже с пример).
Я пытался сделать что-то вроде этого:
- match: '^%\{'
embed: scope:source.c
embed_scope: meta.environment.embedded.c.smalltalk source.c.embedded
escape: '%\}$'
Однако мне не удалось правильно включить его в свой текущий файл выделения.
Кто-нибудь знает, как правильно встроить один язык в другой?
@Olaf Ты прочитал вопрос? Речь идет о подсветке синтаксиса языка C, который встроен в Smalltalk, да в текстовый редактор Sublime. Как может выделение языка C не иметь отношения к C?
Потому что неважно, на каком это языке. С таким же успехом может быть Brainfuck, это вопрос о том, как настроить редактор для смешивания двух стилей выделения в одном исходном коде. Я сильно сомневаюсь, что вы собираетесь полностью написать свой собственный файл подсветки. Даже в этом случае остается спорным, актуален ли тег C.
У нас уже есть накопившиеся теги, которые нужно записать, пожалуйста, не добавляйте больше ненужных. Создавать собственный тег только для этого вопроса не имеет смысла. Меньше, так как вы не добавляли некоторую информацию о том, о чем тег и как его использовать. Если быть более конкретным: это не поможет, вы уже отметили smalltalk и возвышенное, каждый, кто знает достаточно, чтобы, возможно, помочь, поймет, что вы имеете в виду.
@Olaf Во-первых - я добавил информацию о теге Smalltalk / X, но он должен быть одобрен некоторыми людьми, имеющими достаточно репутацию для этого. Вы должны проверить, прежде чем писать "..вы не добавляли какую-то информацию, что за тег ...". Тег smalltak-x
будет использоваться в моих будущих вопросах, поскольку он имеет некоторые довольно специфические особенности среди сред Smalltalk; ваше удаление не имеет смысла. Во-вторых, это может быть Brainfuck, но это не C, поэтому тег не имеет значения (я бы отметил его Brainfuck). С другой стороны, вы правы в том, что это можно рассматривать как руководство для кого-то со схожими потребностями.
@Olaf Из любопытства, если не имеет значения, на каком языке вы оставили тег smalltalk? (Чтобы понять ваш алгоритм). Надеюсь, мне не придется переписывать информацию о smalltalk-x
.
@ Олаф Хорошо. Последний пункт. Код - это Smalltalk и Inline C, который уникален в мире Smalltalk. Я не знаю другой реализации Smalltalk, в которой вы могли бы видеть / работать с кодом C непосредственно из среды. Спасибо, что поделились своим мнением. Хорошего дня / ночи.
Этот вопрос немного сложен, потому что вы предоставили образец определения синтаксиса и образец некоторого исходного кода Smalltalk, но предоставленный код не выделен предоставленным синтаксисом, потому что он не структурирован должным образом.
Для наших целей предположим, что предоставленный вами образец Smalltalk является следующим. Это может быть, а может и нет (я уже давно не работал со Smalltalk), но он подчеркивает ваш синтаксис, поэтому давайте назовем это достаточно хорошим для целей тестирования.
Object subclass: Test [
sigABRT
"return the signal number for SIGABRT - 0 if not supported by OS
(the numeric value is not the same across unix-systems)"
%{ /* NOCONTEXT */
#ifdef SIGABRT
RETURN ( __mkSmallInteger(SIGABRT) );
#else
RETURN ( __mkSmallInteger(0) );
#endif
%}
!
].
Соответствие синтаксиса, которое вы указали выше, является правильным для использования, поэтому я предполагаю, что ваша проблема в том, где вы поместили его в синтаксис.
Итак, предположим, что есть несколько мест, где мы могли бы захотеть сопоставить один из этих блоков C в определении синтаксиса; в этом случае мы можем захотеть создать новый context
в синтаксисе, который содержит совпадение, чтобы мы могли include
там, где это необходимо:
c-block:
- match: '%\{'
embed: scope:source.c
embed_scope: meta.environment.embedded.c.smalltalk source.c.embedded
escape: '%\}$'
Это тот же отрывок, который вы предоставили выше, но помещенный в контекст. Итак, допустим, что первое место, где может появиться такой блок, находится в теле блока. У вас есть контекст block-body
в вашем синтаксисе, поэтому мы прикрепляем include
к его концу, чтобы включить этот новый контекст:
block-body:
- include: pragma
- include: selector
- include: literal
- include: block
- include: comment
- include: c-block
Однако это не дает желаемого результата; выделение неверно:
Очевидно, что выделение идет неправильно, начиная по крайней мере с начала комментария C, возможно, раньше. Если вы используете Tools > Developer > Show Scope Name
, когда курсор находится на комментарии, вы можете видеть, что назначенная область видимости - source.smalltalk entity.name.function
, что означает, что синтаксис обрабатывает начало комментария C как имя метода.
Также похоже, что конструкция %{
не выделена должным образом, и проверка показывает, что область действия символа %
- source.smalltalk keyword.other
.
Таким образом, на самом деле проблема в настоящее время заключается в том, что с приведенными выше определениями вместо того, чтобы рассматривать %{
как начало блока C, он рассматривается как ключевое слово, и если это ключевое слово, то правила сопоставления блока C вообще не запускаются. .
Если вы посмотрите на свой синтаксис, контекст main
выглядит так:
main:
- match: '([a-zA-Z][a-zA-Z0-9]*)\s*(subclass:)\s*([a-zA-Z][a-zA-Z0-9]*)\s*\['
captures:
1: entity.other.inherited-class
2: keyword.other
3: entity.name.type
push:
- match: '\]'
pop: true
- include: pragma
- match: '(([a-zA-Z][a-zA-Z0-9]*:)|[+\-/\\*~<>=@%|&?!.,:;^]+)\s*([a-zA-Z][a-zA-Z0-9]*)'
captures:
1: entity.name.function
3: variable.other
- match: "([a-zA-Z][a-zA-Z0-9]*)"
scope: entity.name.function
- include: block
- include: comment
- include: block-body
Эти правила говорят, что когда мы видим строку, которая начинается с чего-то вроде BaseClass subclass: SubClass [
, мы входим в анонимный контекст (через push
) для обработки содержимого тела класса (или блока, или чего-то еще).
Анонимный контекст содержит правило, которое выскакивает, когда он видит закрывающий символ ]
, два разных совпадения для поиска имени функции, затем include
в контекстах для block
, comment
и block-body
соответственно.
Когда вы используете include
, Sublime берет все правила match
из этого контекста и вставляет их копию в том месте, где вы делаете вставку, как если бы вы только что вручную ввели их туда.
Вдобавок, когда в context
есть несколько правил, которые потенциально могут совпадать, первое правило match
в контексте является тем, которое применяется (т.е. оно «выигрывает» в счете).
Область действия keyword.other
применяется в правилах из контекста pragma
, а также из контекста selector
, и контекст selector
может соответствовать одному символу %
в качестве ключевого слова.
Таким образом, проблема здесь в том, что, поскольку include c-block
появляется после selector
в списке включения для контекста block-body
, контекст selector
находит и сопоставляет символ %
до того, как правило для блока C.
Тогда решением было бы сместить расположение include c-block
до этого элемента, чтобы убедиться, что он совпадает первым:
block-body:
- include: c-block
- include: pragma
- include: selector
- include: literal
- include: block
- include: comment
После этого блок выделяется больше, чем мы ожидали:
Вы правы насчет того, что «... предоставленный код не выделяется предоставленным синтаксисом, потому что он не структурирован должным образом ...» Ну, это было частью моей проблемы. Я также пометил это с помощью "Smalltalk-x" (Олаф (теперь называемый: "Отточить для этого сайта" не согласился и удалил его), что является уникальным в этом вопросе. Он смешивает код Smalltalk с C (который затем генерирует смешанный код Ваше объяснение безупречно и отвечает на мой вопрос. Вы даже заставили меня задуматься о том, чтобы исправить мой неисправный файл syntax
.
Я улучшу тестовый файл и определение.
Я воссоздал файл выделения, и он работает правильно. Не могли бы вы помочь мне с моим новым вопросом: superuser.com/questions/1345947/…? Мне пришлось разместить его на суперпользователе, так как он не включает никакого программирования.
Мне удалось обойти аналогичную проблему с помощью Regex lookahead и lookbehind.
- match: ' (?=\{")'
embed: scope:source.json
escape: '(?<=\})$'
Прекратите добавлять несвязанные теги. это явно не о языке Си, а о том, как настроить редактор.