summaryrefslogtreecommitdiff
path: root/src/repl/scala/tools/nsc/interpreter/Pasted.scala
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2015-07-20 17:07:51 -0700
committerJason Zaugg <jzaugg@gmail.com>2015-09-02 12:45:29 +1000
commit1566196669bb74891a2116236b3e76ea340f6c29 (patch)
treefc857418f1ea580022dae0d833afb89a1bfa9002 /src/repl/scala/tools/nsc/interpreter/Pasted.scala
parent5a23aac8c421fa017edb094563c552236be13c6f (diff)
downloadscala-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.scala56
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)
}