-
Notifications
You must be signed in to change notification settings - Fork 179
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
Add support for cancelling input with Escape #607
Comments
But rustyline has only normal and insert mode, no command line mode. |
Rebinding the Escape key works fine (you essentially make it the same as Ctrl-U) and behaves similarly to the command prompt on Windows -- you're probably running Windows if you want Escape to clear the line. |
But with Windows Terminal, you may have the same issue as on unix if we activate |
Probably yes, but without // On Windows, Esc clears the input buffer
#[cfg(target_family = "windows")]
rl.bind_sequence(
Event::KeySeq(smallvec![KeyEvent(KeyCode::Esc, Modifiers::empty())]),
EventHandler::Simple(Cmd::Kill(Movement::WholeBuffer)),
); So, as long as you're not requiring bracketed paste, mapping the Esc should be quite safe. With If it is just the Esc key, it will be |
I wasn't referring to vim-mode in Rustyline, just using vim as an example of a program that allows using Escape to cancel entering input in readline-like contexts. You can also use Escape to cancel entering a search pattern after pressing I understand that escapes are fundamentally ambiguous, but there are workarounds for that -- lots of programs allow configuring a timeout where, if no data is supplied after reading an Escape byte, it'll register as an Escape press. And those programs also often support setting that timeout to 0. I think the rough assumption is that you'll basically never read half an escape sequence, so if you ask to read 64 bytes, but only get a single escape byte back, it's pretty likely that's an actual Escape press. I tried binding a sequence, but it didn't seem to work: rustyline_editor.bind_sequence(
KeyEvent::new('\x1B', Modifiers::empty()),
Cmd::Interrupt,
); Using a different character -- just |
I think Escape is treated differently. You have to bind via: KeyEvent::KeySeq(smallvec![KeyEvent(KeyCode::Esc, Modifiers::empty())])
|
See https://docs.rs/rustyline/latest/rustyline/config/struct.Config.html#method.keyseq_timeout
This should work by either pressing Escape twice or modifying the default timeout. |
This does not work for me when using use rustyline::history::MemHistory;
use rustyline::Editor;
fn main() {
let editor_config = rustyline::config::Config::builder()
.behavior(rustyline::config::Behavior::PreferTerm)
.keyseq_timeout(0)
.build();
let mut editor = Editor::<(), MemHistory>::with_history(editor_config, MemHistory::default()).unwrap();
editor.bind_sequence(
rustyline::KeyEvent::new('\x1B', rustyline::Modifiers::empty()),
rustyline::Cmd::Interrupt,
);
let result = editor.readline("Enter first command: ");
println!("Initial input: {:?}", result);
} If I delete the I am unsure what the difference could be here (the code difference seems minuscule for |
I've dug more into this, and discovered the root cause. To detect single-escapes vs escape sequences, after reading a single Here are some blog posts that explain potential workarounds. I'm not sure how feasible it is to use one of these workarounds, but there may be a more straightforward solution when It seems like this scenario is already checked for debugging purposes? if key == E::ESC {
if !self.tty_in.buffer().is_empty() {
debug!(target: "rustyline", "read buffer {:?}", self.tty_in.buffer());
}
...
} I'm not sure if there's any simple workaround when I've made a PR to fix this here: #802 |
I think in certain contexts it make sense for
Escape
to cancel entering an input, similar to Ctrl-C or Ctrl-D. When entering a:
command in vim, for example, hitting escape will return you to normal mode.The text was updated successfully, but these errors were encountered: