From 3b27390ccd4fbdd1e79e9a94a7d2e1eb952798ed Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Tue, 10 Dec 2019 12:42:02 -0800 Subject: [PATCH] better keybindings --- src/keybindings.rs | 141 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/window.rs | 76 +++--------------------- 3 files changed, 149 insertions(+), 69 deletions(-) create mode 100644 src/keybindings.rs diff --git a/src/keybindings.rs b/src/keybindings.rs new file mode 100644 index 0000000..12490f9 --- /dev/null +++ b/src/keybindings.rs @@ -0,0 +1,141 @@ +use std::fmt; + +use skulpin::winit::event::{KeyboardInput, ElementState, ModifiersState, VirtualKeyCode}; + +fn parse_keycode(keycode: VirtualKeyCode) -> Option<(String, bool)> { + match keycode { + VirtualKeyCode::Key1 => Some(("1".to_string(), false)), + VirtualKeyCode::Key2 => Some(("2".to_string(), false)), + VirtualKeyCode::Key3 => Some(("3".to_string(), false)), + VirtualKeyCode::Key4 => Some(("4".to_string(), false)), + VirtualKeyCode::Key5 => Some(("5".to_string(), false)), + VirtualKeyCode::Key6 => Some(("6".to_string(), false)), + VirtualKeyCode::Key7 => Some(("7".to_string(), false)), + VirtualKeyCode::Key8 => Some(("8".to_string(), false)), + VirtualKeyCode::Key9 => Some(("9".to_string(), false)), + VirtualKeyCode::Key0 => Some(("0".to_string(), false)), + VirtualKeyCode::A => Some(("a".to_string(), false)), + VirtualKeyCode::B => Some(("b".to_string(), false)), + VirtualKeyCode::C => Some(("c".to_string(), false)), + VirtualKeyCode::D => Some(("d".to_string(), false)), + VirtualKeyCode::E => Some(("e".to_string(), false)), + VirtualKeyCode::F => Some(("f".to_string(), false)), + VirtualKeyCode::G => Some(("g".to_string(), false)), + VirtualKeyCode::H => Some(("h".to_string(), false)), + VirtualKeyCode::I => Some(("i".to_string(), false)), + VirtualKeyCode::J => Some(("j".to_string(), false)), + VirtualKeyCode::K => Some(("k".to_string(), false)), + VirtualKeyCode::L => Some(("l".to_string(), false)), + VirtualKeyCode::M => Some(("m".to_string(), false)), + VirtualKeyCode::N => Some(("n".to_string(), false)), + VirtualKeyCode::O => Some(("o".to_string(), false)), + VirtualKeyCode::P => Some(("p".to_string(), false)), + VirtualKeyCode::Q => Some(("q".to_string(), false)), + VirtualKeyCode::R => Some(("r".to_string(), false)), + VirtualKeyCode::S => Some(("s".to_string(), false)), + VirtualKeyCode::T => Some(("t".to_string(), false)), + VirtualKeyCode::U => Some(("u".to_string(), false)), + VirtualKeyCode::V => Some(("v".to_string(), false)), + VirtualKeyCode::W => Some(("w".to_string(), false)), + VirtualKeyCode::X => Some(("x".to_string(), false)), + VirtualKeyCode::Y => Some(("y".to_string(), false)), + VirtualKeyCode::Z => Some(("z".to_string(), false)), + VirtualKeyCode::Escape => Some(("ESC".to_string(), true)), + VirtualKeyCode::F1 => Some(("F1".to_string(), true)), + VirtualKeyCode::F2 => Some(("F2".to_string(), true)), + VirtualKeyCode::F3 => Some(("F3".to_string(), true)), + VirtualKeyCode::F4 => Some(("F4".to_string(), true)), + VirtualKeyCode::F5 => Some(("F5".to_string(), true)), + VirtualKeyCode::F6 => Some(("F6".to_string(), true)), + VirtualKeyCode::F7 => Some(("F7".to_string(), true)), + VirtualKeyCode::F8 => Some(("F8".to_string(), true)), + VirtualKeyCode::F9 => Some(("F9".to_string(), true)), + VirtualKeyCode::F10 => Some(("F10".to_string(), true)), + VirtualKeyCode::F11 => Some(("F11".to_string(), true)), + VirtualKeyCode::F12 => Some(("F12".to_string(), true)), + VirtualKeyCode::F13 => Some(("F13".to_string(), true)), + VirtualKeyCode::F14 => Some(("F14".to_string(), true)), + VirtualKeyCode::F15 => Some(("F15".to_string(), true)), + VirtualKeyCode::F16 => Some(("F16".to_string(), true)), + VirtualKeyCode::F17 => Some(("F17".to_string(), true)), + VirtualKeyCode::F18 => Some(("F18".to_string(), true)), + VirtualKeyCode::F19 => Some(("F19".to_string(), true)), + VirtualKeyCode::F20 => Some(("F20".to_string(), true)), + VirtualKeyCode::F21 => Some(("F21".to_string(), true)), + VirtualKeyCode::F22 => Some(("F22".to_string(), true)), + VirtualKeyCode::F23 => Some(("F23".to_string(), true)), + VirtualKeyCode::F24 => Some(("F24".to_string(), true)), + VirtualKeyCode::Insert => Some(("Insert".to_string(), true)), + VirtualKeyCode::Home => Some(("Home".to_string(), true)), + VirtualKeyCode::Delete => Some(("Delete".to_string(), true)), + VirtualKeyCode::End => Some(("End".to_string(), true)), + VirtualKeyCode::PageDown => Some(("PageDown".to_string(), true)), + VirtualKeyCode::PageUp => Some(("PageUp".to_string(), true)), + VirtualKeyCode::Left => Some(("Left".to_string(), true)), + VirtualKeyCode::Up => Some(("Up".to_string(), true)), + VirtualKeyCode::Right => Some(("Right".to_string(), true)), + VirtualKeyCode::Down => Some(("Down".to_string(), true)), + VirtualKeyCode::Back => Some(("BS".to_string(), true)), + VirtualKeyCode::Return => Some(("Enter".to_string(), true)), + VirtualKeyCode::Space => Some(("Space".to_string(), true)), + VirtualKeyCode::Apostrophe => Some(("'".to_string(), false)), + VirtualKeyCode::Backslash => Some(("Bslash".to_string(), true)), + VirtualKeyCode::Colon => Some((":".to_string(), false)), + VirtualKeyCode::Comma => Some((",".to_string(), false)), + VirtualKeyCode::Decimal => Some((".".to_string(), false)), + VirtualKeyCode::Divide => Some(("/".to_string(), false)), + VirtualKeyCode::Equals => Some(("=".to_string(), false)), + VirtualKeyCode::Minus => Some(("-".to_string(), false)), + VirtualKeyCode::Semicolon => Some((";".to_string(), false)), + _ => None + } +} + +fn append_modifiers(modifiers: ModifiersState, keycode_text: String, special: bool) -> String { + let mut result = keycode_text; + let mut special = special; + + if modifiers.shift { + result = match result.as_ref() { + "," => "<".to_string(), + "." => ">".to_string(), + ";" => ":".to_string(), + other => { + special = true; + format!("S-{}", result) + } + }; + } + if modifiers.ctrl { + result = format!("C-{}", result); + } + if modifiers.alt { + result = format!("M-{}", result); + } + if modifiers.logo { + result = format!("D-{}", result); + } + if special { + result = format!("<{}>", result); + } + + result +} + +pub fn construct_keybinding_string(input: KeyboardInput) -> Option { + match input { + KeyboardInput { + state: ElementState::Pressed, + virtual_keycode: Some(keycode), + modifiers, + .. + } => { + if let Some((keycode_text, special)) = parse_keycode(keycode) { + Some(append_modifiers(modifiers, keycode_text, special)) + } else { + None + } + }, + _ => None + } +} diff --git a/src/main.rs b/src/main.rs index 13b9e10..a4c2104 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ mod editor; mod window; +mod keybindings; #[macro_use] extern crate derive_new; diff --git a/src/window.rs b/src/window.rs index 12cb3bd..4eab1df 100644 --- a/src/window.rs +++ b/src/window.rs @@ -13,6 +13,7 @@ use skulpin::winit::window::WindowBuilder; use neovim_lib::NeovimApi; use crate::editor::{DrawCommand, Editor, Colors}; +use crate::keybindings::construct_keybinding_string; const FONT_NAME: &str = "Delugia Nerd Font"; const FONT_SIZE: f32 = 14.0; @@ -24,13 +25,10 @@ const FONT_HEIGHT: f32 = 16.4; fn draw( editor: &Arc>, - canvas: &mut Canvas, - _coordinate_system_helper: &CoordinateSystemHelper + canvas: &mut Canvas ) { - let typeface = Typeface::new(FONT_NAME, FontStyle::default()).expect("Could not load font file."); let font = Font::from_typeface(typeface, FONT_SIZE); - let paint = Paint::new(Color4f::new(0.0, 1.0, 1.0, 1.0), None); // let shaper = Shaper::new(None); // if let Some((blob, _)) = shaper.shape_text_blob("This is a test ~==", font, false, 10000.0, Point::default()) { @@ -44,8 +42,6 @@ fn draw( canvas.clear(default_colors.background.clone().unwrap().to_color()); - canvas.draw_str("This is a test!", (50, 50), &font, &paint); - for command in draw_commands { let x = command.col_start as f32 * FONT_WIDTH; let y = command.row as f32 * FONT_HEIGHT + FONT_HEIGHT; @@ -114,71 +110,13 @@ pub fn ui_loop(editor: Arc>) { Event:: WindowEvent { event: WindowEvent::KeyboardInput { - input: KeyboardInput { - state: ElementState::Pressed, - virtual_keycode: Some(keycode), - .. - }, + input, .. }, .. } => { - let possible_string = match keycode { - VirtualKeyCode::A => Some("a"), - VirtualKeyCode::B => Some("b"), - VirtualKeyCode::C => Some("c"), - VirtualKeyCode::D => Some("d"), - VirtualKeyCode::E => Some("e"), - VirtualKeyCode::F => Some("f"), - VirtualKeyCode::G => Some("g"), - VirtualKeyCode::H => Some("h"), - VirtualKeyCode::I => Some("i"), - VirtualKeyCode::J => Some("j"), - VirtualKeyCode::K => Some("k"), - VirtualKeyCode::L => Some("l"), - VirtualKeyCode::M => Some("m"), - VirtualKeyCode::N => Some("n"), - VirtualKeyCode::O => Some("o"), - VirtualKeyCode::P => Some("p"), - VirtualKeyCode::Q => Some("q"), - VirtualKeyCode::R => Some("r"), - VirtualKeyCode::S => Some("s"), - VirtualKeyCode::T => Some("t"), - VirtualKeyCode::U => Some("u"), - VirtualKeyCode::V => Some("v"), - VirtualKeyCode::W => Some("w"), - VirtualKeyCode::X => Some("x"), - VirtualKeyCode::Y => Some("y"), - VirtualKeyCode::Z => Some("z"), - VirtualKeyCode::Escape => Some(""), - VirtualKeyCode::Back => Some(""), - VirtualKeyCode::Space => Some(""), - VirtualKeyCode::Return => Some(""), - VirtualKeyCode::Up => Some(""), - VirtualKeyCode::Down => Some(""), - VirtualKeyCode::Left => Some(""), - VirtualKeyCode::Right => Some(""), - VirtualKeyCode::LShift => Some(""), - VirtualKeyCode::RShift => Some(""), - VirtualKeyCode::Key1 => Some("1"), - VirtualKeyCode::Key2 => Some("2"), - VirtualKeyCode::Key3 => Some("3"), - VirtualKeyCode::Key4 => Some("4"), - VirtualKeyCode::Key5 => Some("5"), - VirtualKeyCode::Key6 => Some("6"), - VirtualKeyCode::Key7 => Some("7"), - VirtualKeyCode::Key8 => Some("8"), - VirtualKeyCode::Key9 => Some("9"), - VirtualKeyCode::Key0 => Some("0"), - VirtualKeyCode::Insert => Some(""), - VirtualKeyCode::Home => Some(""), - VirtualKeyCode::Delete => Some(""), - VirtualKeyCode::End => Some(""), - _ => None - }; - - if let Some(string) = possible_string { - editor.lock().unwrap().nvim.input(string).expect("Input call failed..."); + if let Some(string) = construct_keybinding_string(input) { + editor.lock().unwrap().nvim.input(&string).expect("Input call failed..."); } }, @@ -191,8 +129,8 @@ pub fn ui_loop(editor: Arc>) { event: WindowEvent::RedrawRequested, .. } => { - if let Err(e) = renderer.draw(&window, |canvas, coordinate_system_helper| { - draw(&editor, canvas, coordinate_system_helper); + if let Err(e) = renderer.draw(&window, |canvas, _coordinate_system_helper| { + draw(&editor, canvas); }) { println!("Error during draw: {:?}", e); *control_flow = ControlFlow::Exit