热键停止REPL?

时间:2012-08-08 21:22:37

标签: scala read-eval-print-loop

是否有热键可以停止/退出Scala REPL?

示例:我使用命令console从SBT启动Scala REPL,然后像无限循环那样做一些愚蠢的事情,并希望在不关闭shell的情况下结束REPL。类似 Ctrl + C Ctrl + D Ctrl + Z (这些都不起作用)。

更新 使用的操作系统:Windows 7 64位。

Ctrl + D 存在SBT和REPL,但 Ctrl + D 不会退出REPL我处于无休止的循环中,如

while(true) prinln("test")

有没有办法在不关闭shell的情况下使用热键退出无限循环?或者这是不可能的,因为REPL在循环结束之前不会对热键作出反应(当然,在这种情况下不会发生这种情况)?

2 个答案:

答案 0 :(得分:2)

以下适用于Scala 2.10.0-M6,但在2.9.2中,您可以在REPL电源模式下使用:wrap实现类似的功能。

假设REPL是通过sbt console从sbt开始的 - 不失一般性(否则你只需将ReplUtil类放在scala的类路径上)。假设以下类在类路径上,例如它的来源是src/main/scala/ReplUtil.scala

import java.util.concurrent.{Executors, ExecutorService, TimeoutException, TimeUnit}
import concurrent._

object ReplUtil {
  @volatile private var exec: ExecutorService = _
  @volatile private var threads = Set.empty[ Thread ]
  private def freshPool() { exec = Executors.newCachedThreadPool() }
  freshPool()

  private implicit def context = ExecutionContext.fromExecutorService( exec )

  def panic() {
    (new Thread {
      override def run() {
        try {
          exec.shutdownNow()
          exec.awaitTermination( 1, TimeUnit.SECONDS ) 
        } finally {
          val th = threads
          threads = Set.empty
          th.foreach( _.stop )
          freshPool()
        }
      }
    }).start()
  }    

  def spawn[T](t: => T) = {
    var futPrint = false
    val fut = future {
       val th = Thread.currentThread()
       threads += th
       val res = try { t } finally { threads -= th }
       if( futPrint ) println( "<calculation done>\n" + res )
       t
    }
    try {
      Await.result( fut, util.Duration( 4, TimeUnit.SECONDS )).toString
    } catch {
      case e: TimeoutException =>
        futPrint = true
        "<ongoing calculation>"
    }
  }
}

然后以下将激活半异步REPL:

$ sbt console
...
Welcome to Scala version 2.10.0-M6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_33).
...
scala> import ReplUtil.panic
import ReplUtil.panic

scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
...

scala> power.intp.setExecutionWrapper("ReplUtil.spawn")

scala> 2+2
res1: Int = 4

scala> Thread.sleep(6000); 33
<ongoing calculation>

scala> <calculation done>
res2: Int = 33

scala> while(true) { Thread.sleep(2000); println( "Zzz" )}
Zzz
Zzz
<ongoing calculation>
scala> panic

scala> [error] (pool-5-thread-1) java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
...
Caused by: java.lang.InterruptedException: sleep interrupted
...

答案 1 :(得分:0)

与该主题相关的

是一个有用的 Shift + D 键绑定,用于在eclipse scala工作表中退出程序的非终止计算。