Sublime Forum

Ligatures and string literals

#1

Is it possible to make ligatures only apply to code and not to text inside of strings? Usually I stay out of the ligature thing, but I started playing with Cascadia Code font which has ligature support for coding. So looked through some VHDL code and rapidly turned it off (the language uses <= in two different contexts, assignment and less-than-or-equal and the ligature assumes the latter). I looked at Python and this was a bit nicer but then I noticed it was ligatureizing (probably not a word) text inside of string literals where there’s no language context for it.

So, is there support for ligatures only in code, and eliminating ligatures in string literals? Effectively scopable ligature support?

0 Likes

#2

As far as I know this isn’t possible in a general, user-configurable way (the official docs here don’t mention it either); ligatures are either on or off.

That said, scope does play a part here; ligatures are only considered when all of the characters that make them up are part of the same token. So for example if the syntax groups -> as a single token, it can be a ligature, but if each character is scoped differently, it can’t. This is why the easiest way to debug ligature issues is to try them in a plain text file where everything is scoped the same.

So in theory you can do something like this by making modifications to the syntax definition. For example, if you use Tools > Developer > New Syntax... from the menu, save the resulting syntax as-is, then apply it to a buffer, you end up with something like this (here I’m using Iosevka SS09 as the font):

image

You can then apply an extra rule like this into the double_quoted_string context:

    - match: '>'
      scope: breaking.scope

Once the change is made, the > character in the string has a scope that’s distinct from the character that came before it, so it can’t be rendered as a ligature and you end up with this:

image

Doing something like that on a larger scale may or may not be easy though; plus it suffers from your having to modify the syntax to do it.

3 Likes

#3

Sublime will break tokens on every match, so you can just add:

- match: .

inside double_quoted_string (after everything else) and it will emit a separate token for each character.

0 Likes

#4

Looks like it’s safer to just turn it off for now. String literals usually do not further scope text inside the string so creating a special string literal character scope just to break ligatures seems like a pretty fragile fix. Thanks for the information!

0 Likes

#5

Does using several caputures inside the same match qualify as creating different tokens? What if several captures apply the same scope?

0 Likes

#6

If the rule contains a push, pop, or set, then tokens are broken up on every capture group boundary. If the rule does not, then capture groups that do not apply a scope are ignored. I haven’t specifically tested the case where several capture groups apply the same scope, but I assume that the tokens would be broken.

0 Likes