@@ -211,16 +211,44 @@ class ReplDriver(settings: Array[String],
211
211
val line = terminal.readLine(completer)
212
212
ParseResult (line)
213
213
} catch {
214
- case _ : EndOfFileException |
215
- _ : UserInterruptException => // Ctrl+D or Ctrl+C
214
+ case _ : EndOfFileException => // Ctrl+D
216
215
Quit
216
+ case _ : UserInterruptException => // Ctrl+C at prompt - clear and continue
217
+ SigKill
217
218
}
218
219
}
219
220
220
221
@ tailrec def loop (using state : State )(): State = {
222
+
221
223
val res = readLine()
222
224
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
+ }
224
252
}
225
253
226
254
try runBody { loop() }
0 commit comments