Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 41 additions & 14 deletions compiler/src/dotty/tools/repl/ReplDriver.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import dotty.tools.dotc.util.{SourceFile, SourcePosition}
import dotty.tools.dotc.{CompilationUnit, Driver}
import dotty.tools.dotc.config.CompilerCommand
import dotty.tools.io.*
import dotty.tools.repl.Rendering.showUser
import dotty.tools.runner.ScalaClassLoader.*
import org.jline.reader.*

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

/** Blockingly read a line, getting back a parse result */
def readLine()(using state: State): ParseResult = {
val completer: Completer = { (_, line, candidates) =>
val comps = completions(line.cursor, line.line, state)
candidates.addAll(comps.asJava)
}
given Context = state.context
val completer: Completer = { (lineReader, line, candidates) =>
def makeCandidate(label: String) = {
new Candidate(
/* value = */ label,
/* displ = */ stripBackTicks(label), // displayed value
/* group = */ null, // can be used to group completions together
/* descr = */ null, // TODO use for documentation?
/* suffix = */ null,
/* key = */ null,
/* complete = */ false // if true adds space when completing
)
}
val comps = completionsWithSignatures(line.cursor, line.line, state)
candidates.addAll(comps.map(_.label).distinct.map(makeCandidate).asJava)
val lineWord = line.word()
comps.filter(c => c.label == lineWord && c.symbols.nonEmpty) match
case Nil =>
case exachMatches =>
val terminal = lineReader.nn.getTerminal
lineReader.callWidget(LineReader.CLEAR)
terminal.writer.println()
exachMatches.foreach: exact =>
exact.symbols.foreach: sym =>
terminal.writer.println(SyntaxHighlighting.highlight(sym.showUser))
lineReader.callWidget(LineReader.REDRAW_LINE)
lineReader.callWidget(LineReader.REDISPLAY)
terminal.flush()
}

try {
val line = terminal.readLine(completer)
ParseResult(line)
Expand Down Expand Up @@ -228,24 +254,26 @@ class ReplDriver(settings: Array[String],
else
label

/** Extract possible completions at the index of `cursor` in `expr` */
@deprecated("Use completionsWithSignatures instead", "3.3.4")
protected final def completions(cursor: Int, expr: String, state0: State): List[Candidate] =
def makeCandidate(label: String) = {

completionsWithSignatures(cursor, expr, state0).map: c =>
new Candidate(
/* value = */ label,
/* displ = */ stripBackTicks(label), // displayed value
/* value = */ c.label,
/* displ = */ stripBackTicks(c.label), // displayed value
/* group = */ null, // can be used to group completions together
/* descr = */ null, // TODO use for documentation?
/* suffix = */ null,
/* key = */ null,
/* complete = */ false // if true adds space when completing
)
}
end completions


/** Extract possible completions at the index of `cursor` in `expr` */
protected final def completionsWithSignatures(cursor: Int, expr: String, state0: State): List[Completion] =
if expr.startsWith(":") then
ParseResult.commands.collect {
case command if command._1.startsWith(expr) => makeCandidate(command._1)
case command if command._1.startsWith(expr) => Completion(command._1, "", List())
}
else
given state: State = newRun(state0)
Expand All @@ -258,11 +286,10 @@ class ReplDriver(settings: Array[String],
unit.tpdTree = tpdTree
given Context = state.context.fresh.setCompilationUnit(unit)
val srcPos = SourcePosition(file, Span(cursor))
val completions = try Completion.completions(srcPos)._2 catch case NonFatal(_) => Nil
completions.map(_.label).distinct.map(makeCandidate)
try Completion.completions(srcPos)._2 catch case NonFatal(_) => Nil
}
.getOrElse(Nil)
end completions
end completionsWithSignatures

protected def interpret(res: ParseResult, quiet: Boolean = false)(using state: State): State = {
res match {
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/dotty/tools/repl/TabcompleteTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TabcompleteTests extends ReplTest {

/** Returns the `(<instance completions>, <companion completions>)`*/
private def tabComplete(src: String)(implicit state: State): List[String] =
completions(src.length, src, state).map(_.value).sorted
completionsWithSignatures(src.length, src, state).map(_.label).sorted.distinct

@Test def tabCompleteList = initially {
val comp = tabComplete("List.r")
Expand Down