The class signature can do exactly what you want. ...
# ktlint
p
The class signature can do exactly what you want. See configuration option in docs: https://pinterest.github.io/ktlint/latest/rules/standard/#class-signature
m
🤔 hmmm.... It's not quite working the way I want unfortunately. The class constructor parameters taken on their own don't exceed the character limit so they don't wrap on to separate lines. But the super type does exceed the character limit so is the only one that gets moved to a new line. That's different to what I'm looking for which is to have the whole class signature line considered for exceeding the character limit and then wrapped accordingly. I might be missing something obvious, apologies.
p
Can you provide more details about the version of ktlint you're using, and the
.editorconfig
settings? You might have something configured that is blocking the rule from executing the way you want it to run. Also, I am assuming that you run ktlint via its CLI.
m
Hi Paul, thanks for the help. I've set up a minimal reproduction in this repo. The full
.editorconfig
is also in that repo but the significant parts (at least in my head 😆 ) are:
Copy code
max_line_length = 140
ktlint_code_style = intellij_idea
ktlint_standard_class-signature = enabled
ktlint_function_naming_ignore_when_annotated_with = Composable
ktlint_standard_function-expression-body = disabled
ktlint_standard_multiline-expression-wrapping = disabled
To answer your question:
I am assuming that you run ktlint via its CLI.
I do not. But I run it via the IntelliJ IDE plugin which is recommended in the KtLint page.
Can you provide more details about the version of ktlint you're using,
I've tried with both version
1.3.1
(which we use at work) and
1.5.0
(which I am trying out locally).
p
As documented, setting
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 1
forces the class signature to be written as requested. But it will do this for any class signature having at least 1 parameters regardless whether the (single line) signature fits on one line or not.
m
I did stumble upon that configuration after I posted my message and gave that a try. It works but then forces all of my other class signatures to wrap even if they fit on a single line as you point out. Is there any possibility of a middle ground here for non official KtLint code styles? Something like: • If class signature and a single super type fits on one line, wrap as if
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = unset
• If class signature and single super type does not fit on a single line, wrap as if
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 1
p
m
Thanks, I appreciate the maintenance burden of adding new options. I totally understand and respect that. I'll continue to set
ktlint_standard_class-signature = disabled
in that case. And thank you for the explanations and insight 🙏 .
Sorry to come back to this but what's your view on this: https://kotlinlang.org/docs/coding-conventions.html#class-headers
Classes with a few primary constructor parameters can be written in a single line:
Copy code
class Person(id: Int, name: String)
Classes with longer headers should be formatted so that each primary constructor parameter is in a separate line with indentation. Also, the closing parenthesis should be on a new line. If you use inheritance, the superclass constructor call, or the list of implemented interfaces should be located on the same line as the parenthesis:
```class Person(
id: Int,
name: String,
surname: String
) : Human(id, name) { /*...*/ }```
Specifically this:
If you use inheritance, the superclass constructor call, or the list of implemented interfaces should be located on the same line as the parenthesis:
The test at the heart of this thread seems to contradict this convention as it moves the implemented interface to a newline below the closing parenthesis. I understand that setting
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 1
gives me this behaviour for one or more parameters but according to that Kotlin convention I shouldn't need to force this setting. It should automatically kick it if the whole header exceeds the line limit. I'm just interested in your thoughts at the moment I've got plenty of workarounds to be satisfied for now. Many thanks again, Paul!
p
The coding conventions are just guidelines. They contain details about specific situations, but do not claim to provide an answer for all possible scenarios. Ktlint often has to extend the conventions to be applicable for a wider range of scenarios. It is not too difficult to find a specific code sample that can be written more optimally when no formatter is used. The hard part is to find an algorithm that always work with reasonable results.
🙏 1