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!
Please sign in to leave a comment.
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.
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:
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?
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.
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() ?
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 findcom.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()
andprocessText()
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.
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.