really terrible backspace

parse-tree
Jordan Orelli 2 years ago
parent 893a38f694
commit 6c97ff2889

@ -178,8 +178,12 @@ impl Reader {
fn next_escape_sequence(&mut self) -> Result<Event> { fn next_escape_sequence(&mut self) -> Result<Event> {
self.take_bracket()?; self.take_bracket()?;
match self.next_escape_char()? { match self.next_escape_char()? {
'D' => Ok(Event::Left), 'A' => Ok(Event::Up),
'B' => Ok(Event::Down),
'C' => Ok(Event::Right), 'C' => Ok(Event::Right),
'D' => Ok(Event::Left),
'H' => Ok(Event::Home),
'F' => Ok(Event::End),
e => Err(Error::input_error(format!("unexpected escape char: {}", e)).into()), e => Err(Error::input_error(format!("unexpected escape char: {}", e)).into()),
} }
} }
@ -229,6 +233,10 @@ pub enum Event {
Size, Size,
Left, Left,
Right, Right,
Up,
Down,
Home,
End,
} }
const ALT_KEYS: u32 = 0x0002 | 0x0001; const ALT_KEYS: u32 = 0x0002 | 0x0001;
@ -255,10 +263,15 @@ impl From<Console::INPUT_RECORD> for Event {
let mstate = event.dwControlKeyState; let mstate = event.dwControlKeyState;
let c = char::from_u32(event.uChar.UnicodeChar as u32).unwrap_or('💀'); let c = char::from_u32(event.uChar.UnicodeChar as u32).unwrap_or('💀');
if event.bKeyDown.as_bool() {
debug!("key down {}", event.wVirtualKeyCode);
} else {
debug!("key up {}", event.wVirtualKeyCode);
}
Event::Key(key::Event { Event::Key(key::Event {
down: event.bKeyDown.as_bool(), down: event.bKeyDown.as_bool(),
repeats: event.wRepeatCount, repeats: event.wRepeatCount,
code: event.wVirtualKeyCode, code: key::CODES[event.wVirtualKeyCode as usize],
alt: mstate & ALT_KEYS > 0, alt: mstate & ALT_KEYS > 0,
ctrl: mstate & CTRL_KEYS > 0, ctrl: mstate & CTRL_KEYS > 0,
shift: mstate & SHIFT_PRESSED > 0, shift: mstate & SHIFT_PRESSED > 0,

@ -1,4 +1,13 @@
type Code = u16; // type Code = u16;
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Code {
/// The integer value of the keycode
pub val: u16,
/// The unicode symbol that represents the keycode, if any
pub sym: Option<char>,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Event { pub struct Event {
@ -26,54 +35,35 @@ pub struct Event {
impl Event {} impl Event {}
impl std::fmt::Display for Event { /// CODES contains a lookup table for key codes. Note that this is a sparse array and not all
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { /// values associate to valid key codes.
if self.shift { pub static CODES: [Code; 256] = gen_codes();
if self.ctrl {
if self.alt { macro_rules! keycodes {
// write!(f, "⇧⎈⎇ {}", self.char) ($($val:literal $name:ident $sym:literal)*) => {
write!(f, "<S-C-A-{}>", self.char) const fn gen_codes() -> [Code; 256] {
} else { let mut codes = [Code{val: 0, sym: None}; 256];
// write!(f, "⇧⎈ {}", self.char) let mut i = 0 as usize;
write!(f, "<S-C-{}>", self.char) while i < 256 {
} codes[i] = Code{val: i as u16, sym: None};
} else { i = i + 1;
if self.alt {
// write!(f, "⇧⎇ {}", self.char)
write!(f, "<S-A-{}>", self.char)
} else {
write!(f, "<S-{}>", self.char)
}
}
} else {
if self.ctrl {
if self.alt {
// write!(f, "⎈⎇ {}", self.char)
write!(f, "<C-A-{}>", self.char)
} else {
// write!(f, "⎈ {}", self.char)
write!(f, "<C-{}>", self.char)
}
} else {
if self.alt {
// write!(f, "⎇ {}", self.char)
write!(f, "<A-{}>", self.char)
} else {
write!(f, "{}", self.char)
}
}
}
} }
$(
codes[$val] = Code{val: $val, sym: Some($sym)};
)*
codes
} }
macro_rules! keycodes { $(
($($c:literal $n:ident $x:literal)*) => {$(
#[allow(dead_code)] #[allow(dead_code)]
pub const $n: Code = $c; pub const $name: Code = Code{val: $val, sym: Some($sym)};
)*}; )*
}
} }
keycodes! { keycodes! {
0x07 NOTBACKSPACE '⌫'
0x08 BACKSPACE '⌫' 0x08 BACKSPACE '⌫'
0x09 TAB '↹' 0x09 TAB '↹'
// 0x0A-0B Reserved // 0x0A-0B Reserved

@ -46,6 +46,16 @@ impl Line {
} }
} }
pub fn backspace(&mut self) -> bool {
if self.cursor > 0 {
self.cursor -= 1;
self.chars.remove(self.cursor);
true
} else {
false
}
}
pub fn forward(&mut self) -> bool { pub fn forward(&mut self) -> bool {
if self.cursor < self.chars.len() { if self.cursor < self.chars.len() {
self.cursor += 1; self.cursor += 1;

@ -163,7 +163,6 @@ fn main() -> Result<()> {
loop { loop {
match input.next()? { match input.next()? {
input::Event::Key(event) => { input::Event::Key(event) => {
debug!("Key Event: {}", event);
if event.down { if event.down {
continue; continue;
} }
@ -177,6 +176,34 @@ fn main() -> Result<()> {
continue; continue;
} }
if event.code == key::TAB {
continue;
}
if event.code == key::BACKSPACE {
if line.backspace() {
let text = format!("\x1b[2D");
unsafe {
Error::check(Console::WriteConsoleA(stdout, text.as_bytes(), None, None))?;
}
let tail = format!("{} ", line.tail());
let n = tail.chars().count();
unsafe {
Error::check(Console::WriteConsoleA(
stdout,
tail.as_bytes(),
None,
None,
))?;
}
let text = format!("\x1b[1D");
unsafe {
Error::check(Console::WriteConsoleA(stdout, text.as_bytes(), None, None))?;
}
}
continue;
}
if event.ctrl && event.code == key::D { if event.ctrl && event.code == key::D {
unsafe { unsafe {
CloseHandle(stdout); CloseHandle(stdout);
@ -185,8 +212,8 @@ fn main() -> Result<()> {
} }
if event.ctrl && event.code == key::J { if event.ctrl && event.code == key::J {
// red bullet
unsafe { unsafe {
// red bullet
let text = "\x1b[31m\u{2022}\x1b[0m"; let text = "\x1b[31m\u{2022}\x1b[0m";
Error::check(Console::WriteConsoleA(stdout, text.as_bytes(), None, None))?; Error::check(Console::WriteConsoleA(stdout, text.as_bytes(), None, None))?;
} }
@ -220,7 +247,7 @@ fn main() -> Result<()> {
continue; continue;
} }
debug!("Unhandled Keyboard Event: {}", event); debug!("Unhandled Keyboard Event: {:?}", event.code);
} }
input::Event::Left => { input::Event::Left => {
if line.back() { if line.back() {
@ -238,6 +265,10 @@ fn main() -> Result<()> {
} }
} }
} }
input::Event::Up => {},
input::Event::Down => {},
input::Event::Home => {},
input::Event::End => {},
input::Event::Focus(true) => {}, input::Event::Focus(true) => {},
input::Event::Focus(false) => {}, input::Event::Focus(false) => {},
input::Event::Menu(_command_id) => {}, input::Event::Menu(_command_id) => {},

Loading…
Cancel
Save