@@ -111,11 +111,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
111
111
}
112
112
113
113
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
+ )
119
118
override protected def parentClassLoader =
120
119
settings.explicitParentLoader.getOrElse( classOf [ILoop ].getClassLoader )
121
120
}
@@ -199,10 +198,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
199
198
echo(" %d %s" .format(index + offset, line))
200
199
}
201
200
202
- private val currentPrompt = Properties .shellPromptString
203
-
204
201
/** Prompt to print when awaiting input */
205
- def prompt = currentPrompt
202
+ def prompt = replProps.prompt
206
203
207
204
import LoopCommand .{ cmd , nullary }
208
205
@@ -412,14 +409,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
412
409
}
413
410
414
411
private def readOneLine () = {
415
- import scala .io .AnsiColor .{ MAGENTA , RESET }
416
412
out.flush()
417
- in readLine (
418
- if (replProps.colorOk)
419
- MAGENTA + prompt + RESET
420
- else
421
- prompt
422
- )
413
+ in readLine prompt
423
414
}
424
415
425
416
/** The main read-eval-print loop for the repl. It calls
@@ -770,8 +761,13 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
770
761
}
771
762
772
763
private object paste extends Pasted {
764
+ import scala .util .matching .Regex .quote
773
765
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 }
775
771
776
772
def interpret (line : String ): Unit = {
777
773
echo(line.trim)
@@ -781,10 +777,17 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
781
777
782
778
def transcript (start : String ) = {
783
779
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(_) ))
785
781
}
782
+
783
+ def unapply (line : String ): Boolean = isPrompted(line)
784
+ }
785
+
786
+ private object invocation {
787
+ def unapply (line : String ): Boolean = Completion .looksLikeInvocation(line)
786
788
}
787
- import paste .{ ContinueString , PromptString }
789
+
790
+ private val lineComment = """ \s*//.*""" .r // all comment
788
791
789
792
/** Interpret expressions starting with the first line.
790
793
* Read lines until a complete compilation unit is available
@@ -796,53 +799,42 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
796
799
// signal completion non-completion input has been received
797
800
in.completion.resetVerbosity()
798
801
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)
807
816
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
+ }
821
820
}
822
821
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:
825
824
*
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.
831
830
*/
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
839
837
}
840
- else if (code.trim startsWith " //" ) {
841
- // line comment, do nothing
842
- None
843
- }
844
- else
845
- reallyInterpret._2
846
838
}
847
839
848
840
// runs :load `file` on any files passed via -i
0 commit comments