Ligature support for custom languages? (like PHPStorm)

Answered

Hi,

I'd like to add custom ligature support for my language plugin I'm developing. 

My issue is that the '<=' sign can either mean "smaller than or equal to" __or__ a type of assignment depending on context.

I've just realized the PHPStorm has the same issue and SOMEHOW solves it so that it renders "correctly".

I can't find any documentation for how to add this to a custom language.

In my BNF file there is enough rule knowledge to know when each glyph should be rendered.

8 comments
Comment actions Permalink

Currently different tokens are not joined in a ligature if they are displayed in different colors or font types (regular, italic, etc) in current color scheme. There's no other language specific logic now.

0
Comment actions Permalink

Thank you for your reply!

If I understand you correctly this would then be under user control?

But if I go in under Settings->Editor->Color & Fonts-><MY LANGUAGE> and pick OPERATORS and then make them BOLD & ITALIC (or any other combination) they are still shown as ligatures. If I show underlined or boxed they are still shown as ligatures but with underlined or boxed applied. 

What am I missing?

I'm running 2016.2.5 and FiraCode a.t.m

1
Comment actions Permalink

For ligature not to apply to <= symbols, 'less-than' and 'equals' should represent tokens with different color and/or font style. Is it so in your case?

0
Comment actions Permalink

Dmitry:

I think I understand. So what you are saying is that my language would have to:

1: Remove the token '<=' and instead look for token '<' and '=' in the BNF file

2: Token '<' and token '=' would, in turn, have to have different color and/or font styles (from each other). (The easiest would be to change the color minutely).

If that was the case then the render would *not* render it as a ligature. Is this correct?

Follow on question: If I got the above to work could I then implement an Annotator (http://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/annotator.html) to dynamically change the color depending on some language state variable?

 

 

 

0
Comment actions Permalink

That's correct. It will work wherever different styles come from - lexer or annotator (in the latter case, the effect will be asynchronous, though).

0
Comment actions Permalink

Thank you.

Looking at the Rust project they seem to dynamically return different characters directly in the flex file. This seems better than using an Annotator. It seems I could do something similar and return a different '=' character depending on context. For one type of '=' the color would then be off by one which should stop rendering while not making it visibly different.

Still a bit cumbersome but doable. Might give it a spin later today.

The downside is that it would be exposed to the end user in the color settings page... Perhaps that's hideable too with the correct logic but the amount of code needed is starting to add up.

0
Comment actions Permalink

Dmitry:

I can confirm that step 1 works. If I change my language definition to remove the '<=' token AND make sure that '=' is a different color (currently assigned as a keyword instead of an operator) then glyph generation stops. This is great(ish). My issue now is that default colors I can pick from all differ substantially which makes the '<' '=' combination look weird (gray + bold orange)

I would now like to refine it so that '=' is generated as a separate category that is just like the default operator sign but with the text color attribute changed by one step as this should be invisible to the naked eye (dirty hack but ok). I don't understand to do this.

 

The color settings example from the custom language documentation and the open-source project I've looked at all use default colors. 

How would I go about starting from a default color option but then modifying the text color setting by 1?

 

0
Comment actions Permalink

Example in the guide uses SyntaxHighlighter/SyntaxHighlighterFactory. SyntaxHighlighter's API won't allow you to do what you want (you'll need to return a separate TextAttributeKey for '=', and that key's name should be explicitly specified in the color scheme, so this will require a change in each color scheme you want it to work with).

You can try working directly via EditorHighlighter interface (used internally by editor implementation), by providing an EditorHighlighterProvider instance for your file type. EditorHighlighter can generate text attributes directly for given editor/document and color scheme. But this will mean more work for you.

0

Please sign in to leave a comment.