@@ -31,6 +31,7 @@ import dotty.tools.dotc.util.{SourceFile, SourcePosition}
3131import dotty .tools .dotc .{CompilationUnit , Driver }
3232import dotty .tools .dotc .config .CompilerCommand
3333import dotty .tools .io .*
34+ import dotty .tools .repl .Rendering .showUser
3435import dotty .tools .runner .ScalaClassLoader .*
3536import 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- val comps = completions(line.cursor, line.line, state)
153- candidates.addAll(comps.asJava)
154- }
155152 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+ }
165+ val comps = completionsWithSignatures(line.cursor, line.line, state)
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()
180+ }
181+
156182 try {
157183 val line = terminal.readLine(completer)
158184 ParseResult (line)
@@ -228,24 +254,26 @@ class ReplDriver(settings: Array[String],
228254 else
229255 label
230256
231- /** Extract possible completions at the index of `cursor` in `expr` */
257+ @ deprecated( " Use completionsWithSignatures instead " , " 3.3.4 " )
232258 protected final def completions (cursor : Int , expr : String , state0 : State ): List [Candidate ] =
233- def makeCandidate (label : String ) = {
234-
259+ completionsWithSignatures(cursor, expr, state0).map: c =>
235260 new Candidate (
236- /* value = */ label,
237- /* displ = */ stripBackTicks(label), // displayed value
261+ /* value = */ c. label,
262+ /* displ = */ stripBackTicks(c. label), // displayed value
238263 /* group = */ null , // can be used to group completions together
239264 /* descr = */ null , // TODO use for documentation?
240265 /* suffix = */ null ,
241266 /* key = */ null ,
242267 /* complete = */ false // if true adds space when completing
243268 )
244- }
269+ end completions
245270
271+
272+ /** Extract possible completions at the index of `cursor` in `expr` */
273+ protected final def completionsWithSignatures (cursor : Int , expr : String , state0 : State ): List [Completion ] =
246274 if expr.startsWith(" :" ) then
247275 ParseResult .commands.collect {
248- case command if command._1.startsWith(expr) => makeCandidate (command._1)
276+ case command if command._1.startsWith(expr) => Completion (command._1, " " , List () )
249277 }
250278 else
251279 given state : State = newRun(state0)
@@ -258,11 +286,10 @@ class ReplDriver(settings: Array[String],
258286 unit.tpdTree = tpdTree
259287 given Context = state.context.fresh.setCompilationUnit(unit)
260288 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)
289+ try Completion .completions(srcPos)._2 catch case NonFatal (_) => Nil
263290 }
264291 .getOrElse(Nil )
265- end completions
292+ end completionsWithSignatures
266293
267294 protected def interpret (res : ParseResult , quiet : Boolean = false )(using state : State ): State = {
268295 res match {
0 commit comments