diff --git a/src/keys.rs b/src/keys.rs index bf066368f1..9883b81fca 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -24,6 +24,8 @@ pub enum KeyPress { ControlRight, /// Ctrl-↑ ControlUp, + /// Control Backspace (may not be able to be used on unix) + ControlBackspace, /// Ctrl-char Ctrl(char), /// ⌦ @@ -46,6 +48,8 @@ pub enum KeyPress { Left, /// Escape-char or Alt-char Meta(char), + /// Alt Backspace + MetaBackspace, /// `KeyPress::Char('\0')` Null, /// ⇟ @@ -54,6 +58,8 @@ pub enum KeyPress { PageUp, /// → arrow key Right, + /// Shift Backspace + ShiftBackspace, /// Shift-↓ ShiftDown, /// Shift-← diff --git a/src/lib.rs b/src/lib.rs index 9caa9559c4..303fd44c75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ use std::path::Path; use std::result; use std::sync::{Arc, Mutex, RwLock}; -use log::debug; +use log::{warn, debug}; use unicode_width::UnicodeWidthStr; use crate::tty::{RawMode, Renderer, Term, Terminal}; @@ -888,7 +888,21 @@ impl Editor { /// Bind a sequence to a command. pub fn bind_sequence(&mut self, key_seq: KeyPress, cmd: Cmd) -> Option { if let Ok(mut bindings) = self.custom_bindings.write() { - bindings.insert(key_seq, cmd) + let key = if let KeyPress::Char(ref c) = key_seq { + if c.is_control() { + keys::char_to_key_press(*c) + } else { + key_seq + } + } else if let KeyPress::Ctrl(ref c) = key_seq { + if c.is_control() { + warn!(target: "rustyline", "KeyPress::Ctrl({:?}) will not work on unix", c) + } + key_seq + } else { + key_seq + }; + bindings.insert(key, cmd) } else { None } diff --git a/src/tty/windows.rs b/src/tty/windows.rs index ea499c7c25..8196ce0309 100644 --- a/src/tty/windows.rs +++ b/src/tty/windows.rs @@ -219,14 +219,23 @@ impl RawReader for ConsoleRawReader { return Err(error::ReadlineError::Eof); }; let c = rc?; + let mut key = keys::char_to_key_press(c); if meta { - return Ok(KeyPress::Meta(c)); + if key == KeyPress::Backspace { + key = KeyPress::MetaBackspace; + } else { + key = KeyPress::Meta(c); + } + return Ok(key); } else { - let mut key = keys::char_to_key_press(c); if key == KeyPress::Tab && shift { key = KeyPress::BackTab; } else if key == KeyPress::Char(' ') && ctrl { key = KeyPress::Ctrl(' '); + } else if key == KeyPress::Backspace && ctrl { + key = KeyPress::ControlBackspace; + } else if key == KeyPress::Backspace && shift { + key = KeyPress::ShiftBackspace; } return Ok(key); }