How to not have Gradle quit Scala's REPL immediately? - scala

These simple lines in build.gradle expose a repl task that would ideally fire up a scala REPL. Fire up and keep alive that is. After the repl loads, it immediately receives a :quit command and exits.
Important parts of build.gradle:
dependencies{
compile "org.scala-lang:scala-library:2.11.7"
compile "org.scala-lang:scala-compiler:2.11.7"
}
task repl(type:JavaExec) {
main = "scala.tools.nsc.MainGenericRunner"
classpath = sourceSets.main.runtimeClasspath
}
Launching the REPL:
% gradle repl
:compileJava UP-TO-DATE
:compileScala UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:repl
Welcome to Scala version 2.11.7 (OpenJDK Server VM, Java 1.7.0_91).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :quit
BUILD SUCCESSFUL
Total time: 31.177 secs
REPL quits automatically immediately after launching. How to not have the REPL quit immediately?

You also need to redirect console input to your javaexec java process. Try adding standardInput System.in to your task definition. In my case, I also found it necessary to add args '-userjavacp'.
task repl(type:JavaExec) {
main = "scala.tools.nsc.MainGenericRunner"
classpath = sourceSets.main.runtimeClasspath
standardInput System.in
args '-usejavacp'
}
and finally running gradle with the -q option suppresses the gradle progress prompts giving me a cleaner scala repl.

Related

Is there a command to reload the sbt project while inside the sbt console of a project?

I run sbt console within a scala project and can use all the code within the project in the REPL. If I make any code changes though, I need to exit the console (Ctrl + C) and run sbt console again to load the changes. Is there a way to simply reload code changes without exiting and starting up a new sbt console?
If you're in sbt console you can't reload project, but you can exit repl printing :q but not exit sbt. After that you don't need exit from sbt you can enter reload command and sbt will reload project without exiting from sbt. But you need again type console for open REPL.
Another words, you can do followings:
sbt
console
*print some code in REPL*
*change sbt project*
:q
reload
*you will see sbt project changes does affect*
console
you will lost last REPL session objects and references but you will not load sbt project from scratch, reload is faster than another sbt starting.

How to display project-specific message at the beginning of an sbt shell session?

I'd like to display a project-specific message at the start of an sbt (not Scala) session, similar to the one displayed when starting up the Scala REPL. It would be some sort of help message, but for commands or flows that are specific to that project.
$ scala
Welcome to Scala 2.12.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.
scala>
Is there a built-in way to do this or an sbt plugin for it? If not, how else can I achieve this?
You can define a dummy setting value as a way to access the SBT logger.
val welcomeMessage = settingKey[Unit]("Welcome message")
welcomeMessage := {
sLog.value.info("<some message here>")
}
Note:
this message will be displayed whenever SBT is run, not just when calling it to get to the SBT prompt.
it's may not be the last message to be displayed
If the desire is to show a message when accessing the Scala console rather than the SBT prompt then there is more direct support. The initialCommands setting allows you to set a snippet of code that is run when the Scala console is first entered which could include printing some messages.
SBT docs

Scala REPL in Gradle

At the moment Gradle's scala integration does not offer REPL functionality. How to ergonomically run a Scala REPL from Gradle with the appropriate classpath?
Minimal build.gradle:
apply plugin: 'scala'
repositories{
mavenCentral()
}
dependencies{
compile "org.scala-lang:scala-library:2.11.7"
compile "org.scala-lang:scala-compiler:2.11.7"
}
task repl(type:JavaExec) {
main = "scala.tools.nsc.MainGenericRunner"
classpath = sourceSets.main.runtimeClasspath
standardInput System.in
args '-usejavacp'
}
Credit to this answer for explaining how to direct stdin with standardInput and have REPL use the right classpath with args.
Notice the scala-compiler library is a dependency. That's where scala.tools.nsc.MainGenericRunner is found.
From the console a number of options are needed to run the REPL:
--no-daemon, if you are using a Gradle daemon. At the moment, the REPL does not respond to keystrokes if run from the daemon.
--console plain. A popular, but inferior alternative is --quiet. If run without one of these options, REPL's prompt is contaminated by Gradle's progress report. --console plain has the advantage that it also adjusts readline's behaviour so that rlwrap is unnecessary.
Full command to run the REPL is gradle repl --console plain --no-daemon, so creating an alias in your shell makes sense.

Can you start a Scala REPL in SBT when compilation is broken?

When your project doesn't compile, can you start a Scala REPL in SBT? using sbt console SBT seems to first compile the project and exit in this case. However the console could help experiment for solving the compilation trouble....
consoleQuick is an SBT task that starts a REPL with the same classpath as console but without forcing compilation. (It is described alongside similar tasks by the sbt tasks command).

How to quit scala 2.11.0 REPL?

In the last version of scala (2.10.3) REPL, I can type exit to quit from REPL. However, in Scala 2.11.0 this doesn't work.
$ scala
Welcome to Scala version 2.11.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala> exit
<console>:8: error: not found: value exit
exit
^
scala>
I ran into the same issue on upgrade, just use colon q.
:q
Additionally, exit was deprecated in 2.10.x with sys.exit suggested instead, so this works as well:
sys.exit
As a side note, I think they did this so you can distinguish between exiting the scala console in sbt and exiting sbt itself, though I could be wrong.
You options to leave the REPL as stated in the answers before are:
:quit
:q
Ctrl + d // Unix
Ctrl + z // Windows
sys.exit
Use the end of file characters. Ctrl-D on linux, Ctrl-Z on Windows.
Using the :help command on my 2.10.3 REPL gets me this hint:
:quit exit the interpreter
I don't know whether :quit is still there in 2.11.0 or not though.
When I use exit in 2.10.4, I got a warning:
warning: there were 1 deprecation warning(s); re-run with -deprecation for details
You can use:
:q
:quit
sys.exit
all of them work in 2.11.x.
You can use
sys.exit
OR
:q
to exit the shell
For sbt 1.4.1 commands use below command
exit:Terminates the remote client or the build when called from the console.
shutdown:Terminates the build.
Example
vudikeri#C02CP3LAMD6M scala % sbt version
[info] welcome to sbt 1.4.1 (N/A Java 14.0.1)
sbt:scala> shutdown
[info] shutting down sbt server
vudikeri#C02CP3LAMD6M scala %
sbt:scala> exit
[info] shutting down sbt server