Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix indentation when adding pipes in multiline string. #922

Merged
merged 1 commit into from Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
@@ -1,4 +1,4 @@
def localSnapshotVersion = "0.7.5-SNAPSHOT"
def localSnapshotVersion = "0.7.6-SNAPSHOT"
def isCI = System.getenv("CI") != null

def crossSetting[A](
Expand Down
@@ -1,8 +1,10 @@
package scala.meta.internal.metals

import org.eclipse.lsp4j.{DocumentOnTypeFormattingParams, Range, TextEdit}

import scala.concurrent.{ExecutionContext, Future}
import org.eclipse.lsp4j.DocumentOnTypeFormattingParams
import org.eclipse.lsp4j.Range
import org.eclipse.lsp4j.TextEdit
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.meta.inputs.Input
import scala.meta.internal.metals.MetalsEnrichments._
import scala.meta.internal.mtags.Semanticdbs
Expand Down Expand Up @@ -47,6 +49,24 @@ final class MultilineStringFormattingProvider(
space * (lastPipe - lastNewline - 1)
}

private def indent(
sourceText: String,
start: Int,
position: Position
): TextEdit = {
val defaultIndent = indent(sourceText, start)
val existingSpaces = position.getCharacter()
val addedSpaces = defaultIndent.drop(existingSpaces)
val startChar = defaultIndent.size - addedSpaces.size
position.setCharacter(startChar)
val endChar = startChar + Math.max(0, existingSpaces - defaultIndent.size)
val endPosition = new Position(position.getLine(), endChar)
new TextEdit(
new Range(position, endPosition),
addedSpaces + "|"
)
}

private def isMultilineString(text: String, token: Token) = {
val start = token.start
text(start) == quote &&
Expand Down Expand Up @@ -132,7 +152,7 @@ final class MultilineStringFormattingProvider(
val doc = params.getTextDocument()
val newlineAdded = params.getCh() == "\n"
withToken(doc, range, newlineAdded) { (sourceText, position) =>
List(new TextEdit(range, indent(sourceText, position.start) + "|"))
List(indent(sourceText, position.start, params.getPosition))
}
}

Expand Down
15 changes: 11 additions & 4 deletions tests/unit/src/main/scala/tests/TestingServer.scala
Expand Up @@ -400,10 +400,11 @@ final class TestingServer(
filename: String,
query: String,
expected: String,
autoIndent: String,
root: AbsolutePath = workspace
): Future[Unit] = {
for {
(text, params) <- onTypeParams(filename, query, root)
(text, params) <- onTypeParams(filename, query, root, autoIndent)
multiline <- server.onTypeFormatting(params).asScala
format = TextEdits.applyEdits(
textContents(filename),
Expand Down Expand Up @@ -512,12 +513,18 @@ final class TestingServer(
private def onTypeParams(
filename: String,
original: String,
root: AbsolutePath
root: AbsolutePath,
autoIndent: String
): Future[(String, DocumentOnTypeFormattingParams)] = {
positionFromString(filename, original, root, replaceWith = "\n") {
positionFromString(
filename,
original,
root,
replaceWith = "\n" + autoIndent
) {
case (text, textId, start) =>
start.setLine(start.getLine() + 1) // + newline
start.setCharacter(0)
start.setCharacter(autoIndent.size)
val params = new DocumentOnTypeFormattingParams(start, "\n")
params.setTextDocument(textId)
(text, params)
Expand Down
39 changes: 32 additions & 7 deletions tests/unit/src/test/scala/tests/OnTypeFormattingSuite.scala
Expand Up @@ -80,7 +80,7 @@ object OnTypeFormattingSuite extends BaseSlowSuite("onTypeFormatting") {
|object Main {
| val number = 102
| val str = s"|
|$$number".stripMargin
| $$number".stripMargin
|}""".stripMargin
)

Expand Down Expand Up @@ -118,7 +118,7 @@ object OnTypeFormattingSuite extends BaseSlowSuite("onTypeFormatting") {
| | a multiline
| | string
| '''.stripMargin
|
|
|}""".stripMargin
)

Expand All @@ -136,7 +136,7 @@ object OnTypeFormattingSuite extends BaseSlowSuite("onTypeFormatting") {
| val abc = 123
| val s = ''' example
| word
|'''.stripMargin
| '''.stripMargin
| abc.toInt
|}""".stripMargin
)
Expand All @@ -146,17 +146,41 @@ object OnTypeFormattingSuite extends BaseSlowSuite("onTypeFormatting") {
s"""
|object Main {
| val str = '''|@@
|'''.stripMargin
| '''.stripMargin
|}""".stripMargin,
s"""
|object Main {
| val str = '''|
| |
|'''.stripMargin
| '''.stripMargin
|}""".stripMargin
)

def check(name: String, testCase: String, expectedCase: String): Unit = {
// this can be caused by the client if scala syntax is recognized inside a string
check(
"weird-indent",
s"""
|object Main {
| val str = '''
| |object A{@@
| '''.stripMargin
|}""".stripMargin,
s"""
|object Main {
| val str = '''
| |object A{
| |
| '''.stripMargin
|}""".stripMargin,
" " * 4
)

def check(
name: String,
testCase: String,
expectedCase: String,
autoIndent: String = " "
): Unit = {
val tripleQuote = """\u0022\u0022\u0022"""
def unmangle(string: String): String =
string.replaceAll("'''", tripleQuote)
Expand All @@ -176,7 +200,8 @@ object OnTypeFormattingSuite extends BaseSlowSuite("onTypeFormatting") {
_ <- server.onTypeFormatting(
"a/src/main/scala/a/Main.scala",
test,
expected
expected,
autoIndent
)
} yield ()
}
Expand Down