Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REPL Ctrl-C behaviour suggestion #6302

Open
scabug opened this issue Aug 31, 2012 · 9 comments
Open

REPL Ctrl-C behaviour suggestion #6302

scabug opened this issue Aug 31, 2012 · 9 comments

Comments

@scabug
Copy link

scabug commented Aug 31, 2012

From my scala-internals post (https://groups.google.com/d/msg/scala-internals/PqK6GkZhJK0/xjZw3wQ4wYEJ), verbatim:

Ideally, the function of Ctrl-C should depend on whether the REPL is waiting for user input, or running something in the foreground.

Waiting at a prompt, my preference would be:

  • If there's no text entered at the prompt, print a message like "(interrupt) type :quit or Ctrl-D to exit"
    • it's handy to trap Ctrl-C here, because people often press it repeatedly without intending to completely exit their current activity--mysql client, I'm looking at you
  • If there is text entered, discard it and bring up a new, empty prompt--this is what bash does.

With a foreground task running, ideally Ctrl-C should kill the task and return control to the REPL. I guess this implies running each command in a separate thread from the REPL itself, so it can be forcibly stopped—but of course, this doesn't necessarily imply starting a new thread for each command—we could just keep one of them around to run user code in—until it dies, only then we start a new one.

As for the mechanics of stopping the task, so long as we're baking pie in the sky...

while (!thread.isDead) {
  thread.youShouldExitNow() // presumably this is a custom thread class
  thread.interrupt()
  Thread.sleep(n) // say 2-5 seconds
  if (!thread.isDead) {
    val yn = prompt "The thread hasn't exited yet. Should we try to forcibly stop it?"
    if (yn == "y") {
      thread.stop()
    } 
  }
}

If anything is running in the background, may FSM have mercy on its soul. Out of scope. :)

If we felt like being clever, we could rewrite any line that has a looping construct at the root of its tree to be breakable. If it's a method call that loops, well, too bad.

@scabug
Copy link
Author

scabug commented Aug 31, 2012

Imported From: https://issues.scala-lang.org/browse/SI-6302?orig=1
Reporter: @acruise

@scabug
Copy link
Author

scabug commented Sep 6, 2014

Chip Senkbeil (senkwich) said:
I take it that this was never pursued. With JDK 8 (Oracle) officially disabling Thread.stop, the above would be trimmed down to just attempting an interrupt (hoping the code is interruptible). Cancelling a run doesn't seem to do anything to break out of long-running code.

Like the description says, you could rewrite looping constructs to be interruptible, but that doesn't do anything for external code being referenced inside the REPL.

Just seems like something that would be nice to have, but maybe it's too much to ask for.

@scabug
Copy link
Author

scabug commented Sep 6, 2014

@paulp said:
Nope, Thread.stop is still available. That refers to the "Thread.stop(Throwable)" version, but not the no argument form.

@scabug
Copy link
Author

scabug commented Sep 7, 2014

Chip Senkbeil (senkwich) said:
I thought the no argument form was just a wrapper for Thread.stop(Throwable) with an argument of ThreadDeath?

In JDK 7, this was what I found when browsing JDK 1.7:

public final void stop() {
    stop(new ThreadDeath());
}

@scabug
Copy link
Author

scabug commented Sep 7, 2014

@paulp said:
I verified Thread.stop works on 1.8.0_20 before I commented.

@scabug
Copy link
Author

scabug commented Apr 19, 2015

Li Haoyi (lihaoyi) said:
This is fixed in the Ammonite REPL

[info] Running ammonite.repl.Repl
Loading Ammonite Repl...
@ while(true) ()

Interrupted!
@

@SethTisue SethTisue added this to the Backlog milestone Mar 3, 2018
@vegerot
Copy link

vegerot commented Dec 1, 2019

Hey guys 👋, it's 2019 and this still hasn't been addressed yet. Seems like Alex's proposed behavior for ctrl-c is very reasonable and conforms well with the Unix standards. Is there a reason this hasn't been added yet?

@SethTisue
Copy link
Member

@vegerot no one has submitted a pull request

@scala scala deleted a comment from scabug Dec 1, 2019
@scala scala deleted a comment from scabug Dec 1, 2019
@bjornregnell
Copy link

@vegerot @SethTisue See also recent discussion here: https://users.scala-lang.org/t/c-ctrl-c-closes-repl-expression-interpreter-interactive-loop/7187/13

I just made this feature suggestion for the Scala 3 REPL here:
lampepfl/dotty-feature-requests#188

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants