@@ -211,16 +211,44 @@ class ReplDriver(settings: Array[String],
211211 val line = terminal.readLine(completer)
212212 ParseResult (line)
213213 } catch {
214- case _ : EndOfFileException |
215- _ : UserInterruptException => // Ctrl+D or Ctrl+C
214+ case _ : EndOfFileException => // Ctrl+D
216215 Quit
216+ case _ : UserInterruptException => // Ctrl+C at prompt - clear and continue
217+ SigKill
217218 }
218219 }
219220
220221 @ tailrec def loop (using state : State )(): State = {
222+
221223 val res = readLine()
222224 if (res == Quit ) state
223- else loop(using interpret(res))()
225+ // Ctrl-C pressed at prompt - just continue with same state (line is cleared by JLine)
226+ else if (res == SigKill ) loop(using state)()
227+ else {
228+ // Set up interrupt handler for command execution
229+ var firstCtrlCEntered = false
230+ val thread = Thread .currentThread()
231+ val previousSignalHandler = terminal.handle(
232+ org.jline.terminal.Terminal .Signal .INT ,
233+ (sig : org.jline.terminal.Terminal .Signal ) => {
234+ if (! firstCtrlCEntered) {
235+ firstCtrlCEntered = true
236+ thread.interrupt()
237+ out.println(" \n Interrupting running thread, Ctrl-C again to terminate the REPL Process" )
238+ } else {
239+ out.println(" \n Terminating REPL Process..." )
240+ System .exit(130 ) // Standard exit code for SIGINT
241+ }
242+ }
243+ )
244+
245+ val newState =
246+ try interpret(res)
247+ // Restore previous handler
248+ finally terminal.handle(org.jline.terminal.Terminal .Signal .INT , previousSignalHandler)
249+
250+ loop(using newState)()
251+ }
224252 }
225253
226254 try runBody { loop() }
0 commit comments