diff options
author | Som Snytt <som.snytt@gmail.com> | 2015-07-20 17:07:51 -0700 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-09-02 12:45:29 +1000 |
commit | 1566196669bb74891a2116236b3e76ea340f6c29 (patch) | |
tree | fc857418f1ea580022dae0d833afb89a1bfa9002 /src/repl/scala/tools/nsc/interpreter/Pasted.scala | |
parent | 5a23aac8c421fa017edb094563c552236be13c6f (diff) | |
download | scala-1566196669bb74891a2116236b3e76ea340f6c29.tar.gz scala-1566196669bb74891a2116236b3e76ea340f6c29.tar.bz2 scala-1566196669bb74891a2116236b3e76ea340f6c29.zip |
SI-5408 Prompt after incomplete script paste
Transcript paste mode invites the user to keep typing like
regular paste mode, but really you must enter more transcript.
This matters if the script ends in the middle of incomplete
code that the user wants to complete by hand.
Previously,
```
scala> scala> def f() = {
// Detected repl transcript paste: ctrl-D to finish.
// Replaying 1 commands from transcript.
scala> def f() = {
scala> scala> def f() = {
// Detected repl transcript paste: ctrl-D to finish.
| }
// Replaying 1 commands from transcript.
scala> def f() = {
}
f: ()Unit
```
Now,
```
scala> scala> def f() = {
// Detected repl transcript. Paste more, or ctrl-D to finish.
// Replaying 1 commands from transcript.
scala> def f() = {
| 42
| }
f: ()Int
scala> f()
res0: Int = 42
```
Diffstat (limited to 'src/repl/scala/tools/nsc/interpreter/Pasted.scala')
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/Pasted.scala | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/Pasted.scala b/src/repl/scala/tools/nsc/interpreter/Pasted.scala index f8d8c2ddb1..3a7eda1b77 100644 --- a/src/repl/scala/tools/nsc/interpreter/Pasted.scala +++ b/src/repl/scala/tools/nsc/interpreter/Pasted.scala @@ -15,19 +15,23 @@ package interpreter * a transcript should itself be pasteable and should achieve * the same result. */ -abstract class Pasted { - def interpret(line: String): Unit - def ContinueString: String - def PromptString: String - def AltPromptString: String = "scala> " +abstract class Pasted(prompt: String) { + def interpret(line: String): IR.Result + def echo(message: String): Unit - /* `testBoth` cannot be a val, as `Pasted` is inherited by `object paste` in ILoop, - which would cause `val testBoth` to be initialized before `val PromptString` was. + val PromptString = prompt.lines.toList.last + val AltPromptString = "scala> " + val ContinuePrompt = replProps.continuePrompt + val ContinueString = replProps.continueText // " | " + val anyPrompt = { + import scala.util.matching.Regex.quote + s"""\\s*(?:${quote(PromptString.trim)}|${quote(AltPromptString.trim)})\\s*""".r + } + + def isPrompted(line: String) = matchesPrompt(line) + def isPromptOnly(line: String) = line match { case anyPrompt() => true ; case _ => false } - object paste extends Pasted { - val PromptString = prompt.lines.toList.last - */ - private def testBoth = PromptString != AltPromptString + private val testBoth = PromptString != AltPromptString private val spacey = " \t".toSet def matchesPrompt(line: String) = matchesString(line, PromptString) || testBoth && matchesString(line, AltPromptString) @@ -91,13 +95,26 @@ abstract class Pasted { case _ => code } - def run(): Unit = { - println("// Replaying %d commands from transcript.\n" format cmds.size) - cmds foreach { cmd => - print(ActualPromptString) - interpret(cmd) - } + def interpreted(line: String) = { + echo(line.trim) + val res = interpret(line) + if (res != IR.Incomplete) echo("") + res + } + def incompletely(cmd: String) = { + print(ActualPromptString) + interpreted(cmd) == IR.Incomplete } + def run(): Option[String] = { + echo(s"// Replaying ${cmds.size} commands from transcript.\n") + cmds find incompletely + } + } + + // Run transcript and return incomplete line if any. + def transcript(lines: TraversableOnce[String]): Option[String] = { + echo("\n// Detected repl transcript. Paste more, or ctrl-D to finish.\n") + apply(lines) } /** Commands start on lines beginning with "scala>" and each successive @@ -105,9 +122,10 @@ abstract class Pasted { * Everything else is discarded. When the end of the transcript is spotted, * all the commands are replayed. */ - def apply(lines: TraversableOnce[String]) = { + def apply(lines: TraversableOnce[String]): Option[String] = { isRunning = true - try new PasteAnalyzer(lines.toList) run() + try new PasteAnalyzer(lines.toList).run() finally isRunning = false } + def unapply(line: String): Boolean = isPrompted(line) } |