Skip to content

Commit

Permalink
Merge pull request scala#6045 from som-snytt/issue/banner
Browse files Browse the repository at this point in the history
Opt-in REPL banner
  • Loading branch information
lrytz authored Sep 8, 2017
2 parents da959e8 + 8cb7920 commit e1e8d05
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 29 deletions.
14 changes: 12 additions & 2 deletions project/VersionUtil.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package scala.build

import sbt._
import sbt.{stringToProcess => _, _}
import Keys._
import java.util.{Date, Locale, Properties, TimeZone}
import java.io.{File, FileInputStream}
Expand All @@ -11,6 +11,7 @@ import BuildSettings.autoImport._

object VersionUtil {
lazy val copyrightString = settingKey[String]("Copyright string.")
lazy val shellWelcomeString = settingKey[String]("Shell welcome banner string.")
lazy val versionProperties = settingKey[Versions]("Version properties.")
lazy val gitProperties = settingKey[GitProperties]("Current git information")
lazy val buildCharacterPropertiesFile = settingKey[File]("The file which gets generated by generateBuildCharacterPropertiesFile")
Expand All @@ -27,6 +28,12 @@ object VersionUtil {

lazy val generatePropertiesFileSettings = Seq[Setting[_]](
copyrightString := "Copyright 2002-2017, LAMP/EPFL and Lightbend, Inc.",
shellWelcomeString := """
| ________ ___ / / ___
| / __/ __// _ | / / / _ |
| __\ \/ /__/ __ |/ /__/ __ |
| /____/\___/_/ |_/____/_/ | |
| |/ %s""".stripMargin.lines.drop(1).map(s => s"${ "%n" }${ s }").mkString,
resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue,
generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value
)
Expand Down Expand Up @@ -135,7 +142,10 @@ object VersionUtil {
}

private lazy val generateVersionPropertiesFileImpl: Def.Initialize[Task[File]] = Def.task {
writeProps(versionProperties.value.toMap + ("copyright.string" -> copyrightString.value),
writeProps(versionProperties.value.toMap ++ Seq(
"copyright.string" -> copyrightString.value,
"shell.welcome" -> shellWelcomeString.value
),
(resourceManaged in Compile).value / s"${thisProject.value.id}.properties")
}

Expand Down
43 changes: 23 additions & 20 deletions src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,38 +63,41 @@ s"""|Usage: $cmdName <options> [<script|class|object|jar> <arguments>]
""".stripMargin

override def usageMsg = f"""$shortUsageMsg
The first given argument other than options to $cmdName designates
what to run. Runnable targets are:
The first argument to $cmdName after the options designates what to run.

- a file containing scala source
- the name of a compiled class
- a runnable jar file with a valid Main-Class attribute
- or if no argument is given, the repl (interactive shell) is started
If no argument is given, the Scala REPL, an interactive shell, is started.

Options to $cmdName which reach the java runtime:
Otherwise, the Scala runner will try to run the named target, either as
a compiled class with a main method, a jar file with a Main-Class manifest
header, or as a Scala source file to compile and run.

-Dname=prop passed directly to java to set system properties
-J<arg> -J is stripped and <arg> passed to java as-is
-nobootcp do not put the scala jars on the boot classpath (slower)
The REPL accepts expressions to evaluate. Try `:help` to see more commands.

The script runner will invoke the main method of a top-level object if
it finds one; otherwise, the script code is run locally to a synthetic
main method with arguments available in a variable `args`.

Options to $cmdName which reach the Java runtime:

-Dname=prop passed directly to Java to set system properties
-J<arg> -J is stripped and <arg> passed to Java as-is
-nobootcp do not put the Scala jars on the boot classpath (slower)

Other startup options:

-howtorun what to run <script|object|jar|guess> (default: guess)
-i <file> preload <file> before starting the repl
-i <file> preload <file> before starting the REPL
-I <file> preload <file>, enforcing line-by-line interpretation
-e <string> execute <string> as if entered in the repl
-e <string> execute <string> as if entered in the REPL
-save save the compiled script in a jar for future use
-nc no compilation daemon: do not use the fsc offline compiler

A file argument will be run as a scala script unless it contains only
self-contained compilation units (classes and objects) and exactly one
runnable main method. In that case the file will be compiled and the
main method invoked. This provides a bridge between scripts and standard
scala source.
If the runner does not correctly guess how to run the target:

-howtorun what to run <script|object|jar|guess> (default: guess)

When running a script or using -e, an already running compilation daemon
(fsc) is used, or a new one started on demand. The -nc option can be
used to prevent this.%n"""
(fsc) is used, or a new one started on demand. Use the -nc option to
create a fresh compiler instead.%n"""
}

object GenericRunnerCommand {
Expand Down
2 changes: 2 additions & 0 deletions src/repl/scala/tools/nsc/interpreter/ILoop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) extend
}
line
}
} catch {
case t: Throwable => t.printStackTrace() ; scala.sys.exit(1)
} finally splash.stop()
}
this.settings = settings
Expand Down
2 changes: 1 addition & 1 deletion src/repl/scala/tools/nsc/interpreter/IMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@ object IMain {
def isStripping = isettings.unwrapStrings
def isTruncating = reporter.truncationOK

def stripImpl(str: String): String = naming.unmangle(str)
def stripImpl(str: String): String = if (isInitializeComplete) naming.unmangle(str) else str
}
private[interpreter] def defaultSettings = new Settings()
private[scala] def defaultOut = new NewLinePrintWriter(new ConsoleWriter, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class SplashLoop(reader: InteractiveReader, prompt: String) extends Runnable {
def start(): Unit = result.synchronized {
require(thread == null, "Already started")
thread = new Thread(this)
thread.setDaemon(true)
running = true
thread.start()
}
Expand Down
16 changes: 10 additions & 6 deletions src/repl/scala/tools/nsc/interpreter/ReplProps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
package scala.tools.nsc
package interpreter

import Properties.{ javaVersion, javaVmName, shellPromptString, shellWelcomeString,
versionString, versionNumberString }
import Properties.{javaVersion, javaVmName, shellPromptString, shellWelcomeString,
versionString, versionNumberString}
import scala.sys._
import Prop._
import java.util.{ Formattable, FormattableFlags, Formatter }
import java.util.{Formattable, FormattableFlags, Formatter}

class ReplProps {
private def bool(name: String) = BooleanProp.keyExists(name)
Expand Down Expand Up @@ -57,11 +57,15 @@ class ReplProps {
}
val continuePrompt = encolor(continueText)

// Next time.
//def welcome = enversion(Prop[String]("scala.repl.welcome") or shellWelcomeString)
// -Dscala.repl.welcome=banner uses shell.welcome property
def welcome = enversion {
val p = Prop[String]("scala.repl.welcome")
if (p.isSet) p.get else shellWelcomeString
if (p.isSet) p.get match {
case "banner" => shellWelcomeString
case text => text
} else
"""Welcome to Scala %1$#s (%3$s, Java %2$s).
|Type in expressions for evaluation. Or try :help.""".stripMargin
}

val pasteDelimiter = Prop[String]("scala.repl.here")
Expand Down

0 comments on commit e1e8d05

Please sign in to comment.