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

Handling Interrupt Signals (e.g., Ctrl+C) in Select and Other Dialoguer Actions #294

Open
silentEAG opened this issue Dec 1, 2023 · 4 comments

Comments

@silentEAG
Copy link

using the latest version

dialoguer = { version = "0.11" }

using example-select, when everything operates as expected, it looks like this:

image

however, when I press Ctrl+C in Select, the following occurs:

image

This issue is not limited to the Select; it affects all actions that initially hide the cursor. The root of the problem seems to be the lack of a handler for keys like Ctrl+C.

Is it possible to provide a custom handler to manage these kinds of inputs? Any assistance or suggestions would be greatly appreciated.

@jht5945
Copy link

jht5945 commented Jan 13, 2024

I found a magic solution:

  1. add crate ctrlc, just cargo add ctrlc
  2. call ctrlc::set_handler before call dialoguer
let _ = ctrlc::set_handler(move || {
    // DO NOTHING
});
  1. process dialoguer error
use dialoguer::console::Term;
if dialoguer_result.is_err() {
    let _ = Term::stderr().show_cursor();
}

@mike-lloyd03
Copy link

Thanks for this. It is a much better solution for me with a clap program than showing the cursor in set_handler. My example:

fn main() -> anyhow::Result<()> {
    // Ignore SIGINT so we can handle it ourselves
    ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler");

    let app = App::parse();

    match &app.command {
        // Handle clap commands
    }
    .map_err(|e| {
        let _ = Term::stdout().show_cursor();
        e
    })
}

@mitsuhiko
Copy link
Collaborator

There are two challenges with dialoguer at the moment about this. The underlying console library is now quite decent at restoring terminal state in more cases, even in light of ctrl-c. However in dialoguer the cursor is explicitly hidden in many interactions which results in this sort of behavior.

It would be weird for console to try to install a ctrl-c handler though. One option would be to say the components do not hide the cursor but Term::read_key_no_cursor is added which is like read_key but does not show the cursor. This would result in similar behavior as we have today but it could safely restore the cursor in light of ctrl-c.

@mitsuhiko
Copy link
Collaborator

Playing with this a bit now I do wonder if it would not be a better solution to just provide a convenient way to reset the terminal on ctrl-c with a utility function.

fn main() -> anyhow::Result<()> {
    ctrlc::set_handler(|| console::reset_terminal(); };
    // ...
}

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

Successfully merging a pull request may close this issue.

4 participants