Skip to content

Commit a50e7ca

Browse files
committed
fix: ensure you still get completion when using backticks
This commit addresses the situation where you are trying to use a backtick when it's not needed. For example if you have: ```scala object Foo: case `bar` case foo Foo.`b ``` You still expect to get a completion bar being backticked. This also ensure that if you try ``Foo.`fo`` you also still get a completion.
1 parent f61c6c8 commit a50e7ca

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

compiler/src/dotty/tools/dotc/interactive/Completion.scala

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import dotty.tools.dotc.core.StdNames.nme
1515
import dotty.tools.dotc.core.SymDenotations.SymDenotation
1616
import dotty.tools.dotc.core.TypeError
1717
import dotty.tools.dotc.core.Types.{ExprType, MethodOrPoly, NameFilter, NoType, TermRef, Type}
18-
import dotty.tools.dotc.parsing.Scanners
1918
import dotty.tools.dotc.parsing.Tokens
2019
import dotty.tools.dotc.util.Chars
2120
import dotty.tools.dotc.util.SourcePosition
@@ -118,6 +117,7 @@ object Completion {
118117
private def computeCompletions(pos: SourcePosition, path: List[Tree])(using Context): (Int, List[Completion]) = {
119118
val mode = completionMode(path, pos)
120119
val rawPrefix = completionPrefix(path, pos)
120+
121121
val hasBackTick = rawPrefix.headOption.contains('`')
122122
val prefix = if hasBackTick then rawPrefix.drop(1) else rawPrefix
123123

@@ -135,7 +135,8 @@ object Completion {
135135
}
136136

137137
val describedCompletions = describeCompletions(completions)
138-
val backtickedCompletions = describedCompletions.map(backtickCompletions)
138+
val backtickedCompletions =
139+
describedCompletions.map(completion => backtickCompletions(completion, hasBackTick))
139140

140141
val offset = completionOffset(path)
141142

@@ -147,14 +148,14 @@ object Completion {
147148
(offset, backtickedCompletions)
148149
}
149150

150-
def backtickCompletions(completion: Completion) =
151-
if needsBacktick(completion.label) then
151+
def backtickCompletions(completion: Completion, hasBackTick: Boolean) =
152+
if hasBackTick || needsBacktick(completion.label) then
152153
completion.copy(label = s"`${completion.label}`")
153154
else
154155
completion
155156

156157
// This borrows from Metals, which itself borrows from Ammonite. This uses
157-
// the same apprach, but some of the utils that already exist in Dotty.
158+
// the same approach, but some of the utils that already exist in Dotty.
158159
// https://github.com/scalameta/metals/blob/main/mtags/src/main/scala/scala/meta/internal/mtags/KeywordWrapper.scala
159160
// https://github.com/com-lihaoyi/Ammonite/blob/73a874173cd337f953a3edc9fb8cb96556638fdd/amm/util/src/main/scala/ammonite/util/Model.scala
160161
private def needsBacktick(s: String) =
@@ -429,6 +430,7 @@ object Completion {
429430
private def include(denot: SingleDenotation, nameInScope: Name)(using Context): Boolean =
430431
val sym = denot.symbol
431432

433+
432434
nameInScope.startsWith(prefix) &&
433435
sym.exists &&
434436
completionsFilter(NoType, nameInScope) &&

compiler/src/dotty/tools/repl/ReplDriver.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ import org.jline.reader._
3535
import scala.annotation.tailrec
3636
import scala.collection.JavaConverters._
3737
import scala.util.Using
38-
import dotty.tools.dotc.util.Chars
39-
import dotty.tools.dotc.parsing.Tokens
4038

4139
/** The state of the REPL contains necessary bindings instead of having to have
4240
* mutation

language-server/test/dotty/tools/languageserver/CompletionTest.scala

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,4 +1078,47 @@ class CompletionTest {
10781078
| val x = Bar.`back${m1}"""
10791079
.withSource.completion(m1, expected)
10801080
}
1081+
1082+
@Test def backticksSpace: Unit = {
1083+
val expected = Set(
1084+
("`has space`", Field, "Foo.Bar"),
1085+
)
1086+
code"""object Foo:
1087+
| enum Bar:
1088+
| case `has space`
1089+
|
1090+
| val x = Bar.`has s${m1}"""
1091+
.withSource.completion(m1, expected)
1092+
}
1093+
1094+
@Test def backticksCompleteBoth: Unit = {
1095+
val expected = Set(
1096+
("formatted", Method, "(fmtstr: String): String"),
1097+
("`foo-bar`", Field, "Int"),
1098+
("foo", Field, "Int")
1099+
)
1100+
code"""object Foo:
1101+
| object Bar:
1102+
| val foo = 1
1103+
| val `foo-bar` = 2
1104+
| val `bar` = 3
1105+
|
1106+
| val x = Bar.fo${m1}"""
1107+
.withSource.completion(m1, expected)
1108+
}
1109+
1110+
@Test def backticksWhenNotNeeded: Unit = {
1111+
val expected = Set(
1112+
("`formatted`", Method, "(fmtstr: String): String"),
1113+
("`foo-bar`", Field, "Int"),
1114+
("`foo`", Field, "Int")
1115+
)
1116+
code"""object Foo:
1117+
| object Bar:
1118+
| val foo = 1
1119+
| val `foo-bar` = 2
1120+
|
1121+
| val x = Bar.`fo${m1}"""
1122+
.withSource.completion(m1, expected)
1123+
}
10811124
}

0 commit comments

Comments
 (0)