scalafmt
scalafmt copied to clipboard
Can't align def and val on the same token
I can't align def and val on the same token
This used to work on previous version, like 3.5.9
NB: this issue follow the discussion here
Configuration (required)
version = "3.7.1"
project.git = true
runner.dialect = scala213
maxColumn = 120
align.preset = most
align.allowOverflow = true
align.multiline = true
continuationIndent {
defnSite = 2
extendSite = 2
withSiteRelativeToExtends = 2
}
assumeStandardLibraryStripMargin = true
docstrings.style = keep
newlines.source = keep
lineEndings = preserve
includeCurlyBraceInSelectChains = true
danglingParentheses {
defnSite = true
callSite = true
ctrlSite = true
}
spaces {
inImportCurlyBraces = true
afterKeywordBeforeParen = false
}
optIn.annotationNewlines = true
rewrite.rules = [SortImports, PreferCurlyFors]
rewrite.redundantBraces.generalExpressions = false
rewrite.redundantBraces.methodBodies = false
rewrite.redundantBraces.includeUnitMethods = false
rewrite.redundantBraces.stringInterpolation = false
align.tokens.add = [
{ code = ":", owner = "Param" }
{ code = "=" }
{ code = "?|" }
{ code = "?|>" }
{ code = "|>" }
{ code = "withClue" }
]
Command-line parameters (required)
When I run scalafmt via CLI like this:
~/Dev/scala/sorus develop +2 !11 ?6 ❯ scalafmt 11.0.12+0
'align.tokens.add' is deprecated; use align.tokens."+" instead.
Reformatting...
100,0% [##########] 10 source files formatted
Steps
Given code like this:
package helpers.sorus
import scala.concurrent.duration._
class AuthenticationService() {
private[this] def retry_count_cache_key(xxx: String) = s"some_very_very_very_very_very_very_very_very_very_very_very_long_string_$xxx"
private[this] def retry_cache_key(xxx: String) = s"some_short_string$xxx"
private[this] val retry_timing_in_seconds = 30 seconds
val x = "some_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_veryvery_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_string"
val xx = "àç098098"
val xxx = "àç098098"
val xxxxx = "àç098098"
def coucou(): Int = {
println(s"""
${retry_count_cache_key("123")}
${retry_cache_key("123")}
$retry_timing_in_seconds
""")
12
}
}
Problem
Scalafmt formats code like this:
package helpers.sorus
import scala.concurrent.duration._
class AuthenticationService() {
private[this] def retry_count_cache_key(xxx: String) =
s"some_very_very_very_very_very_very_very_very_very_very_very_long_string_$xxx"
private[this] def retry_cache_key(xxx: String) = s"some_short_string$xxx"
private[this] val retry_timing_in_seconds = 30 seconds
val x =
"some_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_veryvery_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_string"
val xx = "àç098098"
val xxx = "àç098098"
val xxxxx = "àç098098"
def coucou(): Int = {
println(s"""
${retry_count_cache_key("123")}
${retry_cache_key("123")}
$retry_timing_in_seconds
""")
12
}
}
Expectation
I would like the formatted output to look like this:
package helpers.sorus
import scala.concurrent.duration._
class AuthenticationService() {
private[this] def retry_count_cache_key(xxx: String) = s"some_very_very_very_very_very_very_very_very_very_very_very_long_string_$xxx"
private[this] def retry_cache_key(xxx: String) = s"some_short_string$xxx"
private[this] val retry_timing_in_seconds = 30 seconds
val x = "some_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_veryvery_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_string"
val xx = "àç098098"
val xxx = "àç098098"
val xxxxx = "àç098098"
def coucou(): Int = {
println(s"""
${retry_count_cache_key("123")}
${retry_cache_key("123")}
$retry_timing_in_seconds
""")
12
}
}
Note
this is the output when I switch version to 3.5.9
- def and val are aligned according to
=
package helpers.sorus
import scala.concurrent.duration._
class AuthenticationService() {
private[this] def retry_count_cache_key(xxx: String) =
s"some_very_very_very_very_very_very_very_very_very_very_very_long_string_$xxx"
private[this] def retry_cache_key(xxx: String) = s"some_short_string$xxx"
private[this] val retry_timing_in_seconds = 30 seconds
val x =
"some_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_veryvery_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_string"
val xx = "àç098098"
val xxx = "àç098098"
val xxxxx = "àç098098"
def coucou(): Int = {
println(s"""
${retry_count_cache_key("123")}
${retry_cache_key("123")}
$retry_timing_in_seconds
""")
12
}
}
@Driox unfortunately, for now, i don't know how to fix this problem.
it was probably introduced in #3335, to be able to align parameters on adjacent lines, as requested by another user. alas, your use case was not protected by regression tests at that time.
since you have both :
and =
in your list of tokens, for the def
line in your example, :
is in alignment position 1 and =
is in position 2. however, for the val
line, =
is in position 1; it doesn't align with the previous =
because positions don't match. if you remove :
from your configuration, it should work.
to make this work, we'd have to rewrite the entire alignment logic, to be able to assign priority to alignment stops, remove assumptions about alignment stops being contiguous etc., and i don't have the time to do that.