Custom string literal formatter

Answered

I would like to implement custom formatting for a certain parts of my code:

Consider the following code snippet:

MyClass clazz = new MyClass();
clazz
.row("|first|second|third|")
.row("|a|bla bla bla|bird|")
.row("|2|5.4|-1|");

I want to apply this formatting to string literals of .row() calls only

What I want is to make sure the following rules are applied to formatting action:

  • every cell in a column must be expanded to the longest cell width in the column
  • every cell must have 1 leading space and at least 1 trailing space
  • every cell must be aligned to the right side

As a result I expect something like this:

MyClass clazz = new MyClass();
clazz
.row("| first | second | third |")
.row("| a | bla bla bla | bird |")
.row("| 2 | 5.4 | -1 |");

I look for an appropriate extension point and even would be better to have some practical implementations as real examples.

Thank you!

0
6 comments

Hi Serhii,

It seems like a job for https://plugins.jetbrains.com/docs/intellij/code-formatting.html#post-processor.

It should replace string literals with the ones that are modified to your needs.

0

Karol Lewandowski thank you for the response!

I see that there are two methods to implement.

processElement() for some reason never gets triggered - what can be a problem?

processText() does get triggered, however I'm stuck what I suppose to do given a whole file and entire file text range.
It requires text range to be returned. What range should it be in my case if I want to format only these literals:

MyClass clazz = new MyClass();
clazz
.row("|first|second|third|")
.row("|a|bla bla bla|bird|")
.row("|2|5.4|-1|");

And I tried to debug how can I get a list of these .row() calls but looks like it is composed into single PsiMethodCallExpression.

How do I get a List<PsiMethodCallExpression> of size 3 that resolves to that chaining calls?

0

Hi Serhii,

Sorry, but I don't understand why processElement() is not called. I suggest debugging the formatting action to see why it is avoided.

Regarding getting the literals you want to modify, I suggest using "Tools | View PSI Structure…" or the PsiViewer plugin to understand the PSI structure and retrieve the required nodes.

0

Hi Karol, no worries.

When you talk about "debugging the formatting action". What in practice should I do? Can you suggest exact classes and methods to set breakpoints?

About literal modification: Should it be inside processElement() or processText() ?

0

Hi Serhii,

The standard approach is to search for the ExtensionPointName containing qualified name of the extension point of your interest. In this case, you can easily find com.intellij.psi.impl.source.codeStyle.PostFormatProcessor#EP_NAME. Now search for its usages, and you will get the parts you should debug to understand how it works.

In the case when there is no ExtensionPointName for a given extension point, I suggest looking for the interface method usages in the platform code.

Regarding the choice between processElements() and processText()I believe they are invoked depending on how the formatting is triggered, so you will have to implement both.

I also suggest checking for the existing implementations in https://github.com/JetBrains/intellij-community or on https://jb.gg/ipe to get some inspiration.

 
0

Hi Karol!

I was not able to debug `processElement()` so its never triggered.
However I achieved my goal in `processText()`.

Thank you for useful links, they were essential for me.

0

Please sign in to leave a comment.