8000 SI-4684 Repl supports whole-file paste · scala/scala@82e9a64 · GitHub
[go: up one dir, main page]

Skip to content

Commit 82e9a64

Browse files
som-snyttadriaanm
authored andcommitted
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 ```
1 parent 7125dc3 commit 82e9a64

File tree

4 files changed

+50
-15
lines changed

4 files changed

+50
-15
lines changed

src/repl/scala/tools/nsc/interpreter/ILoop.scala

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
216216
cmd("implicits", "[-v]", "show the implicits in scope", intp.implicitsCommand),
217217
cmd("javap", "<path|class>", "disassemble a file or class name", javapCommand),
218218
cmd("line", "<id>|<line>", "place line(s) at the end of history", lineCommand),
219-
cmd("load", "<path>", "load and interpret a Scala file", loadCommand),
220-
nullary("paste", "enter paste mode: all input up to ctrl-D compiled together", pasteCommand),
219+
cmd("load", "<path>", "interpret lines in a file", loadCommand),
220+
cmd("paste", "[path]", "enter paste mode or paste a file", pasteCommand),
221221
nullary("power", "enable power user mode", powerCmd),
222222
nullary("quit", "exit the interpreter", () => Result(keepRunning = false, None)),
223223
nullary("replay", "reset execution and replay all previous commands", replay),
@@ -585,11 +585,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
585585
}
586586
}
587587

588-
def withFile(filename: String)(action: File => Unit) {
589-
val f = File(filename)
590-
591-
if (f.exists) action(f)
592-
else echo("That file does not exist")
588+
def withFile[A](filename: String)(action: File => A): Option[A] = {
589+
val res = Some(File(filename)) filter (_.exists) map action
590+
if (res.isEmpty) echo("That file does not exist") // courtesy side-effect
591+
res
593592
}
594593

595594
def loadCommand(arg: String) = {
@@ -665,13 +664,26 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
665664
Iterator continually in.readLine("") takeWhile (x => x != null && cond(x))
666665
}
667666

668-
def pasteCommand(): Result = {
669-
echo("// Entering paste mode (ctrl-D to finish)\n")
670-
val code = readWhile(_ => true) mkString "\n"
671-
if (code.trim.isEmpty) {
672-
echo("\n// Nothing pasted, nothing gained.\n")
673-
} else {
674-
echo("\n// Exiting paste mode, now interpreting.\n")
667+
def pasteCommand(arg: String): Result = {
668+
var shouldReplay: Option[String] = None
669+
val code = (
670+
if (arg.nonEmpty) {
671+
withFile(arg)(f => {
672+
shouldReplay = Some(s":paste $arg")
673+
val s = f.slurp.trim
674+
if (s.isEmpty) echo(s"File contains no code: $f")
675+
else echo(s"Pasting file $f...")
676+
s
677+
}) getOrElse ""
678+
} else {
679+
echo("// Entering paste mode (ctrl-D to finish)\n")
680+
val text = (readWhile(_ => true) mkString "\n").trim
681+
if (text.isEmpty) echo("\n// Nothing pasted, nothing gained.\n")
682+
else echo("\n// Exiting paste mode, now interpreting.\n")
683+
text
684+
}
685+
)
686+
if (code.nonEmpty) {
675687
val res = intp interpret code
676688
// if input is incomplete, let the compiler try to say why
677689
if (res == IR.Incomplete) {
@@ -681,7 +693,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
681693
if (errless) echo("...but compilation found no error? Good luck with that.")
682694
}
683695
}
684-
()
696+
Result(keepRunning = true, shouldReplay)
685697
}
686698

687699
private object paste extends Pasted {

test/files/run/repl-paste-4.check

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Type in expressions to have them evaluated.
2+
Type :help for more information.
3+
4+
scala> :paste repl-paste-4.pastie
5+
Pasting file repl-paste-4.pastie...
6+
defined class Foo
7+
defined object Foo
8+
9+
scala> Foo(new Foo)
10+
res0: Int = 7
11+
12+
scala>

test/files/run/repl-paste-4.pastie

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
// if we are truly companions, I can see your foo
3+
class Foo { private val foo = 7 }
4+
object Foo { def apply(f: Foo) = f.foo }

test/files/run/repl-paste-4.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
import scala.tools.partest.ReplTest
3+
4+
object Test extends ReplTest {
5+
def code = s":paste $pastie\nFoo(new Foo)\n"
6+
def pastie = testPath.changeExtension("pastie")
7+
}

0 commit comments

Comments
 (0)
0