summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2015-06-17 14:47:13 -0700
committerSom Snytt <som.snytt@gmail.com>2015-06-19 08:10:25 -0700
commitc3aca109e95e2259d9909f8457a1422c5c995940 (patch)
tree733e9869a7a3c064ab667a564fb7e63745b6e390 /src
parentaa98d9a8c19ca27d85b62d1eccfc868440dc9ab2 (diff)
downloadscala-c3aca109e95e2259d9909f8457a1422c5c995940.tar.gz
scala-c3aca109e95e2259d9909f8457a1422c5c995940.tar.bz2
scala-c3aca109e95e2259d9909f8457a1422c5c995940.zip
SI-9206 Fix REPL code indentation
To make code in error messages line up with the original line of code, templated code is indented by the width of the prompt. Use the raw prompt (without ANSI escapes or newlines) to determine the indentation. Also, indent only once per line.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Formatting.scala27
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala9
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala19
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ReplProps.scala6
5 files changed, 30 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala
index 9f160e2485..ca7d8776d4 100644
--- a/src/compiler/scala/tools/nsc/Properties.scala
+++ b/src/compiler/scala/tools/nsc/Properties.scala
@@ -13,7 +13,7 @@ object Properties extends scala.util.PropertiesTrait {
// settings based on jar properties, falling back to System prefixed by "scala."
def residentPromptString = scalaPropOrElse("resident.prompt", "\nnsc> ")
- def shellPromptString = scalaPropOrElse("shell.prompt", "\nscala> ")
+ def shellPromptString = scalaPropOrElse("shell.prompt", "%nscala> ")
// 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/repl/scala/tools/nsc/interpreter/Formatting.scala b/src/repl/scala/tools/nsc/interpreter/Formatting.scala
index 43e653edfd..844997429c 100644
--- a/src/repl/scala/tools/nsc/interpreter/Formatting.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Formatting.scala
@@ -8,28 +8,25 @@ package interpreter
import util.stringFromWriter
-trait Formatting {
- def prompt: String
+class Formatting(indent: Int) {
- def spaces(code: String): String = {
+ private val indentation = " " * indent
+
+ private def indenting(code: String): Boolean = {
/** Heuristic to avoid indenting and thereby corrupting """-strings and XML literals. */
val tokens = List("\"\"\"", "</", "/>")
val noIndent = (code contains "\n") && (tokens exists code.contains)
- if (noIndent) ""
- else prompt drop 1 map (_ => ' ')
+ !noIndent
}
/** Indent some code by the width of the scala> prompt.
* This way, compiler error messages read better.
*/
- def indentCode(code: String) = {
- val indent = spaces(code)
- stringFromWriter(str =>
- for (line <- code.lines) {
- str print indent
- str print (line + "\n")
- str.flush()
- }
- )
- }
+ def indentCode(code: String) = stringFromWriter(str =>
+ for (line <- code.lines) {
+ if (indenting(code)) str print indentation
+ str println line
+ str.flush()
+ }
+ )
}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 11c843248a..89061730f6 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -109,11 +109,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
class ILoopInterpreter extends IMain(settings, out) {
- outer =>
-
- override lazy val formatting = new Formatting {
- def prompt = ILoop.this.prompt
- }
+ // 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 )
}
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index e355d9f864..2550a5dc57 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -112,12 +112,13 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def this(factory: ScriptEngineFactory) = this(factory, new Settings())
def this() = this(new Settings())
- lazy val formatting: Formatting = new Formatting {
- val prompt = Properties.shellPromptString
- }
+ // 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 reporter: ReplReporter = new ReplReporter(this)
- import formatting._
+ import formatting.indentCode
import reporter.{ printMessage, printUntruncatedMessage }
// This exists mostly because using the reporter too early leads to deadlock.
@@ -468,7 +469,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
}
private def requestFromLine(line: String, synthetic: Boolean): Either[IR.Result, Request] = {
- val content = indentCode(line)
+ val content = line //indentCode(line)
val trees = parse(content) match {
case parse.Incomplete => return Left(IR.Incomplete)
case parse.Error => return Left(IR.Error)
@@ -909,10 +910,10 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees"))
}
def preamble = s"""
- |$preambleHeader
- |%s%s%s
- """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString,
- importsPreamble, indentCode(toCompute))
+ |${preambleHeader format lineRep.readName}
+ |${envLines mkString (" ", ";\n ", ";\n")}
+ |$importsPreamble
+ |${indentCode(toCompute)}""".stripMargin
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
diff --git a/src/repl/scala/tools/nsc/interpreter/ReplProps.scala b/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
index 19f66e98a2..945129a868 100644
--- a/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ReplProps.scala
@@ -17,11 +17,11 @@ class ReplProps {
val colorOk = bool("scala.color")
// Handy system prop for shell prompt, or else pick it up from compiler.properties
+ val promptString = Prop[String]("scala.repl.prompt").option getOrElse Properties.shellPromptString
val prompt = {
import scala.io.AnsiColor.{ MAGENTA, RESET }
- val p = Prop[String]("scala.repl.prompt").option getOrElse Properties.shellPromptString
- val q = String.format(p, Properties.versionNumberString)
- if (colorOk) s"$MAGENTA$q$RESET" else q
+ val p = promptString format Properties.versionNumberString
+ if (colorOk) s"$MAGENTA$p$RESET" else p
}
val info = bool("scala.repl.info")