summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSeth Tisue <seth@tisue.net>2015-07-01 15:56:17 -0400
committerSeth Tisue <seth@tisue.net>2015-07-01 15:56:17 -0400
commit495fdb8119c1941bc210a9b0a186d63971002e22 (patch)
tree2067bf5985fc138577fa7251b0ab7e4a23236a88 /src
parentc8fbc41631da0a860f749479a610312814c0e88f (diff)
parentfac81d705ff0bfdeb3320fd9e46b6d3d34e47ddf (diff)
downloadscala-495fdb8119c1941bc210a9b0a186d63971002e22.tar.gz
scala-495fdb8119c1941bc210a9b0a186d63971002e22.tar.bz2
scala-495fdb8119c1941bc210a9b0a186d63971002e22.zip
Merge pull request #4576 from som-snytt/issue/9206-more
SI-9206 REPL custom bits
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala8
-rw-r--r--src/library/scala/sys/BooleanProp.scala1
-rw-r--r--src/library/scala/sys/Prop.scala4
-rw-r--r--src/partest-extras/scala/tools/partest/ReplTest.scala34
-rw-r--r--src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala12
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Formatting.scala3
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala27
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala4
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ReplProps.scala46
9 files changed, 92 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala
index ca7d8776d4..cb523edfe5 100644
--- a/src/compiler/scala/tools/nsc/Properties.scala
+++ b/src/compiler/scala/tools/nsc/Properties.scala
@@ -12,8 +12,16 @@ object Properties extends scala.util.PropertiesTrait {
protected def pickJarBasedOn = classOf[Global]
// settings based on jar properties, falling back to System prefixed by "scala."
+
+ // messages to display at startup or prompt, format string with string parameters
+ // Scala version, Java version, JVM name
def residentPromptString = scalaPropOrElse("resident.prompt", "\nnsc> ")
def shellPromptString = scalaPropOrElse("shell.prompt", "%nscala> ")
+ def shellWelcomeString = scalaPropOrElse("shell.welcome",
+ """Welcome to Scala %1$#s (%3$s, Java %2$s).
+ |Type in expressions for evaluation. Or try :help.""".stripMargin
+ )
+
// message to display at EOF (which by default ends with
// a newline so as not to break the user's terminal)
def shellInterruptedString = scalaPropOrElse("shell.interrupted", f":quit$lineSeparator")
diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala
index e5e4668edb..b0008b41fd 100644
--- a/src/library/scala/sys/BooleanProp.scala
+++ b/src/library/scala/sys/BooleanProp.scala
@@ -50,6 +50,7 @@ object BooleanProp {
def get: String = "" + value
val clear, enable, disable, toggle = ()
def option = if (isSet) Some(value) else None
+ //def or[T1 >: Boolean](alt: => T1): T1 = if (value) true else alt
protected def zero = false
}
diff --git a/src/library/scala/sys/Prop.scala b/src/library/scala/sys/Prop.scala
index 17ae8cb69c..52a3d89ecb 100644
--- a/src/library/scala/sys/Prop.scala
+++ b/src/library/scala/sys/Prop.scala
@@ -58,6 +58,10 @@ trait Prop[+T] {
*/
def option: Option[T]
+ // Do not open until 2.12.
+ //** This value if the property is set, an alternative value otherwise. */
+ //def or[T1 >: T](alt: => T1): T1
+
/** Removes the property from the underlying map.
*/
def clear(): Unit
diff --git a/src/partest-extras/scala/tools/partest/ReplTest.scala b/src/partest-extras/scala/tools/partest/ReplTest.scala
index 1fde2370d3..20dfe0eb16 100644
--- a/src/partest-extras/scala/tools/partest/ReplTest.scala
+++ b/src/partest-extras/scala/tools/partest/ReplTest.scala
@@ -6,8 +6,9 @@
package scala.tools.partest
import scala.tools.nsc.Settings
-import scala.tools.nsc.interpreter.ILoop
+import scala.tools.nsc.interpreter.{ ILoop, replProps }
import java.lang.reflect.{ Method => JMethod, Field => JField }
+import scala.util.matching.Regex
import scala.util.matching.Regex.Match
/** A class for testing repl code.
@@ -19,30 +20,33 @@ abstract class ReplTest extends DirectTest {
// final because we need to enforce the existence of a couple settings.
final override def settings: Settings = {
val s = super.settings
- // s.Yreplsync.value = true
s.Xnojline.value = true
transformSettings(s)
}
+ def normalize(s: String) = s
/** True for SessionTest to preserve session text. */
def inSession: Boolean = false
- /** True to preserve welcome text. */
+ /** True to preserve welcome header, eliding version number. */
def welcoming: Boolean = false
- lazy val welcome = "(Welcome to Scala) version .*".r
- def normalize(s: String) = s match {
- case welcome(w) => w
- case s => s
- }
- def unwelcoming(s: String) = s match {
- case welcome(w) => false
- case _ => true
- }
+ lazy val header = replProps.welcome
def eval() = {
val s = settings
log("eval(): settings = " + s)
- //ILoop.runForTranscript(code, s).lines drop 1 // not always first line
val lines = ILoop.runForTranscript(code, s, inSession = inSession).lines
- if (welcoming) lines map normalize
- else lines filter unwelcoming
+ (if (welcoming) {
+ val welcome = "(Welcome to Scala).*".r
+ //val welcome = Regex.quote(header.lines.next).r
+ //val version = "(.*version).*".r // version on separate line?
+ //var inHead = false
+ lines map {
+ //case s @ welcome() => inHead = true ; s
+ //case version(s) if inHead => inHead = false ; s
+ case welcome(s) => s
+ case s => s
+ }
+ } else {
+ lines drop header.lines.size
+ }) map normalize
}
def show() = eval() foreach println
}
diff --git a/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala b/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
index b6c9792ec0..53a06ca972 100644
--- a/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
+++ b/src/repl-jline/scala/tools/nsc/interpreter/jline/FileBackedHistory.scala
@@ -7,9 +7,9 @@ package scala.tools.nsc.interpreter.jline
import _root_.jline.console.history.PersistentHistory
-
import scala.tools.nsc.interpreter
-import scala.tools.nsc.io.{File, Path}
+import scala.reflect.io.{ File, Path }
+import scala.tools.nsc.Properties.{ propOrNone, userHome }
/** TODO: file locking.
*/
@@ -85,9 +85,9 @@ object FileBackedHistory {
// val ContinuationChar = '\003'
// val ContinuationNL: String = Array('\003', '\n').mkString
- import scala.tools.nsc.Properties.userHome
-
- def defaultFileName = ".scala_history"
+ final val defaultFileName = ".scala_history"
- def defaultFile: File = File(Path(userHome) / defaultFileName)
+ def defaultFile: File = File(
+ propOrNone("scala.shell.histfile") map (Path.apply) getOrElse (Path(userHome) / defaultFileName)
+ )
}
diff --git a/src/repl/scala/tools/nsc/interpreter/Formatting.scala b/src/repl/scala/tools/nsc/interpreter/Formatting.scala
index 844997429c..4a9548730a 100644
--- a/src/repl/scala/tools/nsc/interpreter/Formatting.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Formatting.scala
@@ -30,3 +30,6 @@ class Formatting(indent: Int) {
}
)
}
+object Formatting {
+ def forPrompt(prompt: String) = new Formatting(prompt.lines.toList.last.length)
+}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 525609171e..6470a450b2 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -56,13 +56,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private var globalFuture: Future[Boolean] = _
- /** Print a welcome message */
- def printWelcome() {
- echo(s"""
- |Welcome to Scala $versionString ($javaVmName, Java $javaVersion).
- |Type in expressions to have them evaluated.
- |Type :help for more information.""".trim.stripMargin
- )
+ /** Print a welcome message! */
+ def printWelcome(): Unit = {
+ Option(replProps.welcome) filter (!_.isEmpty) foreach echo
replinfo("[info] started at " + new java.util.Date)
}
@@ -111,10 +107,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
class ILoopInterpreter extends IMain(settings, out) {
- // the expanded prompt but without color escapes and without leading newline, for purposes of indenting
- override lazy val formatting: Formatting = new Formatting(
- (replProps.promptString format Properties.versionNumberString).lines.toList.last.length
- )
override protected def parentClassLoader =
settings.explicitParentLoader.getOrElse( classOf[ILoop].getClassLoader )
}
@@ -680,9 +672,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
def verbosity() = {
- val old = intp.printResults
- intp.printResults = !old
- echo("Switched " + (if (old) "off" else "on") + " result printing.")
+ intp.printResults = !intp.printResults
+ replinfo(s"Result printing is ${ if (intp.printResults) "on" else "off" }.")
}
/** Run one command submitted by the user. Two values are returned:
@@ -762,7 +753,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private object paste extends Pasted {
import scala.util.matching.Regex.quote
- val ContinueString = " | "
+ val ContinuePrompt = replProps.continuePrompt
+ val ContinueString = replProps.continueText // " | "
val PromptString = prompt.lines.toList.last
val anyPrompt = s"""\\s*(?:${quote(PromptString.trim)}|${quote(AltPromptString.trim)})\\s*""".r
@@ -806,7 +798,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
echo("You typed two blank lines. Starting a new command.")
None
case IR.Incomplete =>
- in.readLine(paste.ContinueString) match {
+ in.readLine(paste.ContinuePrompt) match {
case null =>
// we know compilation is going to fail since we're at EOF and the
// parser thinks the input is still incomplete, but since this is
@@ -949,8 +941,9 @@ object ILoop {
Console.withOut(ostream) {
val output = new JPrintWriter(new OutputStreamWriter(ostream), true) {
// skip margin prefix for continuation lines, unless preserving session text for test
+ // should test for repl.paste.ContinueString or replProps.continueText.contains(ch)
override def write(str: String) =
- if (!inSession && (str forall (ch => ch.isWhitespace || ch == '|'))) () // repl.paste.ContinueString
+ if (!inSession && (str forall (ch => ch.isWhitespace || ch == '|'))) ()
else super.write(str)
}
val input = new BufferedReader(new StringReader(code.trim + "\n")) {
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 2550a5dc57..841b4abfa5 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -113,9 +113,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def this() = this(new Settings())
// the expanded prompt but without color escapes and without leading newline, for purposes of indenting
- lazy val formatting: Formatting = new Formatting(
- (replProps.promptString format Properties.versionNumberString).lines.toList.last.length
- )
+ lazy val formatting = Formatting.forPrompt(replProps.promptText)
lazy val reporter: ReplReporter = new ReplReporter(this)
import formatting.indentCode
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplProps.scala b/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
index df65e9974d..588d92f81b 100644
--- a/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
@@ -6,9 +6,11 @@
package scala.tools.nsc
package interpreter
-import Properties.shellPromptString
+import Properties.{ javaVersion, javaVmName, shellPromptString, shellWelcomeString,
+ versionString, versionNumberString }
import scala.sys._
import Prop._
+import java.util.{ Formattable, FormattableFlags, Formatter }
class ReplProps {
private def bool(name: String) = BooleanProp.keyExists(name)
@@ -22,12 +24,44 @@ class ReplProps {
val trace = bool("scala.repl.trace")
val power = bool("scala.repl.power")
- // Handy system prop for shell prompt, or else pick it up from compiler.properties
- val promptString = Prop[String]("scala.repl.prompt").option getOrElse (if (info) "%nscala %s> " else shellPromptString)
- val prompt = {
+ def enversion(s: String) = {
+ import FormattableFlags._
+ val v = new Formattable {
+ override def formatTo(formatter: Formatter, flags: Int, width: Int, precision: Int) = {
+ val version = if ((flags & ALTERNATE) != 0) versionNumberString else versionString
+ val left = if ((flags & LEFT_JUSTIFY) != 0) "-" else ""
+ val w = if (width >= 0) s"$width" else ""
+ val p = if (precision >= 0) s".$precision" else ""
+ val fmt = s"%${left}${w}${p}s"
+ formatter.format(fmt, version)
+ }
+ }
+ s.format(v, javaVersion, javaVmName)
+ }
+ def encolor(s: String) = {
import scala.io.AnsiColor.{ MAGENTA, RESET }
- val p = promptString format Properties.versionNumberString
- if (colorOk) s"$MAGENTA$p$RESET" else p
+ if (colorOk) s"$MAGENTA$s$RESET" else s
+ }
+
+ // Handy system prop for shell prompt, or else pick it up from compiler.properties
+ val promptString = Prop[String]("scala.repl.prompt").option getOrElse (if (info) "%nscala %#s> " else shellPromptString)
+ val promptText = enversion(promptString)
+ val prompt = encolor(promptText)
+
+ // Prompt for continued input, will be right-adjusted to width of the primary prompt
+ val continueString = Prop[String]("scala.repl.continue").option getOrElse "| "
+ val continueText = {
+ val text = enversion(continueString)
+ val margin = promptText.lines.toList.last.length - text.length
+ if (margin > 0) " " * margin + text else text
+ }
+ val continuePrompt = encolor(continueText)
+
+ // Next time.
+ //def welcome = enversion(Prop[String]("scala.repl.welcome") or shellWelcomeString)
+ def welcome = enversion {
+ val p = Prop[String]("scala.repl.welcome")
+ if (p.isSet) p.get else shellWelcomeString
}
/** CSV of paged,across to enable pagination or `-x` style