Idiosyncratic Scala Indent Style

Opinion: both IntelliJ and (especially) ScalaFmt formatting rules suck. That is partly because of syntactical complexity of the language on one hand, but especially because various syntactical fragments can vastly vary in size. A method may have no type parameters, a type parameter list of a couple characters, or one of a couple lines (especially with implicits). Similarly with parameter lists. Add to this the fact that, where the variance of Java type names is really low, it is huge in Scala when the application of higher types come into play. Sometimes a rule 'align parameters with the opening paren' looks right, sometimes the opening paren is close to the hard wrap line. Sometimes a parameter per line is ok, sometimes a huge waste of screen estate.

Bottom line: I would switch off formatting completely if I could (don't even make me start on how IntelliJ hates `if/else` without braces). I developed an adaptive style, as well as a personal preference for aligning broken declarations to key syntax points rather than based on the indent used for nesting blocks. Examples:

  • when breaking an 'extends' list align the end of the first 'with' of the following line with the end of 'extends' (thus aligning the names of extended types)
  • when breaking a generic method (with a type parameter list which ends close to half way to the hard wrap, start the parameter list in the next line, aligning '(' with '['.
  • unless aligning it with the start of the method name instead would prevent line breaking
  • align continuations of type and value parameter lists with the first opening '[' or '('
  • unless it is placed close to half way to the hard wrap and results in an excessive number of breaks, in which case use a single indent unit.
  • if the return type must be placed in a new line, use two indent units to indent it deeper than the indent of the method body.

It is a bit of a pain to do all this manually and I started entertainig the thought of implementing it in IDE. It would have to run on top of the chosen formatter, because a lot of configuration there remains applicable regardless of line breaking and indents. I doubt anyone would like to see it in the official Scala plugin, but it would have to be relatively tightly integrated.

So, my question is: how much work would it be for a complete noob to IntelliJ plugin development to inject/bolt on some heuristic code to the formatter, in a way that doesn't replace it completely (like ScalaFmt)? Could someone point me to a source file and say 'start there'?

Please sign in to leave a comment.