@@ -111,11 +111,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
111111 }
112112
113113 class ILoopInterpreter extends IMain (settings, out) {
114- outer =>
115-
116- override lazy val formatting = new Formatting {
117- def prompt = ILoop .this .prompt
118- }
114+ // the expanded prompt but without color escapes and without leading newline, for purposes of indenting
115+ override lazy val formatting : Formatting = new Formatting (
116+ (replProps.promptString format Properties .versionNumberString).lines.toList.last.length
117+ )
119118 override protected def parentClassLoader =
120119 settings.explicitParentLoader.getOrElse( classOf [ILoop ].getClassLoader )
121120 }
@@ -199,10 +198,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
199198 echo(" %d %s" .format(index + offset, line))
200199 }
201200
202- private val currentPrompt = Properties .shellPromptString
203-
204201 /** Prompt to print when awaiting input */
205- def prompt = currentPrompt
202+ def prompt = replProps.prompt
206203
207204 import LoopCommand .{ cmd , nullary }
208205
@@ -412,14 +409,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
412409 }
413410
414411 private def readOneLine () = {
415- import scala .io .AnsiColor .{ MAGENTA , RESET }
416412 out.flush()
417- in readLine (
418- if (replProps.colorOk)
419- MAGENTA + prompt + RESET
420- else
421- prompt
422- )
413+ in readLine prompt
423414 }
424415
425416 /** The main read-eval-print loop for the repl. It calls
@@ -770,8 +761,13 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
770761 }
771762
772763 private object paste extends Pasted {
764+ import scala .util .matching .Regex .quote
773765 val ContinueString = " | "
774- val PromptString = " scala> "
766+ val PromptString = prompt.lines.toList.last
767+ val anyPrompt = s """ \\ s*(?: ${quote(PromptString .trim)}| ${quote(AltPromptString .trim)}) \\ s* """ .r
768+
769+ def isPrompted (line : String ) = matchesPrompt(line)
770+ def isPromptOnly (line : String ) = line match { case anyPrompt() => true ; case _ => false }
775771
776772 def interpret (line : String ): Unit = {
777773 echo(line.trim)
@@ -781,10 +777,17 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
781777
782778 def transcript (start : String ) = {
783779 echo(" \n // Detected repl transcript paste: ctrl-D to finish.\n " )
784- apply(Iterator (start) ++ readWhile(_.trim != PromptString .trim ))
780+ apply(Iterator (start) ++ readWhile(! isPromptOnly(_) ))
785781 }
782+
783+ def unapply (line : String ): Boolean = isPrompted(line)
784+ }
785+
786+ private object invocation {
787+ def unapply (line : String ): Boolean = Completion .looksLikeInvocation(line)
786788 }
787- import paste .{ ContinueString , PromptString }
789+
790+ private val lineComment = """ \s*//.*""" .r // all comment
788791
789792 /** Interpret expressions starting with the first line.
790793 * Read lines until a complete compilation unit is available
@@ -796,53 +799,42 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
796799 // signal completion non-completion input has been received
797800 in.completion.resetVerbosity()
798801
799- def reallyInterpret = {
800- val reallyResult = intp.interpret(code)
801- (reallyResult, reallyResult match {
802- case IR .Error => None
803- case IR .Success => Some (code)
804- case IR .Incomplete =>
805- if (in.interactive && code.endsWith(" \n\n " )) {
806- echo(" You typed two blank lines. Starting a new command." )
802+ def reallyInterpret = intp.interpret(code) match {
803+ case IR .Error => None
804+ case IR .Success => Some (code)
805+ case IR .Incomplete if in.interactive && code.endsWith(" \n\n " ) =>
806+ echo(" You typed two blank lines. Starting a new command." )
807+ None
808+ case IR .Incomplete =>
809+ in.readLine(paste.ContinueString ) match {
810+ case null =>
811+ // we know compilation is going to fail since we're at EOF and the
812+ // parser thinks the input is still incomplete, but since this is
813+ // a file being read non-interactively we want to fail. So we send
814+ // it straight to the compiler for the nice error message.
815+ intp.compileString(code)
807816 None
808- }
809- else in.readLine(ContinueString ) match {
810- case null =>
811- // we know compilation is going to fail since we're at EOF and the
812- // parser thinks the input is still incomplete, but since this is
813- // a file being read non-interactively we want to fail. So we send
814- // it straight to the compiler for the nice error message.
815- intp.compileString(code)
816- None
817-
818- case line => interpretStartingWith(code + " \n " + line)
819- }
820- })
817+
818+ case line => interpretStartingWith(code + " \n " + line)
819+ }
821820 }
822821
823- /** Here we place ourselves between the user and the interpreter and examine
824- * the input they are ostensibly submitting. We intervene in several cases:
822+ /* Here we place ourselves between the user and the interpreter and examine
823+ * the input they are ostensibly submitting. We intervene in several cases:
825824 *
826- * 1) If the line starts with "scala> " it is assumed to be an interpreter paste.
827- * 2) If the line starts with "." (but not ".." or "./") it is treated as an invocation
828- * on the previous result.
829- * 3) If the Completion object's execute returns Some(_), we inject that value
830- * and avoid the interpreter, as it's likely not valid scala code.
825+ * 1) If the line starts with "scala> " it is assumed to be an interpreter paste.
826+ * 2) If the line starts with "." (but not ".." or "./") it is treated as an invocation
827+ * on the previous result.
828+ * 3) If the Completion object's execute returns Some(_), we inject that value
829+ * and avoid the interpreter, as it's likely not valid scala code.
831830 */
832- if (code == " " ) None
833- else if (! paste.running && code.trim.startsWith(PromptString )) {
834- paste.transcript(code)
835- None
836- }
837- else if (Completion .looksLikeInvocation(code) && intp.mostRecentVar != " " ) {
838- interpretStartingWith(intp.mostRecentVar + code)
831+ code match {
832+ case " " => None
833+ case lineComment() => None // line comment, do nothing
834+ case paste() if ! paste.running => paste.transcript(code) ; None
835+ case invocation() if intp.mostRecentVar != " " => interpretStartingWith(intp.mostRecentVar + code)
836+ case _ => reallyInterpret
839837 }
840- else if (code.trim startsWith " //" ) {
841- // line comment, do nothing
842- None
843- }
844- else
845- reallyInterpret._2
846838 }
847839
848840 // runs :load `file` on any files passed via -i
0 commit comments