Skip to content

Commit 19d673b

Browse files
committed
Repl - method signatures in autocomplete (#19917)
Closes #17367 This PR brings method signatures to repl completions, as in Scala 2 repl (but with syntax highlighting). After typing `List(1).max<TAB>`: ![image](https://github.com/scala/scala3/assets/24961583/0846e7b1-ff44-4e95-aaff-398069821b2f) [Cherry-picked b0ba045][modified]
1 parent 49e7b4c commit 19d673b

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

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

+32-20
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import dotty.tools.dotc.util.{SourceFile, SourcePosition}
3131
import dotty.tools.dotc.{CompilationUnit, Driver}
3232
import dotty.tools.dotc.config.CompilerCommand
3333
import dotty.tools.io.*
34+
import dotty.tools.repl.Rendering.showUser
3435
import dotty.tools.runner.ScalaClassLoader.*
3536
import org.jline.reader.*
3637

@@ -148,11 +149,36 @@ class ReplDriver(settings: Array[String],
148149

149150
/** Blockingly read a line, getting back a parse result */
150151
def readLine()(using state: State): ParseResult = {
151-
val completer: Completer = { (_, line, candidates) =>
152+
given Context = state.context
153+
val completer: Completer = { (lineReader, line, candidates) =>
154+
def makeCandidate(label: String) = {
155+
new Candidate(
156+
/* value = */ label,
157+
/* displ = */ stripBackTicks(label), // displayed value
158+
/* group = */ null, // can be used to group completions together
159+
/* descr = */ null, // TODO use for documentation?
160+
/* suffix = */ null,
161+
/* key = */ null,
162+
/* complete = */ false // if true adds space when completing
163+
)
164+
}
152165
val comps = completions(line.cursor, line.line, state)
153-
candidates.addAll(comps.asJava)
166+
candidates.addAll(comps.map(_.label).distinct.map(makeCandidate).asJava)
167+
val lineWord = line.word()
168+
comps.filter(c => c.label == lineWord && c.symbols.nonEmpty) match
169+
case Nil =>
170+
case exachMatches =>
171+
val terminal = lineReader.nn.getTerminal
172+
lineReader.callWidget(LineReader.CLEAR)
173+
terminal.writer.println()
174+
exachMatches.foreach: exact =>
175+
exact.symbols.foreach: sym =>
176+
terminal.writer.println(SyntaxHighlighting.highlight(sym.showUser))
177+
lineReader.callWidget(LineReader.REDRAW_LINE)
178+
lineReader.callWidget(LineReader.REDISPLAY)
179+
terminal.flush()
154180
}
155-
given Context = state.context
181+
156182
try {
157183
val line = terminal.readLine(completer)
158184
ParseResult(line)
@@ -229,23 +255,10 @@ class ReplDriver(settings: Array[String],
229255
label
230256

231257
/** Extract possible completions at the index of `cursor` in `expr` */
232-
protected final def completions(cursor: Int, expr: String, state0: State): List[Candidate] =
233-
def makeCandidate(label: String) = {
234-
235-
new Candidate(
236-
/* value = */ label,
237-
/* displ = */ stripBackTicks(label), // displayed value
238-
/* group = */ null, // can be used to group completions together
239-
/* descr = */ null, // TODO use for documentation?
240-
/* suffix = */ null,
241-
/* key = */ null,
242-
/* complete = */ false // if true adds space when completing
243-
)
244-
}
245-
258+
protected final def completions(cursor: Int, expr: String, state0: State): List[Completion] =
246259
if expr.startsWith(":") then
247260
ParseResult.commands.collect {
248-
case command if command._1.startsWith(expr) => makeCandidate(command._1)
261+
case command if command._1.startsWith(expr) => Completion(command._1, "", List())
249262
}
250263
else
251264
given state: State = newRun(state0)
@@ -258,8 +271,7 @@ class ReplDriver(settings: Array[String],
258271
unit.tpdTree = tpdTree
259272
given Context = state.context.fresh.setCompilationUnit(unit)
260273
val srcPos = SourcePosition(file, Span(cursor))
261-
val completions = try Completion.completions(srcPos)._2 catch case NonFatal(_) => Nil
262-
completions.map(_.label).distinct.map(makeCandidate)
274+
try Completion.completions(srcPos)._2 catch case NonFatal(_) => Nil
263275
}
264276
.getOrElse(Nil)
265277
end completions

0 commit comments

Comments
 (0)