Structured Highlights
This project can be found on github at
https://github.com/luxalpa/structured-highlights
Furthermore, it is released on the Jetbrains marketplace: https://plugins.jetbrains.com/plugin/28073-structured-highlights/
Motivation
I had been working on my Houdini-Node implementation when I realized that I found it really annoying to look through the source code in order to find trait and function implementations. The usual syntax highlighting was more of a distraction if anything, and what I really wanted was a way to very quickly locate the function that I wanted to edit.
From this, the idea was born to build a plugin to automatically draw boxes around individual code blocks.
In addition to this, with RustRover being my main IDE to use, I also was motivated to learn how to write extensions for the editor in general so that later on I could use this experience to implement other functionality that I might want to do.
Implementation
Building the feature was relatively easy. This was my first time writing and reading Kotlin code, and I asked ChatGPT to teach me the language which went very well. In general, this was a project in which my AI tools had become extremely handy. With Kotlin being such a popular language, the tool was very accurate and I could just constantly bombard it with questions.
Being very experienced at this point handling all kinds of AST and parser stuff, the highlighting itself was pretty straight forward to build, although I did end up switching the highlighter itself around a few times, looking at other crates source code as the IntelliJ API itself was very underdocumented.
In fact, the lack of general documentation on the API turned out to be a borderline nightmare when implementing the settings menu. I wanted the user (me) to be able to adjust colors and opacity on the highlighting with a preview directly in the settings menu. But this feature was not available on the normal settings page workflow used by virtually every other plugin on the marketplace and required a deepdive into custom User Interface creation and rendering, as well as understanding the internals of the Jetbrains code editor control.
Later on I also decided to make all of this work with Themes (it currently doesn't), and while I haven't released a theme specific version, most of the technicalities have been figured out.
Here I also learned how invaluable AI tools can be when it comes to analyzing and understanding large, foreign and very underdocumented code bases. While pretty much none of my actual code was generated by the AI tools (because they would just get it wrong all the time) and ChatGPT turned out to be pretty useless for answering questions about IDEA specific API's (I thought if it was trained on all the IDEA extensions it would be a bit smarter in understanding its API), the AI extension provided inside IntelliJ itself was able to look over the actual IntelliJ source code and save me many hours of manual analysis.
Future
I am currently actively using the extension every day as my main highlighter. I have disabled most of my IDE's syntax highlighting and only use the rainbow highlights for different variables ("semantic highlighting"), which massively cuts down on distractions.
Once I have a bit more time to work on this again, I will finish the theming implementation, which means fully splitting the settings page into 2 separate pages - one for the colors which depend on the theme, and one for the actual rules which are not theme specific (as in IntelliJ you can only have colors and font properties in themes, nothing else).
Then, I need to revisit the painting process. Currently it uses semi-transparent rectangles that can be layered on top of each other. This looked really nice, but it created a severe performance issue so that I had to disable layering ( i.e. blocks inside blocks) in a patch update. In order to reenable this feature, and also make performance even better in normal mode, I will need to change the rendering away from using opacity. This however means that the blocks need to be rendered at the bottom-most layer - and that means that the background-highlight for the caret line will completely override it instead of blending in. Because that looks pretty jarring in practice, the solution here is to also manually implement a feature into this theme that renders the builtin caret line with opacity. In practice I have been able to make this work, but on the settings dialog it needs to deal with a bunch of edge cases (as it overrides a value in the default theme that cannot normally be changed by the user outside of this extension).
Then the main piece of work - although not very challenging - will be to implement this highlighter for other programming languages, so that it will also be possible to use this in other Jetbrains IDE's.
The next plan is to add more options for what to highlight. Currently it's only doing the outer-most blocks, but one idea was to for example highlight inline lambda blocks, or the current loop-block, or if-condition, etc. Possibly even just the parts between function parentheses for nested function calls.
Also, in addition to just block formatting, I also want to enable other types of syntactical highlighting as well. Current highlighting in pretty much every IDE is solely based on lexing (which is way more performant), but I would like to have more accurate highlights. For example, highlighting variables based on their types. Highlighting functions based on attribute-macros. Classes based on their interface implementations, etc.