@@ -31,6 +31,7 @@ import dotty.tools.dotc.util.{SourceFile, SourcePosition}
31
31
import dotty .tools .dotc .{CompilationUnit , Driver }
32
32
import dotty .tools .dotc .config .CompilerCommand
33
33
import dotty .tools .io .*
34
+ import dotty .tools .repl .Rendering .showUser
34
35
import dotty .tools .runner .ScalaClassLoader .*
35
36
import org .jline .reader .*
36
37
@@ -148,11 +149,36 @@ class ReplDriver(settings: Array[String],
148
149
149
150
/** Blockingly read a line, getting back a parse result */
150
151
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
- }
155
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
+ }
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
+
156
182
try {
157
183
val line = terminal.readLine(completer)
158
184
ParseResult (line)
@@ -228,24 +254,26 @@ class ReplDriver(settings: Array[String],
228
254
else
229
255
label
230
256
231
- /** Extract possible completions at the index of `cursor` in `expr` */
257
+ @ deprecated( " Use completionsWithSignatures instead " , " 3.3.4 " )
232
258
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 =>
235
260
new Candidate (
236
- /* value = */ label,
237
- /* displ = */ stripBackTicks(label), // displayed value
261
+ /* value = */ c. label,
262
+ /* displ = */ stripBackTicks(c. label), // displayed value
238
263
/* group = */ null , // can be used to group completions together
239
264
/* descr = */ null , // TODO use for documentation?
240
265
/* suffix = */ null ,
241
266
/* key = */ null ,
242
267
/* complete = */ false // if true adds space when completing
243
268
)
244
- }
269
+ end completions
245
270
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 ] =
246
274
if expr.startsWith(" :" ) then
247
275
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 () )
249
277
}
250
278
else
251
279
given state : State = newRun(state0)
@@ -258,11 +286,10 @@ class ReplDriver(settings: Array[String],
258
286
unit.tpdTree = tpdTree
259
287
given Context = state.context.fresh.setCompilationUnit(unit)
260
288
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
263
290
}
264
291
.getOrElse(Nil )
265
- end completions
292
+ end completionsWithSignatures
266
293
267
294
protected def interpret (res : ParseResult , quiet : Boolean = false )(using state : State ): State = {
268
295
res match {
0 commit comments