Skip to content

Commit e7468f3

Browse files
committed
SI-4684 Repl supports raw paste
By special request, :paste -raw simply compiles the pasted code to the repl output dir. The -raw flag means no wrapping; the pasted code must be ordinary top level Scala code, not script.
1 parent 816a444 commit e7468f3

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

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

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
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),
219219
cmd("load", "<path>", "interpret lines in a file", loadCommand),
220-
cmd("paste", "[path]", "enter paste mode or paste a file", pasteCommand),
220+
cmd("paste", "[-raw] [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),
@@ -666,24 +666,38 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
666666

667667
def pasteCommand(arg: String): Result = {
668668
var shouldReplay: Option[String] = None
669-
val code = (
670-
if (arg.nonEmpty) {
671-
withFile(arg)(f => {
669+
def result = Result(keepRunning = true, shouldReplay)
670+
val (raw, file) =
671+
if (arg.isEmpty) (false, None)
672+
else {
673+
val r = """(-raw)?(\s+)?([^\-]\S*)?""".r
674+
arg match {
675+
case r(flag, sep, name) =>
676+
if (flag != null && name != null && sep == null)
677+
echo(s"""I assume you mean "$flag $name"?""")
678+
(flag != null, Option(name))
679+
case _ =>
680+
echo("usage: :paste -raw file")
681+
return result
682+
}
683+
}
684+
val code = file match {
685+
case Some(name) =>
686+
withFile(name)(f => {
672687
shouldReplay = Some(s":paste $arg")
673688
val s = f.slurp.trim
674689
if (s.isEmpty) echo(s"File contains no code: $f")
675690
else echo(s"Pasting file $f...")
676691
s
677692
}) getOrElse ""
678-
} else {
693+
case None =>
679694
echo("// Entering paste mode (ctrl-D to finish)\n")
680695
val text = (readWhile(_ => true) mkString "\n").trim
681696
if (text.isEmpty) echo("\n// Nothing pasted, nothing gained.\n")
682697
else echo("\n// Exiting paste mode, now interpreting.\n")
683698
text
684-
}
685-
)
686-
if (code.nonEmpty) {
699+
}
700+
def interpretCode() = {
687701
val res = intp interpret code
688702
// if input is incomplete, let the compiler try to say why
689703
if (res == IR.Incomplete) {
@@ -693,7 +707,14 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
693707
if (errless) echo("...but compilation found no error? Good luck with that.")
694708
}
695709
}
696-
Result(keepRunning = true, shouldReplay)
710+
def compileCode() = {
711+
val errless = intp compileSources new BatchSourceFile("<pastie>", code)
712+
if (!errless) echo("There were compilation errors!")
713+
}
714+
if (code.nonEmpty) {
715+
if (raw) compileCode() else interpretCode()
716+
}
717+
result
697718
}
698719

699720
private object paste extends Pasted {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
// a raw paste is not a script
3+
// hence it can be packaged
4+
5+
package brown_paper
6+
7+
// these are a few of my favorite things
8+
case class Gift (hasString: Boolean)

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
import scala.tools.partest.SessionTest
3+
4+
object Test extends SessionTest {
5+
def session =
6+
s"""|Type in expressions to have them evaluated.
7+
|Type :help for more information.
8+
|
9+
|scala> :paste -raw $pastie
10+
|Pasting file $pastie...
11+
|
12+
|scala> val favoriteThing = brown_paper.Gift(true)
13+
|favoriteThing: brown_paper.Gift = Gift(true)
14+
|
15+
|scala> favoriteThing.hasString
16+
|res0: Boolean = true
17+
|
18+
|scala> """
19+
def pastie = testPath changeExtension "pastie"
20+
}

0 commit comments

Comments
 (0)