Skip to content

Commit 1a9f845

Browse files
committed
Support command prefixes in REPL
e.g. `:q` or `:qu` instead of `:quit`. If exactly one command matching the prefix is found, it is executed. If multiple matching commands are found, an error is shown. (Currently this is not possible, as each command starts with a different letter.)
1 parent 93ef012 commit 1a9f845

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

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

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ sealed trait Command extends ParseResult
4141
/** An unknown command that will not be handled by the REPL */
4242
case class UnknownCommand(cmd: String) extends Command
4343

44+
/** An ambiguous prefix that matches multiple commands */
45+
case class AmbiguousCommand(cmd: String) extends Command
46+
4447
/** `:load <path>` interprets a scala file as if entered line-by-line into
4548
* the REPL
4649
*/
@@ -116,19 +119,29 @@ object ParseResult {
116119
stats
117120
}
118121

122+
private val commands: List[(String, String => ParseResult)] = List(
123+
Quit.command -> (_ => Quit),
124+
Help.command -> (_ => Help),
125+
Reset.command -> (_ => Reset),
126+
Imports.command -> (_ => Imports),
127+
Load.command -> (arg => Load(arg)),
128+
TypeOf.command -> (arg => TypeOf(arg)),
129+
DocOf.command -> (arg => DocOf(arg))
130+
)
131+
119132
def apply(source: SourceFile)(implicit state: State): ParseResult = {
120133
val sourceCode = source.content().mkString
121134
sourceCode match {
122135
case "" => Newline
123-
case CommandExtract(cmd, arg) => cmd match {
124-
case Quit.command => Quit
125-
case Help.command => Help
126-
case Reset.command => Reset
127-
case Imports.command => Imports
128-
case Load.command => Load(arg)
129-
case TypeOf.command => TypeOf(arg)
130-
case DocOf.command => DocOf(arg)
131-
case _ => UnknownCommand(cmd)
136+
case CommandExtract(cmd, arg) => {
137+
val matchingParsers = commands.collect {
138+
case (command, f) if command.startsWith(cmd) => f
139+
}
140+
matchingParsers match {
141+
case Nil => UnknownCommand(cmd)
142+
case f :: Nil => f(arg)
143+
case _ => AmbiguousCommand(cmd)
144+
}
132145
}
133146
case _ =>
134147
implicit val ctx: Context = state.context

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ class ReplDriver(settings: Array[String],
329329
out.println(s"""Unknown command: "$cmd", run ":help" for a list of commands""")
330330
state
331331

332+
case AmbiguousCommand(cmd) =>
333+
out.println(s""""$cmd" matches more than one command. Try typing a few more characters. Run ":help" for a list of commands""")
334+
state
335+
332336
case Help =>
333337
out.println(Help.text)
334338
state

0 commit comments

Comments
 (0)