Sublime Forum

When embedding a syntax, is it possible to redefine '^'?

#1

I have a custom syntax for a simple preprocessor. Lines that start with ‘#:’ are C++ code that I would like highlighted as C++. I’m currently using a syntax file with:

- match: '^#:'
  embed: Packages/C++/C++.sublime-syntax
  embed_scope: source.c++.embedded
  escape: \n

This works fine. The problem is that lines such as:

#:#define ABC

are not highlighted correctly because the syntax file for C++ uses ‘^\s*#’ to find preprocessor directives. Although my syntax consumes the ‘#:’, so the embedded scope starts in the correct place, the ‘^’ anchor will not match the beginning of the C++ line. Is there a way to set ‘^’ to mark the current position? Or is there a different way to solve this?

Thanks.

1 Like

#2

This is a kind of kludgy solution, but you could use YAML Macros to create a customized version of the C++ syntax that modifies the regexps, then embed that syntax.

0 Likes

#3

Yes, I could do it by modifying the C++ syntax, and thanks for the idea of using YAML macros, so I wouldn’t have to maintain multiple versions of it. I may have to use that.

It would be preferable if I could do this without rewriting the C++ syntax. I’m also concerned it could break the C++ syntax if I removed the ‘^’ anchors - I wouldn’t want it to “find” preprocessor directives in the middle of other lines, for instance.

I would think that this is a general problem for embedded syntaxes for languages that care about where in the line they are, so I’m hoping there’s a general solution.

0 Likes

#4

Instead of removing the ^, you could replace it with ^#:.

0 Likes

#5

I’ve been working on this, and although I can modify the C++ syntax to look for ^#: at the beginning of the line, that doesn’t solve the problem.

My modified C++ syntax can correctly highlight lines like

#:#define ABC

but it doesn’t work when the modified C++ is called from “embed”. I assume the reason is that my preprocessor (i.e,. the match code above) matches the #:, so in the above example, the C++ syntax sees “#define” at the beginning of its input, which doesn’t match ^#:#define. As far as I can tell, if the next un-matched symbol is not really at the beginning fo the line, then no pattern containing ^ is going to match it.

I realize that I could change my preprocessor rule to match something like ^(?=#:), so it doesn’t consume #:. Then the C++ syntax would need to consume the it, though, which it doesn’t know how to do. It would take major surgery on it (more than just sed or YAML Macros) to make it properly handle this sort of thing.

The more I look at it, the more convinced I become that the only way to handle a construct like this without rewriting the embedded syntax would be to force ^ to match someplace other than the beginning of the line. Is there anything I’m missing?

Thanks.

0 Likes