Indentation in Custom Languages


The whole Formatter architecture is probably incredibly powerful, but it is near impossible to understand it, and it doesn't behave at all as I expect, and the result seems absolutely random.

I am trying to create a language plugin for "Pony", but I am stuck in the simplest of indentation problem.

1. Since I eventually want to support the spacing settings between operators, parenthesis, assignment and so on, the Block structure mimics the AST all the way down.

2. The PsiViewer shows me that the blocks are built correctly, and the inspection is great.

3. When it comes to indentation, what should most block do? Return null? Return Indentation.getNoneIndent()? What does "Normal Indent" really mean?

4. What about whitespace? I have PsiWhiteSpace in the AST, but I think I saw "improvement" by dropping that from formatting blocks, but not sure, because every time I try anything, I don't get result remotely to what I expect. (Added issue is that class reloading via debugger, is sometimes ok, but other times something is cached somewhere and restarting the session is needed. And since I now have noticed that, I must assume all previous tests are invalid, and all future tests must restart session every time, slowing me down incredibly)

It is hard to blame documentation, since too much information is also a problem. But I think a better description of the whole mental model is needed, and how that ties back into the Formatter.getInstance().createFormattingModelForPsiFile(file, rootBlock, settings); model. Pony Language Psi tree ends up being very deep, as "control blocks" (if/for/repeat/..) are expressions and can be nested arbitrarily in such, so if I don't get the mental model of what is, it is completely impossible to grok what should be used where, why and the result should be.


Sorry, to let my frustration shine through....


Plugin is on GitHub at, and working code to try on is at


If we look at a limited section;


I have the correct blocks, matching the AST/Psi



And selecting the block nodes I get selection in the text that the editor think it is;




But the above pulls all the text to the left. Why?


There is some documentation available here: In general AST structure and formatting model are two different things serving different purposes. Usually formatting model is built using AST but they do not have to match one-to-one. For example, spacing elements should never be covered by blocks unless you want the space to be left as is, one formatting block may cover several PSI elements, one PSI element may be split to several formatting blocks and so on.

In your example above not all blocks have indentation which means a continuation indent by default. It's better to use explicit indent for all blocks, it will be easier for you to analyze the model later to figure out what went wrong.


Well... you're not alone, I'm stuck at this as well for a long time and left it for later.
Sadly that documentation JetBrains offers explains about 5% of what you need to know... if not less.

I'd advice to look at git repositories for some smaller plugins like and study from code.
And if you want to understand it a bit, it's always better to look at 2 or 3 different plugins, because most people seems to be drowning in IntelliJ language plugins.

It would be really helpful to create one good example project... not the 'SimpleLanguage' that is in documentation as it barely cover and explains anything.