summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2013-07-01 00:30:16 -0700
committerSom Snytt <som.snytt@gmail.com>2013-07-11 19:06:42 -0700
commit816a444f177b5f2bb90a2e89802d06c26f6a21ff (patch)
tree1d97ae0dad5e415dc6a1d1f36ca29e0a08b765de
parent8b41240f3d532c470112d7bf1f409badac4d56aa (diff)
downloadscala-816a444f177b5f2bb90a2e89802d06c26f6a21ff.tar.gz
scala-816a444f177b5f2bb90a2e89802d06c26f6a21ff.tar.bz2
scala-816a444f177b5f2bb90a2e89802d06c26f6a21ff.zip
SI-4684 Repl supports whole-file paste
Add a file argument to the :paste command which loads the file's contents as though entered in :paste mode. The :paste command is replayable. Samples, including companions defined together: ``` scala> :paste junk.scala File contains no code: junk.scala scala> :paste no-file.scala That file does not exist scala> :paste obj-repl.scala Pasting file obj-repl.scala... <console>:2: error: expected start of definition private foo = 7 ^ scala> :paste hw-repl.scala Pasting file hw-repl.scala... The pasted code is incomplete! <pastie>:5: error: illegal start of simple expression } ^ scala> :replay Replaying: :paste junk.scala File contains no code: junk.scala Replaying: :paste obj-repl.scala Pasting file obj-repl.scala... defined trait Foo defined object Foo Replaying: Foo(new Foo{}) res0: Int = 7 ```
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala42
-rw-r--r--test/files/run/repl-paste-4.pastie4
-rw-r--r--test/files/run/repl-paste-4.scala20
3 files changed, 51 insertions, 15 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index ccc9621fad..aa65a858df 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -216,8 +216,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
cmd("implicits", "[-v]", "show the implicits in scope", intp.implicitsCommand),
cmd("javap", "<path|class>", "disassemble a file or class name", javapCommand),
cmd("line", "<id>|<line>", "place line(s) at the end of history", lineCommand),
- cmd("load", "<path>", "load and interpret a Scala file", loadCommand),
- nullary("paste", "enter paste mode: all input up to ctrl-D compiled together", pasteCommand),
+ cmd("load", "<path>", "interpret lines in a file", loadCommand),
+ cmd("paste", "[path]", "enter paste mode or paste a file", pasteCommand),
nullary("power", "enable power user mode", powerCmd),
nullary("quit", "exit the interpreter", () => Result(keepRunning = false, None)),
nullary("replay", "reset execution and replay all previous commands", replay),
@@ -585,11 +585,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
- def withFile(filename: String)(action: File => Unit) {
- val f = File(filename)
-
- if (f.exists) action(f)
- else echo("That file does not exist")
+ def withFile[A](filename: String)(action: File => A): Option[A] = {
+ val res = Some(File(filename)) filter (_.exists) map action
+ if (res.isEmpty) echo("That file does not exist") // courtesy side-effect
+ res
}
def loadCommand(arg: String) = {
@@ -665,13 +664,26 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
Iterator continually in.readLine("") takeWhile (x => x != null && cond(x))
}
- def pasteCommand(): Result = {
- echo("// Entering paste mode (ctrl-D to finish)\n")
- val code = readWhile(_ => true) mkString "\n"
- if (code.trim.isEmpty) {
- echo("\n// Nothing pasted, nothing gained.\n")
- } else {
- echo("\n// Exiting paste mode, now interpreting.\n")
+ def pasteCommand(arg: String): Result = {
+ var shouldReplay: Option[String] = None
+ val code = (
+ if (arg.nonEmpty) {
+ withFile(arg)(f => {
+ shouldReplay = Some(s":paste $arg")
+ val s = f.slurp.trim
+ if (s.isEmpty) echo(s"File contains no code: $f")
+ else echo(s"Pasting file $f...")
+ s
+ }) getOrElse ""
+ } else {
+ echo("// Entering paste mode (ctrl-D to finish)\n")
+ val text = (readWhile(_ => true) mkString "\n").trim
+ if (text.isEmpty) echo("\n// Nothing pasted, nothing gained.\n")
+ else echo("\n// Exiting paste mode, now interpreting.\n")
+ text
+ }
+ )
+ if (code.nonEmpty) {
val res = intp interpret code
// if input is incomplete, let the compiler try to say why
if (res == IR.Incomplete) {
@@ -681,7 +693,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
if (errless) echo("...but compilation found no error? Good luck with that.")
}
}
- ()
+ Result(keepRunning = true, shouldReplay)
}
private object paste extends Pasted {
diff --git a/test/files/run/repl-paste-4.pastie b/test/files/run/repl-paste-4.pastie
new file mode 100644
index 0000000000..853a66f6a4
--- /dev/null
+++ b/test/files/run/repl-paste-4.pastie
@@ -0,0 +1,4 @@
+
+// if we are truly companions, I can see your foo
+class Foo { private val foo = 7 }
+object Foo { def apply(f: Foo) = f.foo }
diff --git a/test/files/run/repl-paste-4.scala b/test/files/run/repl-paste-4.scala
new file mode 100644
index 0000000000..0060dc1ff6
--- /dev/null
+++ b/test/files/run/repl-paste-4.scala
@@ -0,0 +1,20 @@
+
+import scala.tools.partest.SessionTest
+
+object Test extends SessionTest {
+ def session =
+s"""|Type in expressions to have them evaluated.
+ |Type :help for more information.
+ |
+ |scala> :paste $pastie
+ |Pasting file $pastie...
+ |defined class Foo
+ |defined object Foo
+ |
+ |scala> Foo(new Foo)
+ |res0: Int = 7
+ |
+ |scala> """
+ def pastie = testPath changeExtension "pastie"
+}
+