diff --git a/src/window/keyboard.rs b/src/window/keyboard.rs deleted file mode 100644 index 6f79fcd..0000000 --- a/src/window/keyboard.rs +++ /dev/null @@ -1,81 +0,0 @@ -use log::error; - -use crate::settings::*; - -#[derive(Clone)] -pub enum KeyboardLayout { - Qwerty, -} - -impl FromValue for KeyboardLayout { - fn from_value(&mut self, value: Value) { - match value.as_str() { - Some("qwerty") => *self = KeyboardLayout::Qwerty, - _ => error!( - "keyboard_layout setting expected a known keyboard layout name, but received: {}", - value - ), - } - } -} - -impl From for Value { - fn from(layout: KeyboardLayout) -> Self { - match layout { - KeyboardLayout::Qwerty => "qwerty".into(), - } - } -} - -#[derive(Clone)] -pub struct KeyboardSettings { - pub layout: KeyboardLayout, -} - -pub fn initialize_settings() { - SETTINGS.set(&KeyboardSettings { - layout: KeyboardLayout::Qwerty, - }); - - register_nvim_setting!("keyboard_layout", KeyboardSettings::layout); -} - -pub fn append_modifiers( - keycode_text: &str, - special: bool, - shift: bool, - ctrl: bool, - alt: bool, - gui: bool, -) -> String { - let mut result = keycode_text.to_string(); - let mut special = if result == "<" { - result = "lt".to_string(); - true - } else { - special - }; - - if shift { - special = true; - result = format!("S-{}", result); - } - if ctrl { - special = true; - result = format!("C-{}", result); - } - if alt { - special = true; - result = format!("M-{}", result); - } - if cfg!(not(target_os = "windows")) && gui { - special = true; - result = format!("D-{}", result); - } - - if special { - result = format!("<{}>", result); - } - - result -} diff --git a/src/window/keyboard/layout.rs b/src/window/keyboard/layout.rs new file mode 100644 index 0000000..cdc7641 --- /dev/null +++ b/src/window/keyboard/layout.rs @@ -0,0 +1,26 @@ +use crate::settings::{FromValue, Value}; + +#[derive(Clone)] +pub enum KeyboardLayout { + Qwerty, +} + +impl FromValue for KeyboardLayout { + fn from_value(&mut self, value: Value) { + match value.as_str() { + Some("qwerty") => *self = KeyboardLayout::Qwerty, + _ => log::error!( + "keyboard_layout setting expected a known keyboard layout name, but received: {}", + value + ), + } + } +} + +impl From for Value { + fn from(layout: KeyboardLayout) -> Self { + match layout { + KeyboardLayout::Qwerty => "qwerty".into(), + } + } +} diff --git a/src/window/keyboard/mod.rs b/src/window/keyboard/mod.rs new file mode 100644 index 0000000..c5dc126 --- /dev/null +++ b/src/window/keyboard/mod.rs @@ -0,0 +1,52 @@ +mod layout; +mod modifiers; +mod settings; +mod token; + +use crate::settings::SETTINGS; + +pub use self::{ + layout::KeyboardLayout, + modifiers::Modifiers, + settings::{initialize_settings, KeyboardSettings}, + token::Token, +}; + +type KeycodeToTokenFn = fn(T, bool) -> Option>; + +pub fn neovim_keybinding_string( + keycode: Option, + keytext: Option, + modifiers: T, + keycode_to_token: KeycodeToTokenFn, +) -> Option +where + T: Into, +{ + let modifiers: Modifiers = modifiers.into(); + if let Some(text) = keytext { + Some( + if text == "<" { + Token::new("lt", true, true) + } else { + Token::new(&text, false, false) + } + .into_string(modifiers), + ) + } else if let Some(keycode) = keycode { + match SETTINGS.get::().layout { + KeyboardLayout::Qwerty => keycode_to_token(keycode, modifiers.shift), + } + .map(|e| e.into_string(modifiers)) + } else { + None + } +} + +pub fn unsupported_key(keycode: T) -> Option +where + T: std::fmt::Debug, +{ + log::trace!("Unsupported key: {:?}", keycode); + None +} diff --git a/src/window/keyboard/modifiers.rs b/src/window/keyboard/modifiers.rs new file mode 100644 index 0000000..fb35ed1 --- /dev/null +++ b/src/window/keyboard/modifiers.rs @@ -0,0 +1,15 @@ +/// The keyboard modifiers associated with a keystroke +#[derive(Debug, Copy, Clone)] +pub struct Modifiers { + /// Shift key + pub shift: bool, + + /// Control key + pub control: bool, + + /// Alt on Windows, option on Mac + pub meta: bool, + + /// Windows key on PC, command key on Mac + pub logo: bool, +} diff --git a/src/window/keyboard/settings.rs b/src/window/keyboard/settings.rs new file mode 100644 index 0000000..1b200a8 --- /dev/null +++ b/src/window/keyboard/settings.rs @@ -0,0 +1,17 @@ +use super::KeyboardLayout; +use crate::{ + register_nvim_setting, + settings::{FromValue, Value, SETTINGS}, +}; + +#[derive(Clone)] +pub struct KeyboardSettings { + pub layout: KeyboardLayout, +} + +pub fn initialize_settings() { + SETTINGS.set(&KeyboardSettings { + layout: KeyboardLayout::Qwerty, + }); + register_nvim_setting!("keyboard_layout", KeyboardSettings::layout); +} diff --git a/src/window/keyboard/token.rs b/src/window/keyboard/token.rs new file mode 100644 index 0000000..aac0698 --- /dev/null +++ b/src/window/keyboard/token.rs @@ -0,0 +1,53 @@ +use super::Modifiers; + +/// Information about how to translate keyboard into Vim input +#[derive(Debug, Clone)] +pub struct Token<'a> { + /// The name of the key in Vimscript. + /// See `:help key-notation` for more details. + key_name: &'a str, + + /// Whether the token should be enclosed in brackets, such as or + special: bool, + + /// Whether the shift key should be considered for inclusion in the token. + use_shift: bool, +} + +impl<'a> Token<'a> { + pub const fn new(key_name: &'a str, special: bool, use_shift: bool) -> Self { + Self { + key_name, + special, + use_shift, + } + } + + /// Converts the keypress to a Neovim input + pub fn into_string(self, mods: Modifiers) -> String { + let shift = self.use_shift && mods.shift; + let special = self.special || shift || mods.control || mods.meta || use_logo(mods.logo); + let open = if special { "<" } else { "" }; + let command = if use_logo(mods.logo) { "D-" } else { "" }; + let shift = if shift { "S-" } else { "" }; + let control = if mods.control { "C-" } else { "" }; + let meta = if mods.meta { "M-" } else { "" }; + let close = if special { ">" } else { "" }; + format!( + "{}{}{}{}{}{}{}", + open, command, shift, control, meta, self.key_name, close + ) + } +} + +#[cfg(not(target_os = "windows"))] +fn use_logo(logo: bool) -> bool { + return logo; +} + +// The Windows key is used for OS-level shortcuts, +// so we want to ignore the logo key on this platform. +#[cfg(target_os = "windows")] +fn use_logo(_: bool) -> bool { + false +} diff --git a/src/window/mod.rs b/src/window/mod.rs index 8049041..dfbdc37 100644 --- a/src/window/mod.rs +++ b/src/window/mod.rs @@ -1,21 +1,19 @@ -pub mod keyboard; +mod keyboard; mod settings; #[cfg_attr(feature = "sdl2", path = "sdl2/mod.rs")] #[cfg_attr(feature = "winit", path = "winit/mod.rs")] mod window_wrapper; -use std::sync::atomic::AtomicBool; -use std::sync::mpsc::Receiver; -use std::sync::Arc; - +use crate::{ + bridge::UiCommand, + editor::{DrawCommand, WindowCommand}, + renderer::Renderer, + INITIAL_DIMENSIONS, +}; use crossfire::mpsc::TxUnbounded; use skulpin::LogicalSize; - -use crate::bridge::UiCommand; -use crate::editor::{DrawCommand, WindowCommand}; -use crate::renderer::Renderer; -use crate::INITIAL_DIMENSIONS; +use std::sync::{atomic::AtomicBool, mpsc::Receiver, Arc}; #[cfg(feature = "sdl2")] pub use window_wrapper::start_loop; diff --git a/src/window/sdl2/layouts/mod.rs b/src/window/sdl2/layouts/mod.rs index 6254546..b2e2f5d 100644 --- a/src/window/sdl2/layouts/mod.rs +++ b/src/window/sdl2/layouts/mod.rs @@ -1,36 +1,17 @@ mod qwerty; -use log::trace; -use skulpin::sdl2::keyboard::{Keycode, Mod}; +use crate::window::keyboard::Modifiers; +use skulpin::sdl2::keyboard::Mod; -use super::keyboard::*; -use crate::settings::*; -use qwerty::*; +pub use qwerty::handle_qwerty_layout; -pub fn unsupported_key(keycode: Keycode) -> Option { - trace!("Unsupported key: {:?}", keycode); - None -} - -pub fn produce_neovim_keybinding_string( - keycode: Option, - keytext: Option, - modifiers: Mod, -) -> Option { - let shift = modifiers.contains(Mod::LSHIFTMOD) || modifiers.contains(Mod::RSHIFTMOD); - let ctrl = modifiers.contains(Mod::LCTRLMOD) || modifiers.contains(Mod::RCTRLMOD); - let alt = modifiers.contains(Mod::LALTMOD) || modifiers.contains(Mod::RALTMOD); - let gui = modifiers.contains(Mod::LGUIMOD) || modifiers.contains(Mod::RGUIMOD); - if let Some(text) = keytext { - Some(append_modifiers(&text, false, false, ctrl, alt, gui)) - } else if let Some(keycode) = keycode { - (match SETTINGS.get::().layout { - KeyboardLayout::Qwerty => handle_qwerty_layout(keycode, shift, ctrl, alt), - }) - .map(|(transformed_text, special, shift, ctrl, alt)| { - append_modifiers(transformed_text, special, shift, ctrl, alt, gui) - }) - } else { - None +impl From for Modifiers { + fn from(mods: Mod) -> Modifiers { + Modifiers { + shift: mods.contains(Mod::LSHIFTMOD) || mods.contains(Mod::RSHIFTMOD), + control: mods.contains(Mod::LCTRLMOD) || mods.contains(Mod::RCTRLMOD), + meta: mods.contains(Mod::LALTMOD) || mods.contains(Mod::RALTMOD), + logo: mods.contains(Mod::LGUIMOD) || mods.contains(Mod::RGUIMOD), + } } } diff --git a/src/window/sdl2/layouts/qwerty.rs b/src/window/sdl2/layouts/qwerty.rs index 4db76cf..474dccd 100644 --- a/src/window/sdl2/layouts/qwerty.rs +++ b/src/window/sdl2/layouts/qwerty.rs @@ -1,269 +1,184 @@ -use super::unsupported_key; - -use skulpin::sdl2::keyboard::Keycode; - -pub fn handle_qwerty_layout( - keycode: Keycode, - shift: bool, - ctrl: bool, - alt: bool, -) -> Option<(&'static str, bool, bool, bool, bool)> { - match (keycode, shift, ctrl, alt) { - (Keycode::Backspace, shift, ctrl, alt) => Some(("BS", true, shift, ctrl, alt)), - (Keycode::Tab, shift, ctrl, alt) => Some(("Tab", true, shift, ctrl, alt)), - (Keycode::Return, shift, ctrl, alt) => Some(("Enter", true, shift, ctrl, alt)), - (Keycode::Escape, shift, ctrl, alt) => Some(("Esc", true, shift, ctrl, alt)), - (Keycode::Space, shift, ctrl, alt) => Some((" ", false, shift, ctrl, alt)), - (Keycode::Exclaim, shift, ctrl, alt) => Some(("!", false, shift, ctrl, alt)), - (Keycode::Quotedbl, shift, ctrl, alt) => Some(("\"", false, shift, ctrl, alt)), - (Keycode::Hash, shift, ctrl, alt) => Some(("#", false, shift, ctrl, alt)), - (Keycode::Dollar, shift, ctrl, alt) => Some(("$", false, shift, ctrl, alt)), - (Keycode::Percent, shift, ctrl, alt) => Some(("%", false, shift, ctrl, alt)), - (Keycode::Ampersand, shift, ctrl, alt) => Some(("&", false, shift, ctrl, alt)), - (Keycode::Quote, false, ctrl, alt) => Some(("'", false, false, ctrl, alt)), - (Keycode::Quote, true, ctrl, alt) => Some(("\"", false, false, ctrl, alt)), - (Keycode::LeftParen, shift, ctrl, alt) => Some(("(", false, shift, ctrl, alt)), - (Keycode::RightParen, shift, ctrl, alt) => Some((")", false, shift, ctrl, alt)), - (Keycode::Asterisk, shift, ctrl, alt) => Some(("*", false, shift, ctrl, alt)), - (Keycode::Plus, shift, ctrl, alt) => Some(("+", false, shift, ctrl, alt)), - (Keycode::Comma, false, ctrl, alt) => Some((",", false, shift, ctrl, alt)), - (Keycode::Comma, true, ctrl, alt) => Some(("<", false, shift, ctrl, alt)), - (Keycode::Minus, false, ctrl, alt) => Some(("-", false, false, ctrl, alt)), - (Keycode::Minus, true, ctrl, alt) => Some(("_", false, false, ctrl, alt)), - (Keycode::Period, false, ctrl, alt) => Some((".", false, false, ctrl, alt)), - (Keycode::Period, true, ctrl, alt) => Some((">", false, false, ctrl, alt)), - (Keycode::Slash, false, ctrl, alt) => Some(("/", false, false, ctrl, alt)), - (Keycode::Slash, true, ctrl, alt) => Some(("?", false, false, ctrl, alt)), - (Keycode::Num0, false, ctrl, alt) => Some(("0", false, shift, ctrl, alt)), - (Keycode::Num0, true, ctrl, alt) => Some((")", true, shift, ctrl, alt)), - (Keycode::Num1, false, ctrl, alt) => Some(("1", false, shift, ctrl, alt)), - (Keycode::Num1, true, ctrl, alt) => Some(("!", true, shift, ctrl, alt)), - (Keycode::Num2, false, ctrl, alt) => Some(("2", false, false, ctrl, alt)), - (Keycode::Num2, true, ctrl, alt) => Some(("@", false, false, ctrl, alt)), - (Keycode::Num3, false, ctrl, alt) => Some(("3", false, false, ctrl, alt)), - (Keycode::Num3, true, ctrl, alt) => Some(("#", false, false, ctrl, alt)), - (Keycode::Num4, false, ctrl, alt) => Some(("4", false, false, ctrl, alt)), - (Keycode::Num4, true, ctrl, alt) => Some(("$", false, false, ctrl, alt)), - (Keycode::Num5, false, ctrl, alt) => Some(("5", false, false, ctrl, alt)), - (Keycode::Num5, true, ctrl, alt) => Some(("%", false, false, ctrl, alt)), - (Keycode::Num6, false, ctrl, alt) => Some(("6", false, false, ctrl, alt)), - (Keycode::Num6, true, ctrl, alt) => Some(("^", false, false, ctrl, alt)), - (Keycode::Num7, false, ctrl, alt) => Some(("7", false, false, ctrl, alt)), - (Keycode::Num7, true, ctrl, alt) => Some(("&", false, false, ctrl, alt)), - (Keycode::Num8, false, ctrl, alt) => Some(("8", false, false, ctrl, alt)), - (Keycode::Num8, true, ctrl, alt) => Some(("*", false, false, ctrl, alt)), - (Keycode::Num9, false, ctrl, alt) => Some(("9", false, false, ctrl, alt)), - (Keycode::Num9, true, ctrl, alt) => Some(("(", true, false, ctrl, alt)), - (Keycode::Colon, shift, ctrl, alt) => Some((":", false, shift, ctrl, alt)), - (Keycode::Semicolon, false, ctrl, alt) => Some((";", false, false, ctrl, alt)), - (Keycode::Semicolon, true, ctrl, alt) => Some((":", false, false, ctrl, alt)), - (Keycode::Less, shift, ctrl, alt) => Some(("lt", false, shift, ctrl, alt)), - (Keycode::Equals, false, ctrl, alt) => Some(("=", false, false, ctrl, alt)), - (Keycode::Equals, true, ctrl, alt) => Some(("+", false, false, ctrl, alt)), - (Keycode::Greater, shift, ctrl, alt) => Some(("gt", false, shift, ctrl, alt)), - (Keycode::Question, shift, ctrl, alt) => Some(("?", false, shift, ctrl, alt)), - (Keycode::At, shift, ctrl, alt) => Some(("@", false, shift, ctrl, alt)), - (Keycode::LeftBracket, false, ctrl, alt) => Some(("[", false, false, ctrl, alt)), - (Keycode::LeftBracket, true, ctrl, alt) => Some(("{", false, false, ctrl, alt)), - (Keycode::Backslash, false, ctrl, alt) => Some(("\\", false, false, ctrl, alt)), - (Keycode::Backslash, true, ctrl, alt) => Some(("|", false, false, ctrl, alt)), - (Keycode::RightBracket, false, ctrl, alt) => Some(("]", false, false, ctrl, alt)), - (Keycode::RightBracket, true, ctrl, alt) => Some(("}", false, false, ctrl, alt)), - (Keycode::Caret, shift, ctrl, alt) => Some(("^", false, shift, ctrl, alt)), - (Keycode::Underscore, shift, ctrl, alt) => Some(("_", false, shift, ctrl, alt)), - (Keycode::Backquote, false, ctrl, alt) => Some(("`", false, false, ctrl, alt)), - (Keycode::Backquote, true, ctrl, alt) => Some(("~", false, false, ctrl, alt)), - (Keycode::A, shift, ctrl, alt) => Some(("a", false, shift, ctrl, alt)), - (Keycode::B, shift, ctrl, alt) => Some(("b", false, shift, ctrl, alt)), - (Keycode::C, shift, ctrl, alt) => Some(("c", false, shift, ctrl, alt)), - (Keycode::D, shift, ctrl, alt) => Some(("d", false, shift, ctrl, alt)), - (Keycode::E, shift, ctrl, alt) => Some(("e", false, shift, ctrl, alt)), - (Keycode::F, shift, ctrl, alt) => Some(("f", false, shift, ctrl, alt)), - (Keycode::G, shift, ctrl, alt) => Some(("g", false, shift, ctrl, alt)), - (Keycode::H, shift, ctrl, alt) => Some(("h", false, shift, ctrl, alt)), - (Keycode::I, shift, ctrl, alt) => Some(("i", false, shift, ctrl, alt)), - (Keycode::J, shift, ctrl, alt) => Some(("j", false, shift, ctrl, alt)), - (Keycode::K, shift, ctrl, alt) => Some(("k", false, shift, ctrl, alt)), - (Keycode::L, shift, ctrl, alt) => Some(("l", false, shift, ctrl, alt)), - (Keycode::M, shift, ctrl, alt) => Some(("m", false, shift, ctrl, alt)), - (Keycode::N, shift, ctrl, alt) => Some(("n", false, shift, ctrl, alt)), - (Keycode::O, shift, ctrl, alt) => Some(("o", false, shift, ctrl, alt)), - (Keycode::P, shift, ctrl, alt) => Some(("p", false, shift, ctrl, alt)), - (Keycode::Q, shift, ctrl, alt) => Some(("q", false, shift, ctrl, alt)), - (Keycode::R, shift, ctrl, alt) => Some(("r", false, shift, ctrl, alt)), - (Keycode::S, shift, ctrl, alt) => Some(("s", false, shift, ctrl, alt)), - (Keycode::T, shift, ctrl, alt) => Some(("t", false, shift, ctrl, alt)), - (Keycode::U, shift, ctrl, alt) => Some(("u", false, shift, ctrl, alt)), - (Keycode::V, shift, ctrl, alt) => Some(("v", false, shift, ctrl, alt)), - (Keycode::W, shift, ctrl, alt) => Some(("w", false, shift, ctrl, alt)), - (Keycode::X, shift, ctrl, alt) => Some(("x", false, shift, ctrl, alt)), - (Keycode::Y, shift, ctrl, alt) => Some(("y", false, shift, ctrl, alt)), - (Keycode::Z, shift, ctrl, alt) => Some(("z", false, shift, ctrl, alt)), - (Keycode::Delete, shift, ctrl, alt) => Some(("Delete", true, shift, ctrl, alt)), - (Keycode::CapsLock, _, _, _) => unsupported_key(Keycode::CapsLock), - (Keycode::F1, shift, ctrl, alt) => Some(("F1", true, shift, ctrl, alt)), - (Keycode::F2, shift, ctrl, alt) => Some(("F2", true, shift, ctrl, alt)), - (Keycode::F3, shift, ctrl, alt) => Some(("F3", true, shift, ctrl, alt)), - (Keycode::F4, shift, ctrl, alt) => Some(("F4", true, shift, ctrl, alt)), - (Keycode::F5, shift, ctrl, alt) => Some(("F5", true, shift, ctrl, alt)), - (Keycode::F6, shift, ctrl, alt) => Some(("F6", true, shift, ctrl, alt)), - (Keycode::F7, shift, ctrl, alt) => Some(("F7", true, shift, ctrl, alt)), - (Keycode::F8, shift, ctrl, alt) => Some(("F8", true, shift, ctrl, alt)), - (Keycode::F9, shift, ctrl, alt) => Some(("F9", true, shift, ctrl, alt)), - (Keycode::F10, shift, ctrl, alt) => Some(("F10", true, shift, ctrl, alt)), - (Keycode::F11, shift, ctrl, alt) => Some(("F11", true, shift, ctrl, alt)), - (Keycode::F12, shift, ctrl, alt) => Some(("F12", true, shift, ctrl, alt)), - (Keycode::PrintScreen, _, _, _) => unsupported_key(Keycode::PrintScreen), - (Keycode::ScrollLock, _, _, _) => unsupported_key(Keycode::ScrollLock), - (Keycode::Pause, _, _, _) => unsupported_key(Keycode::Pause), - (Keycode::Insert, shift, ctrl, alt) => Some(("Insert", true, shift, ctrl, alt)), - (Keycode::Home, shift, ctrl, alt) => Some(("Home", true, shift, ctrl, alt)), - (Keycode::PageUp, shift, ctrl, alt) => Some(("PageUp", true, shift, ctrl, alt)), - (Keycode::End, shift, ctrl, alt) => Some(("End", true, shift, ctrl, alt)), - (Keycode::PageDown, shift, ctrl, alt) => Some(("PageDown", true, shift, ctrl, alt)), - (Keycode::Right, shift, ctrl, alt) => Some(("Right", true, shift, ctrl, alt)), - (Keycode::Left, shift, ctrl, alt) => Some(("Left", true, shift, ctrl, alt)), - (Keycode::Down, shift, ctrl, alt) => Some(("Down", true, shift, ctrl, alt)), - (Keycode::Up, shift, ctrl, alt) => Some(("Up", true, shift, ctrl, alt)), - (Keycode::NumLockClear, _, _, _) => unsupported_key(Keycode::NumLockClear), - (Keycode::KpDivide, shift, ctrl, alt) => Some(("/", true, shift, ctrl, alt)), - (Keycode::KpMultiply, shift, ctrl, alt) => Some(("*", true, shift, ctrl, alt)), - (Keycode::KpMinus, shift, ctrl, alt) => Some(("-", true, shift, ctrl, alt)), - (Keycode::KpPlus, shift, ctrl, alt) => Some(("+", true, shift, ctrl, alt)), - (Keycode::KpEnter, shift, ctrl, alt) => Some(("Enter", true, shift, ctrl, alt)), - (Keycode::Kp0, shift, ctrl, alt) => Some(("0", false, shift, ctrl, alt)), - (Keycode::Kp1, shift, ctrl, alt) => Some(("1", false, shift, ctrl, alt)), - (Keycode::Kp2, shift, ctrl, alt) => Some(("2", false, shift, ctrl, alt)), - (Keycode::Kp3, shift, ctrl, alt) => Some(("3", false, shift, ctrl, alt)), - (Keycode::Kp4, shift, ctrl, alt) => Some(("4", false, shift, ctrl, alt)), - (Keycode::Kp5, shift, ctrl, alt) => Some(("5", false, shift, ctrl, alt)), - (Keycode::Kp6, shift, ctrl, alt) => Some(("6", false, shift, ctrl, alt)), - (Keycode::Kp7, shift, ctrl, alt) => Some(("7", false, shift, ctrl, alt)), - (Keycode::Kp8, shift, ctrl, alt) => Some(("8", false, shift, ctrl, alt)), - (Keycode::Kp9, shift, ctrl, alt) => Some(("9", false, shift, ctrl, alt)), - (Keycode::KpPeriod, shift, ctrl, alt) => Some((".", false, shift, ctrl, alt)), - (Keycode::Application, _, _, _) => unsupported_key(Keycode::Application), - (Keycode::Power, _, _, _) => unsupported_key(Keycode::Power), - (Keycode::KpEquals, shift, ctrl, alt) => Some(("=", false, shift, ctrl, alt)), - (Keycode::F13, shift, ctrl, alt) => Some(("F13", true, shift, ctrl, alt)), - (Keycode::F14, shift, ctrl, alt) => Some(("F14", true, shift, ctrl, alt)), - (Keycode::F15, shift, ctrl, alt) => Some(("F15", true, shift, ctrl, alt)), - (Keycode::F16, shift, ctrl, alt) => Some(("F16", true, shift, ctrl, alt)), - (Keycode::F17, shift, ctrl, alt) => Some(("F17", true, shift, ctrl, alt)), - (Keycode::F18, shift, ctrl, alt) => Some(("F18", true, shift, ctrl, alt)), - (Keycode::F19, shift, ctrl, alt) => Some(("F19", true, shift, ctrl, alt)), - (Keycode::F20, shift, ctrl, alt) => Some(("F20", true, shift, ctrl, alt)), - (Keycode::F21, shift, ctrl, alt) => Some(("F21", true, shift, ctrl, alt)), - (Keycode::F22, shift, ctrl, alt) => Some(("F22", true, shift, ctrl, alt)), - (Keycode::F23, shift, ctrl, alt) => Some(("F23", true, shift, ctrl, alt)), - (Keycode::F24, shift, ctrl, alt) => Some(("F24", true, shift, ctrl, alt)), - (Keycode::Execute, _, _, _) => unsupported_key(Keycode::Execute), - (Keycode::Help, _, _, _) => unsupported_key(Keycode::Help), - (Keycode::Menu, _, _, _) => unsupported_key(Keycode::Menu), - (Keycode::Select, _, _, _) => unsupported_key(Keycode::Select), - (Keycode::Stop, _, _, _) => unsupported_key(Keycode::Stop), - (Keycode::Again, _, _, _) => unsupported_key(Keycode::Again), - (Keycode::Undo, _, _, _) => unsupported_key(Keycode::Undo), - (Keycode::Cut, _, _, _) => unsupported_key(Keycode::Cut), - (Keycode::Copy, _, _, _) => unsupported_key(Keycode::Copy), - (Keycode::Paste, _, _, _) => unsupported_key(Keycode::Paste), - (Keycode::Find, _, _, _) => unsupported_key(Keycode::Find), - (Keycode::Mute, _, _, _) => unsupported_key(Keycode::Mute), - (Keycode::VolumeUp, _, _, _) => unsupported_key(Keycode::VolumeUp), - (Keycode::VolumeDown, _, _, _) => unsupported_key(Keycode::VolumeDown), - (Keycode::KpComma, _, _, _) => unsupported_key(Keycode::KpComma), - (Keycode::KpEqualsAS400, _, _, _) => unsupported_key(Keycode::KpEqualsAS400), - (Keycode::AltErase, _, _, _) => unsupported_key(Keycode::AltErase), - (Keycode::Sysreq, _, _, _) => unsupported_key(Keycode::Sysreq), - (Keycode::Cancel, _, _, _) => unsupported_key(Keycode::Cancel), - (Keycode::Clear, _, _, _) => unsupported_key(Keycode::Clear), - (Keycode::Prior, _, _, _) => unsupported_key(Keycode::Prior), - (Keycode::Return2, _, _, _) => unsupported_key(Keycode::Return2), - (Keycode::Separator, _, _, _) => unsupported_key(Keycode::Separator), - (Keycode::Out, _, _, _) => unsupported_key(Keycode::Out), - (Keycode::Oper, _, _, _) => unsupported_key(Keycode::Oper), - (Keycode::ClearAgain, _, _, _) => unsupported_key(Keycode::ClearAgain), - (Keycode::CrSel, _, _, _) => unsupported_key(Keycode::CrSel), - (Keycode::ExSel, _, _, _) => unsupported_key(Keycode::ExSel), - (Keycode::Kp00, _, _, _) => unsupported_key(Keycode::Kp00), - (Keycode::Kp000, _, _, _) => unsupported_key(Keycode::Kp000), - (Keycode::ThousandsSeparator, _, _, _) => unsupported_key(Keycode::ThousandsSeparator), - (Keycode::DecimalSeparator, _, _, _) => unsupported_key(Keycode::DecimalSeparator), - (Keycode::CurrencyUnit, _, _, _) => unsupported_key(Keycode::CurrencyUnit), - (Keycode::CurrencySubUnit, _, _, _) => unsupported_key(Keycode::CurrencySubUnit), - (Keycode::KpLeftParen, shift, ctrl, alt) => Some(("(", false, shift, ctrl, alt)), - (Keycode::KpRightParen, shift, ctrl, alt) => Some(("(", false, shift, ctrl, alt)), - (Keycode::KpLeftBrace, shift, ctrl, alt) => Some(("[", false, shift, ctrl, alt)), - (Keycode::KpRightBrace, shift, ctrl, alt) => Some(("]", false, shift, ctrl, alt)), - (Keycode::KpTab, shift, ctrl, alt) => Some(("TAB", true, shift, ctrl, alt)), - (Keycode::KpBackspace, shift, ctrl, alt) => Some(("BS", true, shift, ctrl, alt)), - (Keycode::KpA, shift, ctrl, alt) => Some(("A", false, shift, ctrl, alt)), - (Keycode::KpB, shift, ctrl, alt) => Some(("B", false, shift, ctrl, alt)), - (Keycode::KpC, shift, ctrl, alt) => Some(("C", false, shift, ctrl, alt)), - (Keycode::KpD, shift, ctrl, alt) => Some(("D", false, shift, ctrl, alt)), - (Keycode::KpE, shift, ctrl, alt) => Some(("E", false, shift, ctrl, alt)), - (Keycode::KpF, shift, ctrl, alt) => Some(("F", false, shift, ctrl, alt)), - (Keycode::KpXor, _, _, _) => unsupported_key(Keycode::KpXor), - (Keycode::KpPower, shift, ctrl, alt) => Some(("^", false, shift, ctrl, alt)), - (Keycode::KpPercent, shift, ctrl, alt) => Some(("%", false, shift, ctrl, alt)), - (Keycode::KpLess, shift, ctrl, alt) => Some(("lt", true, shift, ctrl, alt)), - (Keycode::KpGreater, shift, ctrl, alt) => Some(("gt", true, shift, ctrl, alt)), - (Keycode::KpAmpersand, shift, ctrl, alt) => Some(("&", false, shift, ctrl, alt)), - (Keycode::KpDblAmpersand, _, _, _) => unsupported_key(Keycode::KpDblAmpersand), - (Keycode::KpVerticalBar, shift, ctrl, alt) => Some(("|", false, shift, ctrl, alt)), - (Keycode::KpDblVerticalBar, _, _, _) => unsupported_key(Keycode::KpDblVerticalBar), - (Keycode::KpColon, shift, ctrl, alt) => Some((":", false, shift, ctrl, alt)), - (Keycode::KpHash, shift, ctrl, alt) => Some(("#", false, shift, ctrl, alt)), - (Keycode::KpSpace, shift, ctrl, alt) => Some((" ", false, shift, ctrl, alt)), - (Keycode::KpAt, shift, ctrl, alt) => Some(("@", false, shift, ctrl, alt)), - (Keycode::KpExclam, shift, ctrl, alt) => Some(("!", false, shift, ctrl, alt)), - (Keycode::KpMemStore, _, _, _) => unsupported_key(Keycode::KpMemStore), - (Keycode::KpMemRecall, _, _, _) => unsupported_key(Keycode::KpMemRecall), - (Keycode::KpMemClear, _, _, _) => unsupported_key(Keycode::KpMemClear), - (Keycode::KpMemAdd, _, _, _) => unsupported_key(Keycode::KpMemAdd), - (Keycode::KpMemSubtract, _, _, _) => unsupported_key(Keycode::KpMemSubtract), - (Keycode::KpMemMultiply, _, _, _) => unsupported_key(Keycode::KpMemMultiply), - (Keycode::KpMemDivide, _, _, _) => unsupported_key(Keycode::KpMemDivide), - (Keycode::KpPlusMinus, _, _, _) => unsupported_key(Keycode::KpPlusMinus), - (Keycode::KpClear, _, _, _) => unsupported_key(Keycode::KpClear), - (Keycode::KpClearEntry, _, _, _) => unsupported_key(Keycode::KpClearEntry), - (Keycode::KpBinary, _, _, _) => unsupported_key(Keycode::KpBinary), - (Keycode::KpOctal, _, _, _) => unsupported_key(Keycode::KpOctal), - (Keycode::KpDecimal, _, _, _) => unsupported_key(Keycode::KpDecimal), - (Keycode::KpHexadecimal, _, _, _) => unsupported_key(Keycode::KpHexadecimal), - (Keycode::LCtrl, _, _, _) => None, - (Keycode::LShift, _, _, _) => None, - (Keycode::LAlt, _, _, _) => None, - (Keycode::LGui, _, _, _) => None, - (Keycode::RCtrl, _, _, _) => None, - (Keycode::RShift, _, _, _) => None, - (Keycode::RAlt, _, _, _) => None, - (Keycode::RGui, _, _, _) => None, - (Keycode::Mode, _, _, _) => unsupported_key(Keycode::Mode), - (Keycode::AudioNext, _, _, _) => unsupported_key(Keycode::AudioNext), - (Keycode::AudioPrev, _, _, _) => unsupported_key(Keycode::AudioPrev), - (Keycode::AudioStop, _, _, _) => unsupported_key(Keycode::AudioStop), - (Keycode::AudioPlay, _, _, _) => unsupported_key(Keycode::AudioPlay), - (Keycode::AudioMute, _, _, _) => unsupported_key(Keycode::AudioMute), - (Keycode::MediaSelect, _, _, _) => unsupported_key(Keycode::MediaSelect), - (Keycode::Www, _, _, _) => unsupported_key(Keycode::Www), - (Keycode::Mail, _, _, _) => unsupported_key(Keycode::Mail), - (Keycode::Calculator, _, _, _) => unsupported_key(Keycode::Calculator), - (Keycode::Computer, _, _, _) => unsupported_key(Keycode::Computer), - (Keycode::AcSearch, _, _, _) => unsupported_key(Keycode::AcSearch), - (Keycode::AcHome, _, _, _) => unsupported_key(Keycode::AcHome), - (Keycode::AcBack, _, _, _) => unsupported_key(Keycode::AcBack), - (Keycode::AcForward, _, _, _) => unsupported_key(Keycode::AcForward), - (Keycode::AcStop, _, _, _) => unsupported_key(Keycode::AcStop), - (Keycode::AcRefresh, _, _, _) => unsupported_key(Keycode::AcRefresh), - (Keycode::AcBookmarks, _, _, _) => unsupported_key(Keycode::AcBookmarks), - (Keycode::BrightnessDown, _, _, _) => unsupported_key(Keycode::BrightnessDown), - (Keycode::BrightnessUp, _, _, _) => unsupported_key(Keycode::BrightnessUp), - (Keycode::DisplaySwitch, _, _, _) => unsupported_key(Keycode::DisplaySwitch), - (Keycode::KbdIllumToggle, _, _, _) => unsupported_key(Keycode::KbdIllumToggle), - (Keycode::KbdIllumDown, _, _, _) => unsupported_key(Keycode::KbdIllumDown), - (Keycode::KbdIllumUp, _, _, _) => unsupported_key(Keycode::KbdIllumUp), - (Keycode::Eject, _, _, _) => unsupported_key(Keycode::Eject), - (Keycode::Sleep, _, _, _) => unsupported_key(Keycode::Sleep), - } -} +use crate::window::keyboard::{unsupported_key, Token}; +use skulpin::sdl2::keyboard::Keycode::{self, *}; + +/// Maps winit keyboard events to Vim tokens +pub fn handle_qwerty_layout(keycode: Keycode, shift: bool) -> Option> { + let special = |text| Some(Token::new(text, true, true)); + let normal = |text| Some(Token::new(text, false, true)); + let partial = |text| Some(Token::new(text, false, false)); + match (keycode, shift) { + (Backspace, _) => special("BS"), + (Tab, _) => special("Tab"), + (Return, _) => special("Enter"), + (Escape, _) => special("Esc"), + (Space, _) => normal(" "), + (Exclaim, _) => normal("!"), + (Quotedbl, _) => normal("\""), + (Hash, _) => normal("#"), + (Dollar, _) => normal("$"), + (Percent, _) => normal("%"), + (Ampersand, _) => normal("&"), + (Quote, false) => normal("'"), + (Quote, true) => normal("\""), + (LeftParen, _) => normal("("), + (RightParen, _) => normal(")"), + (Asterisk, _) => normal("*"), + (Plus, _) => normal("+"), + (Comma, false) => normal(","), + (Comma, true) => special("lt"), + (Minus, false) => partial("-"), + (Minus, true) => partial("_"), + (Period, false) => partial("."), + (Period, true) => partial(">"), + (Slash, false) => partial("/"), + (Slash, true) => partial("?"), + (Num0, false) => partial("0"), + (Num0, true) => special(")"), + (Num1, false) => partial("1"), + (Num1, true) => special("!"), + (Num2, false) => partial("2"), + (Num2, true) => partial("@"), + (Num3, false) => partial("3"), + (Num3, true) => partial("#"), + (Num4, false) => partial("4"), + (Num4, true) => partial("$"), + (Num5, false) => partial("5"), + (Num5, true) => partial("%"), + (Num6, false) => partial("6"), + (Num6, true) => partial("^"), + (Num7, false) => partial("7"), + (Num7, true) => partial("&"), + (Num8, false) => partial("8"), + (Num8, true) => partial("*"), + (Num9, false) => partial("9"), + (Num9, true) => partial("("), + (Colon, _) => normal(":"), + (Semicolon, false) => partial(";"), + (Semicolon, true) => partial(":"), + (Less, _) => special("lt"), + (Equals, false) => partial("="), + (Equals, true) => partial("+"), + (Greater, _) => normal("gt"), + (Question, _) => normal("?"), + (At, _) => normal("@"), + (LeftBracket, false) => partial("["), + (LeftBracket, true) => partial("{"), + (Backslash, false) => partial("\\"), + (Backslash, true) => partial("|"), + (RightBracket, false) => partial("]"), + (RightBracket, true) => partial("}"), + (Caret, _) => normal("^"), + (Underscore, _) => normal("_"), + (Backquote, false) => partial("`"), + (Backquote, true) => partial("~"), + (A, _) => normal("a"), + (B, _) => normal("b"), + (C, _) => normal("c"), + (D, _) => normal("d"), + (E, _) => normal("e"), + (F, _) => normal("f"), + (G, _) => normal("g"), + (H, _) => normal("h"), + (I, _) => normal("i"), + (J, _) => normal("j"), + (K, _) => normal("k"), + (L, _) => normal("l"), + (M, _) => normal("m"), + (N, _) => normal("n"), + (O, _) => normal("o"), + (P, _) => normal("p"), + (Q, _) => normal("q"), + (R, _) => normal("r"), + (S, _) => normal("s"), + (T, _) => normal("t"), + (U, _) => normal("u"), + (V, _) => normal("v"), + (W, _) => normal("w"), + (X, _) => normal("x"), + (Y, _) => normal("y"), + (Z, _) => normal("z"), + (Delete, _) => special("Delete"), + (F1, _) => special("F1"), + (F2, _) => special("F2"), + (F3, _) => special("F3"), + (F4, _) => special("F4"), + (F5, _) => special("F5"), + (F6, _) => special("F6"), + (F7, _) => special("F7"), + (F8, _) => special("F8"), + (F9, _) => special("F9"), + (F10, _) => special("F10"), + (F11, _) => special("F11"), + (F12, _) => special("F12"), + (Insert, _) => special("Insert"), + (Home, _) => special("Home"), + (PageUp, _) => special("PageUp"), + (End, _) => special("End"), + (PageDown, _) => special("PageDown"), + (Right, _) => special("Right"), + (Left, _) => special("Left"), + (Down, _) => special("Down"), + (Up, _) => special("Up"), + (KpDivide, _) => special("/"), + (KpMultiply, _) => special("*"), + (KpMinus, _) => special("-"), + (KpPlus, _) => special("+"), + (KpEnter, _) => special("Enter"), + (Kp0, _) => normal("0"), + (Kp1, _) => normal("1"), + (Kp2, _) => normal("2"), + (Kp3, _) => normal("3"), + (Kp4, _) => normal("4"), + (Kp5, _) => normal("5"), + (Kp6, _) => normal("6"), + (Kp7, _) => normal("7"), + (Kp8, _) => normal("8"), + (Kp9, _) => normal("9"), + (KpPeriod, _) => normal("."), + (KpEquals, _) => normal("="), + (F13, _) => special("F13"), + (F14, _) => special("F14"), + (F15, _) => special("F15"), + (F16, _) => special("F16"), + (F17, _) => special("F17"), + (F18, _) => special("F18"), + (F19, _) => special("F19"), + (F20, _) => special("F20"), + (F21, _) => special("F21"), + (F22, _) => special("F22"), + (F23, _) => special("F23"), + (F24, _) => special("F24"), + (KpLeftParen, _) => normal("("), + (KpRightParen, _) => normal("("), + (KpLeftBrace, _) => normal("["), + (KpRightBrace, _) => normal("]"), + (KpTab, _) => special("TAB"), + (KpBackspace, _) => special("BS"), + (KpA, _) => normal("A"), + (KpB, _) => normal("B"), + (KpC, _) => normal("C"), + (KpD, _) => normal("D"), + (KpE, _) => normal("E"), + (KpF, _) => normal("F"), + (KpPower, _) => normal("^"), + (KpPercent, _) => normal("%"), + (KpLess, _) => special("lt"), + (KpGreater, _) => special("gt"), + (KpAmpersand, _) => normal("&"), + (KpVerticalBar, _) => normal("|"), + (KpColon, _) => normal(":"), + (KpHash, _) => normal("#"), + (KpSpace, _) => normal(" "), + (KpAt, _) => normal("@"), + (KpExclam, _) => normal("!"), + (LCtrl, _) => None, + (LShift, _) => None, + (LAlt, _) => None, + (LGui, _) => None, + (RCtrl, _) => None, + (RShift, _) => None, + (RAlt, _) => None, + (RGui, _) => None, + (keycode, _) => unsupported_key(keycode), + } +} diff --git a/src/window/sdl2/mod.rs b/src/window/sdl2/mod.rs index 18384b3..276d3f4 100644 --- a/src/window/sdl2/mod.rs +++ b/src/window/sdl2/mod.rs @@ -1,36 +1,34 @@ #[macro_use] mod layouts; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::Receiver; -use std::sync::Arc; -use std::thread::sleep; -use std::time::{Duration, Instant}; - +use super::{handle_new_grid_size, keyboard::neovim_keybinding_string, WindowSettings}; +use crate::{ + bridge::UiCommand, editor::WindowCommand, error_handling::ResultPanicExplanation, + redraw_scheduler::REDRAW_SCHEDULER, renderer::Renderer, settings::SETTINGS, +}; use crossfire::mpsc::TxUnbounded; -use log::{debug, error, trace}; -use skulpin::ash::prelude::VkResult; -use skulpin::sdl2; -use skulpin::sdl2::event::{Event, WindowEvent}; -use skulpin::sdl2::keyboard::Keycode; -use skulpin::sdl2::video::FullscreenType; -use skulpin::sdl2::EventPump; -use skulpin::sdl2::Sdl; +use layouts::handle_qwerty_layout; use skulpin::{ + ash::prelude::VkResult, + sdl2::{ + self, + event::{Event, WindowEvent}, + keyboard::Keycode, + video::FullscreenType, + EventPump, Sdl, + }, CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer, RendererBuilder, Sdl2Window, Window, }; - -use super::handle_new_grid_size; -pub use super::keyboard; -use super::settings::*; -use crate::bridge::UiCommand; -use crate::editor::WindowCommand; -use crate::error_handling::ResultPanicExplanation; -use crate::redraw_scheduler::REDRAW_SCHEDULER; -use crate::renderer::Renderer; -use crate::settings::*; -use layouts::produce_neovim_keybinding_string; +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::Receiver, + Arc, + }, + thread::sleep, + time::{Duration, Instant}, +}; #[derive(RustEmbed)] #[folder = "assets/"] @@ -142,7 +140,7 @@ impl Sdl2WindowWrapper { let modifiers = self.context.keyboard().mod_state(); if keycode.is_some() || text.is_some() { - trace!( + log::trace!( "Keyboard Input Received: keycode-{:?} modifiers-{:?} text-{:?}", keycode, modifiers, @@ -150,7 +148,8 @@ impl Sdl2WindowWrapper { ); } - if let Some(keybinding_string) = produce_neovim_keybinding_string(keycode, text, modifiers) + if let Some(keybinding_string) = + neovim_keybinding_string(keycode, text, modifiers, handle_qwerty_layout) { self.ui_command_sender .send(UiCommand::Keyboard(keybinding_string)) @@ -361,7 +360,7 @@ impl Sdl2WindowWrapper { let ui_command_sender = self.ui_command_sender.clone(); if REDRAW_SCHEDULER.should_draw() || SETTINGS.get::().no_idle { - debug!("Render Triggered"); + log::debug!("Render Triggered"); let renderer = &mut self.renderer; self.skulpin_renderer.draw( @@ -466,7 +465,7 @@ pub fn start_loop( was_animating = animating; } Err(error) => { - error!("Render failed: {}", error); + log::error!("Render failed: {}", error); break; } } diff --git a/src/window/winit/layouts/mod.rs b/src/window/winit/layouts/mod.rs index 3bf8477..68b2b28 100644 --- a/src/window/winit/layouts/mod.rs +++ b/src/window/winit/layouts/mod.rs @@ -1,44 +1,21 @@ mod qwerty; -use log::trace; +use crate::window::keyboard::Modifiers; use skulpin::winit::event::ModifiersState; -use skulpin::winit::event::VirtualKeyCode as Keycode; -use super::keyboard::*; -use crate::settings::*; -use qwerty::*; +pub use qwerty::handle_qwerty_layout; -pub fn unsupported_key(keycode: Keycode) -> Option { - trace!("Unsupported key: {:?}", keycode); - None -} - -pub fn produce_neovim_keybinding_string( - keycode: Option, - keytext: Option, - modifiers: Option, -) -> Option { - let mut shift = false; - let mut ctrl = false; - let mut alt = false; - let mut gui = false; - if let Some(modifiers) = modifiers { - shift = modifiers.shift(); - ctrl = modifiers.ctrl(); - alt = modifiers.alt(); - gui = modifiers.logo(); - } - - if let Some(text) = keytext { - Some(append_modifiers(&text, false, false, ctrl, alt, gui)) - } else if let Some(keycode) = keycode { - (match SETTINGS.get::().layout { - KeyboardLayout::Qwerty => handle_qwerty_layout(keycode, shift, ctrl, alt), - }) - .map(|(transformed_text, special, shift, ctrl, alt)| { - append_modifiers(transformed_text, special, shift, ctrl, alt, gui) - }) - } else { - None +impl From> for Modifiers { + fn from(state: Option) -> Modifiers { + if let Some(modifiers) = state { + Modifiers { + shift: state.shift(), + control: state.ctrl(), + meta: state.alt(), + logo: state.logo(), + } + } else { + Modifiers::new(false, false, false, false) + } } } diff --git a/src/window/winit/layouts/qwerty.rs b/src/window/winit/layouts/qwerty.rs index e234ac0..9f70cf6 100644 --- a/src/window/winit/layouts/qwerty.rs +++ b/src/window/winit/layouts/qwerty.rs @@ -1,164 +1,138 @@ -use super::unsupported_key; - -use skulpin::winit::event::VirtualKeyCode as Keycode; - -pub fn handle_qwerty_layout( - keycode: Keycode, - shift: bool, - ctrl: bool, - alt: bool, -) -> Option<(&'static str, bool, bool, bool, bool)> { - match (keycode, shift, ctrl, alt) { - (Keycode::Back, shift, ctrl, alt) => Some(("BS", true, shift, ctrl, alt)), - (Keycode::Tab, shift, ctrl, alt) => Some(("Tab", true, shift, ctrl, alt)), - (Keycode::Return, shift, ctrl, alt) => Some(("Enter", true, shift, ctrl, alt)), - (Keycode::Escape, shift, ctrl, alt) => Some(("Esc", true, shift, ctrl, alt)), - (Keycode::Space, shift, ctrl, alt) => Some((" ", false, shift, ctrl, alt)), - (Keycode::Apostrophe, false, ctrl, alt) => Some(("'", false, false, ctrl, alt)), - (Keycode::Apostrophe, true, ctrl, alt) => Some(("\"", false, false, ctrl, alt)), - (Keycode::Comma, false, ctrl, alt) => Some((",", false, shift, ctrl, alt)), - (Keycode::Comma, true, ctrl, alt) => Some(("<", false, shift, ctrl, alt)), - (Keycode::Minus, false, ctrl, alt) => Some(("-", false, false, ctrl, alt)), - (Keycode::Minus, true, ctrl, alt) => Some(("_", false, false, ctrl, alt)), - (Keycode::Period, false, ctrl, alt) => Some((".", false, false, ctrl, alt)), - (Keycode::Period, true, ctrl, alt) => Some((">", false, false, ctrl, alt)), - (Keycode::Slash, false, ctrl, alt) => Some(("/", false, false, ctrl, alt)), - (Keycode::Slash, true, ctrl, alt) => Some(("?", false, false, ctrl, alt)), - (Keycode::Key0, false, ctrl, alt) => Some(("0", false, shift, ctrl, alt)), - (Keycode::Key0, true, ctrl, alt) => Some((")", true, shift, ctrl, alt)), - (Keycode::Key1, false, ctrl, alt) => Some(("1", false, shift, ctrl, alt)), - (Keycode::Key1, true, ctrl, alt) => Some(("!", true, shift, ctrl, alt)), - (Keycode::Key2, false, ctrl, alt) => Some(("2", false, false, ctrl, alt)), - (Keycode::Key2, true, ctrl, alt) => Some(("@", false, false, ctrl, alt)), - (Keycode::Key3, false, ctrl, alt) => Some(("3", false, false, ctrl, alt)), - (Keycode::Key3, true, ctrl, alt) => Some(("#", false, false, ctrl, alt)), - (Keycode::Key4, false, ctrl, alt) => Some(("4", false, false, ctrl, alt)), - (Keycode::Key4, true, ctrl, alt) => Some(("$", false, false, ctrl, alt)), - (Keycode::Key5, false, ctrl, alt) => Some(("5", false, false, ctrl, alt)), - (Keycode::Key5, true, ctrl, alt) => Some(("%", false, false, ctrl, alt)), - (Keycode::Key6, false, ctrl, alt) => Some(("6", false, false, ctrl, alt)), - (Keycode::Key6, true, ctrl, alt) => Some(("^", false, false, ctrl, alt)), - (Keycode::Key7, false, ctrl, alt) => Some(("7", false, false, ctrl, alt)), - (Keycode::Key7, true, ctrl, alt) => Some(("&", false, false, ctrl, alt)), - (Keycode::Key8, false, ctrl, alt) => Some(("8", false, false, ctrl, alt)), - (Keycode::Key8, true, ctrl, alt) => Some(("*", false, false, ctrl, alt)), - (Keycode::Key9, false, ctrl, alt) => Some(("9", false, false, ctrl, alt)), - (Keycode::Key9, true, ctrl, alt) => Some(("(", true, false, ctrl, alt)), - (Keycode::Colon, shift, ctrl, alt) => Some((":", false, shift, ctrl, alt)), - (Keycode::Semicolon, false, ctrl, alt) => Some((";", false, false, ctrl, alt)), - (Keycode::Semicolon, true, ctrl, alt) => Some((":", false, false, ctrl, alt)), - (Keycode::Equals, false, ctrl, alt) => Some(("=", false, false, ctrl, alt)), - (Keycode::Equals, true, ctrl, alt) => Some(("+", false, false, ctrl, alt)), - (Keycode::At, shift, ctrl, alt) => Some(("@", false, shift, ctrl, alt)), - (Keycode::LBracket, false, ctrl, alt) => Some(("[", false, false, ctrl, alt)), - (Keycode::LBracket, true, ctrl, alt) => Some(("{", false, false, ctrl, alt)), - (Keycode::Backslash, false, ctrl, alt) => Some(("\\", false, false, ctrl, alt)), - (Keycode::Backslash, true, ctrl, alt) => Some(("|", false, false, ctrl, alt)), - (Keycode::RBracket, false, ctrl, alt) => Some(("]", false, false, ctrl, alt)), - (Keycode::RBracket, true, ctrl, alt) => Some(("}", false, false, ctrl, alt)), - (Keycode::Caret, shift, ctrl, alt) => Some(("^", false, shift, ctrl, alt)), - (Keycode::Grave, false, ctrl, alt) => Some(("`", false, false, ctrl, alt)), - (Keycode::Grave, true, ctrl, alt) => Some(("~", false, false, ctrl, alt)), - (Keycode::A, shift, ctrl, alt) => Some(("a", false, shift, ctrl, alt)), - (Keycode::B, shift, ctrl, alt) => Some(("b", false, shift, ctrl, alt)), - (Keycode::C, shift, ctrl, alt) => Some(("c", false, shift, ctrl, alt)), - (Keycode::D, shift, ctrl, alt) => Some(("d", false, shift, ctrl, alt)), - (Keycode::E, shift, ctrl, alt) => Some(("e", false, shift, ctrl, alt)), - (Keycode::F, shift, ctrl, alt) => Some(("f", false, shift, ctrl, alt)), - (Keycode::G, shift, ctrl, alt) => Some(("g", false, shift, ctrl, alt)), - (Keycode::H, shift, ctrl, alt) => Some(("h", false, shift, ctrl, alt)), - (Keycode::I, shift, ctrl, alt) => Some(("i", false, shift, ctrl, alt)), - (Keycode::J, shift, ctrl, alt) => Some(("j", false, shift, ctrl, alt)), - (Keycode::K, shift, ctrl, alt) => Some(("k", false, shift, ctrl, alt)), - (Keycode::L, shift, ctrl, alt) => Some(("l", false, shift, ctrl, alt)), - (Keycode::M, shift, ctrl, alt) => Some(("m", false, shift, ctrl, alt)), - (Keycode::N, shift, ctrl, alt) => Some(("n", false, shift, ctrl, alt)), - (Keycode::O, shift, ctrl, alt) => Some(("o", false, shift, ctrl, alt)), - (Keycode::P, shift, ctrl, alt) => Some(("p", false, shift, ctrl, alt)), - (Keycode::Q, shift, ctrl, alt) => Some(("q", false, shift, ctrl, alt)), - (Keycode::R, shift, ctrl, alt) => Some(("r", false, shift, ctrl, alt)), - (Keycode::S, shift, ctrl, alt) => Some(("s", false, shift, ctrl, alt)), - (Keycode::T, shift, ctrl, alt) => Some(("t", false, shift, ctrl, alt)), - (Keycode::U, shift, ctrl, alt) => Some(("u", false, shift, ctrl, alt)), - (Keycode::V, shift, ctrl, alt) => Some(("v", false, shift, ctrl, alt)), - (Keycode::W, shift, ctrl, alt) => Some(("w", false, shift, ctrl, alt)), - (Keycode::X, shift, ctrl, alt) => Some(("x", false, shift, ctrl, alt)), - (Keycode::Y, shift, ctrl, alt) => Some(("y", false, shift, ctrl, alt)), - (Keycode::Z, shift, ctrl, alt) => Some(("z", false, shift, ctrl, alt)), - (Keycode::Delete, shift, ctrl, alt) => Some(("Delete", true, shift, ctrl, alt)), - (Keycode::F1, shift, ctrl, alt) => Some(("F1", true, shift, ctrl, alt)), - (Keycode::F2, shift, ctrl, alt) => Some(("F2", true, shift, ctrl, alt)), - (Keycode::F3, shift, ctrl, alt) => Some(("F3", true, shift, ctrl, alt)), - (Keycode::F4, shift, ctrl, alt) => Some(("F4", true, shift, ctrl, alt)), - (Keycode::F5, shift, ctrl, alt) => Some(("F5", true, shift, ctrl, alt)), - (Keycode::F6, shift, ctrl, alt) => Some(("F6", true, shift, ctrl, alt)), - (Keycode::F7, shift, ctrl, alt) => Some(("F7", true, shift, ctrl, alt)), - (Keycode::F8, shift, ctrl, alt) => Some(("F8", true, shift, ctrl, alt)), - (Keycode::F9, shift, ctrl, alt) => Some(("F9", true, shift, ctrl, alt)), - (Keycode::F10, shift, ctrl, alt) => Some(("F10", true, shift, ctrl, alt)), - (Keycode::F11, shift, ctrl, alt) => Some(("F11", true, shift, ctrl, alt)), - (Keycode::F12, shift, ctrl, alt) => Some(("F12", true, shift, ctrl, alt)), - (Keycode::Snapshot, _, _, _) => unsupported_key(Keycode::Snapshot), - (Keycode::Pause, _, _, _) => unsupported_key(Keycode::Pause), - (Keycode::Insert, shift, ctrl, alt) => Some(("Insert", true, shift, ctrl, alt)), - (Keycode::Home, shift, ctrl, alt) => Some(("Home", true, shift, ctrl, alt)), - (Keycode::PageUp, shift, ctrl, alt) => Some(("PageUp", true, shift, ctrl, alt)), - (Keycode::End, shift, ctrl, alt) => Some(("End", true, shift, ctrl, alt)), - (Keycode::PageDown, shift, ctrl, alt) => Some(("PageDown", true, shift, ctrl, alt)), - (Keycode::Right, shift, ctrl, alt) => Some(("Right", true, shift, ctrl, alt)), - (Keycode::Left, shift, ctrl, alt) => Some(("Left", true, shift, ctrl, alt)), - (Keycode::Down, shift, ctrl, alt) => Some(("Down", true, shift, ctrl, alt)), - (Keycode::Up, shift, ctrl, alt) => Some(("Up", true, shift, ctrl, alt)), - (Keycode::Numpad0, shift, ctrl, alt) => Some(("0", false, shift, ctrl, alt)), - (Keycode::Numpad1, shift, ctrl, alt) => Some(("1", false, shift, ctrl, alt)), - (Keycode::Numpad2, shift, ctrl, alt) => Some(("2", false, shift, ctrl, alt)), - (Keycode::Numpad3, shift, ctrl, alt) => Some(("3", false, shift, ctrl, alt)), - (Keycode::Numpad4, shift, ctrl, alt) => Some(("4", false, shift, ctrl, alt)), - (Keycode::Numpad5, shift, ctrl, alt) => Some(("5", false, shift, ctrl, alt)), - (Keycode::Numpad6, shift, ctrl, alt) => Some(("6", false, shift, ctrl, alt)), - (Keycode::Numpad7, shift, ctrl, alt) => Some(("7", false, shift, ctrl, alt)), - (Keycode::Numpad8, shift, ctrl, alt) => Some(("8", false, shift, ctrl, alt)), - (Keycode::Numpad9, shift, ctrl, alt) => Some(("9", false, shift, ctrl, alt)), - (Keycode::Apps, _, _, _) => unsupported_key(Keycode::Apps), - (Keycode::Power, _, _, _) => unsupported_key(Keycode::Power), - (Keycode::F13, shift, ctrl, alt) => Some(("F13", true, shift, ctrl, alt)), - (Keycode::F14, shift, ctrl, alt) => Some(("F14", true, shift, ctrl, alt)), - (Keycode::F15, shift, ctrl, alt) => Some(("F15", true, shift, ctrl, alt)), - (Keycode::F16, shift, ctrl, alt) => Some(("F16", true, shift, ctrl, alt)), - (Keycode::F17, shift, ctrl, alt) => Some(("F17", true, shift, ctrl, alt)), - (Keycode::F18, shift, ctrl, alt) => Some(("F18", true, shift, ctrl, alt)), - (Keycode::F19, shift, ctrl, alt) => Some(("F19", true, shift, ctrl, alt)), - (Keycode::F20, shift, ctrl, alt) => Some(("F20", true, shift, ctrl, alt)), - (Keycode::F21, shift, ctrl, alt) => Some(("F21", true, shift, ctrl, alt)), - (Keycode::F22, shift, ctrl, alt) => Some(("F22", true, shift, ctrl, alt)), - (Keycode::F23, shift, ctrl, alt) => Some(("F23", true, shift, ctrl, alt)), - (Keycode::F24, shift, ctrl, alt) => Some(("F24", true, shift, ctrl, alt)), - (Keycode::Cut, _, _, _) => unsupported_key(Keycode::Cut), - (Keycode::Copy, _, _, _) => unsupported_key(Keycode::Copy), - (Keycode::Paste, _, _, _) => unsupported_key(Keycode::Paste), - (Keycode::Mute, _, _, _) => unsupported_key(Keycode::Mute), - (Keycode::VolumeUp, _, _, _) => unsupported_key(Keycode::VolumeUp), - (Keycode::VolumeDown, _, _, _) => unsupported_key(Keycode::VolumeDown), - (Keycode::Sysrq, _, _, _) => unsupported_key(Keycode::Sysrq), - (Keycode::LControl, _, _, _) => None, - (Keycode::LShift, _, _, _) => None, - (Keycode::LAlt, _, _, _) => None, - (Keycode::RControl, _, _, _) => None, - (Keycode::RShift, _, _, _) => None, - (Keycode::RAlt, _, _, _) => None, - (Keycode::MediaStop, _, _, _) => unsupported_key(Keycode::MediaStop), - (Keycode::MediaSelect, _, _, _) => unsupported_key(Keycode::MediaSelect), - (Keycode::Calculator, _, _, _) => unsupported_key(Keycode::Calculator), - (Keycode::MyComputer, _, _, _) => unsupported_key(Keycode::MyComputer), - (Keycode::WebSearch, _, _, _) => unsupported_key(Keycode::WebSearch), - (Keycode::WebHome, _, _, _) => unsupported_key(Keycode::WebHome), - (Keycode::WebBack, _, _, _) => unsupported_key(Keycode::WebBack), - (Keycode::WebForward, _, _, _) => unsupported_key(Keycode::WebForward), - (Keycode::NavigateBackward, _, _, _) => unsupported_key(Keycode::NavigateBackward), - (Keycode::NavigateForward, _, _, _) => unsupported_key(Keycode::NavigateForward), - (Keycode::WebStop, _, _, _) => unsupported_key(Keycode::WebStop), - (Keycode::WebRefresh, _, _, _) => unsupported_key(Keycode::WebRefresh), - (Keycode::Sleep, _, _, _) => unsupported_key(Keycode::Sleep), - _ => None, - } -} +use crate::window::keyboard::{unsupported_key, Token}; +use skulpin::winit::event::VirtualKeyCode::{self, *}; + +/// Maps winit keyboard events to Vim tokens +pub fn handle_qwerty_layout(keycode: VirtualKeyCode, shift: bool) -> Option> { + let special = |text| Some(Token::new(text, true, true)); + let normal = |text| Some(Token::new(text, false, true)); + let partial = |text| Some(Token::new(text, false, false)); + match (keycode, shift) { + (Back, _) => special("BS"), + (Tab, _) => special("Tab"), + (Return, _) => special("Enter"), + (Escape, _) => special("Esc"), + (Space, _) => normal(" "), + (Apostrophe, false) => partial("'"), + (Apostrophe, true) => partial("\""), + (Comma, false) => normal(","), + (Comma, true) => special("lt"), + (Minus, false) => partial("-"), + (Minus, true) => partial("_"), + (Period, false) => partial("."), + (Period, true) => partial(">"), + (Slash, false) => partial("/"), + (Slash, true) => partial("?"), + (Key0, false) => normal("0"), + (Key0, true) => special(")"), + (Key1, false) => normal("1"), + (Key1, true) => special("!"), + (Key2, false) => partial("2"), + (Key2, true) => partial("@"), + (Key3, false) => partial("3"), + (Key3, true) => partial("#"), + (Key4, false) => partial("4"), + (Key4, true) => partial("$"), + (Key5, false) => partial("5"), + (Key5, true) => partial("%"), + (Key6, false) => partial("6"), + (Key6, true) => partial("^"), + (Key7, false) => partial("7"), + (Key7, true) => partial("&"), + (Key8, false) => partial("8"), + (Key8, true) => partial("*"), + (Key9, false) => partial("9"), + (Key9, true) => partial("("), + (Colon, _) => normal(":"), + (Semicolon, false) => partial(";"), + (Semicolon, true) => partial(":"), + (Equals, false) => partial("="), + (Equals, true) => partial("+"), + (At, _) => normal("@"), + (LBracket, false) => partial("["), + (LBracket, true) => partial("{"), + (Backslash, false) => partial("\\"), + (Backslash, true) => partial("|"), + (RBracket, false) => partial("]"), + (RBracket, true) => partial("}"), + (Caret, _) => normal("^"), + (Grave, false) => partial("`"), + (Grave, true) => partial("~"), + (A, _) => normal("a"), + (B, _) => normal("b"), + (C, _) => normal("c"), + (D, _) => normal("d"), + (E, _) => normal("e"), + (F, _) => normal("f"), + (G, _) => normal("g"), + (H, _) => normal("h"), + (I, _) => normal("i"), + (J, _) => normal("j"), + (K, _) => normal("k"), + (L, _) => normal("l"), + (M, _) => normal("m"), + (N, _) => normal("n"), + (O, _) => normal("o"), + (P, _) => normal("p"), + (Q, _) => normal("q"), + (R, _) => normal("r"), + (S, _) => normal("s"), + (T, _) => normal("t"), + (U, _) => normal("u"), + (V, _) => normal("v"), + (W, _) => normal("w"), + (X, _) => normal("x"), + (Y, _) => normal("y"), + (Z, _) => normal("z"), + (Delete, _) => special("Delete"), + (F1, _) => special("F1"), + (F2, _) => special("F2"), + (F3, _) => special("F3"), + (F4, _) => special("F4"), + (F5, _) => special("F5"), + (F6, _) => special("F6"), + (F7, _) => special("F7"), + (F8, _) => special("F8"), + (F9, _) => special("F9"), + (F10, _) => special("F10"), + (F11, _) => special("F11"), + (F12, _) => special("F12"), + (Insert, _) => special("Insert"), + (Home, _) => special("Home"), + (PageUp, _) => special("PageUp"), + (End, _) => special("End"), + (PageDown, _) => special("PageDown"), + (Right, _) => special("Right"), + (Left, _) => special("Left"), + (Down, _) => special("Down"), + (Up, _) => special("Up"), + (Numpad0, _) => normal("0"), + (Numpad1, _) => normal("1"), + (Numpad2, _) => normal("2"), + (Numpad3, _) => normal("3"), + (Numpad4, _) => normal("4"), + (Numpad5, _) => normal("5"), + (Numpad6, _) => normal("6"), + (Numpad7, _) => normal("7"), + (Numpad8, _) => normal("8"), + (Numpad9, _) => normal("9"), + (F13, _) => special("F13"), + (F14, _) => special("F14"), + (F15, _) => special("F15"), + (F16, _) => special("F16"), + (F17, _) => special("F17"), + (F18, _) => special("F18"), + (F19, _) => special("F19"), + (F20, _) => special("F20"), + (F21, _) => special("F21"), + (F22, _) => special("F22"), + (F23, _) => special("F23"), + (F24, _) => special("F24"), + (LControl, _) => None, + (LShift, _) => None, + (LAlt, _) => None, + (RControl, _) => None, + (RShift, _) => None, + (RAlt, _) => None, + (keycode, _) => unsupported_key(keycode), + } +} diff --git a/src/window/winit/mod.rs b/src/window/winit/mod.rs index 3a2edec..423cbad 100644 --- a/src/window/winit/mod.rs +++ b/src/window/winit/mod.rs @@ -1,38 +1,36 @@ #[macro_use] mod layouts; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::mpsc::Receiver; -use std::sync::Arc; -use std::thread::sleep; -use std::time::{Duration, Instant}; - +use super::{handle_new_grid_size, keyboard::neovim_keybinding_string, settings::WindowSettings}; +use crate::{ + bridge::UiCommand, editor::WindowCommand, error_handling::ResultPanicExplanation, + redraw_scheduler::REDRAW_SCHEDULER, renderer::Renderer, settings::SETTINGS, +}; use crossfire::mpsc::TxUnbounded; use image::{load_from_memory, GenericImageView, Pixel}; -use log::{debug, error, info, trace}; -use skulpin::ash::prelude::VkResult; -use skulpin::winit; -use skulpin::winit::event::VirtualKeyCode as Keycode; -use skulpin::winit::event::{ - ElementState, Event, ModifiersState, MouseButton, MouseScrollDelta, WindowEvent, -}; -use skulpin::winit::event_loop::{ControlFlow, EventLoop}; -use skulpin::winit::window::{Fullscreen, Icon}; +use layouts::handle_qwerty_layout; use skulpin::{ + ash::prelude::VkResult, + winit::{ + self, + event::{ + ElementState, Event, ModifiersState, MouseButton, MouseScrollDelta, + VirtualKeyCode as Keycode, WindowEvent, + }, + event_loop::{ControlFlow, EventLoop}, + window::{Fullscreen, Icon}, + }, CoordinateSystem, LogicalSize, PhysicalSize, PresentMode, Renderer as SkulpinRenderer, RendererBuilder, Window, WinitWindow, }; - -use super::handle_new_grid_size; -pub use super::keyboard; -use super::settings::*; -use crate::bridge::UiCommand; -use crate::editor::WindowCommand; -use crate::error_handling::ResultPanicExplanation; -use crate::redraw_scheduler::REDRAW_SCHEDULER; -use crate::renderer::Renderer; -use crate::settings::*; -use layouts::produce_neovim_keybinding_string; +use std::{ + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::Receiver, + Arc, + }, + time::{Duration, Instant}, +}; #[derive(RustEmbed)] #[folder = "assets/"] @@ -49,7 +47,6 @@ pub struct WinitWindowWrapper { current_modifiers: Option, title: String, previous_size: LogicalSize, - transparency: f32, fullscreen: bool, cached_size: LogicalSize, cached_position: LogicalSize, @@ -110,14 +107,15 @@ impl WinitWindowWrapper { modifiers: Option, ) { if keycode.is_some() { - trace!( + log::trace!( "Keyboard Input Received: keycode-{:?} modifiers-{:?} ", keycode, modifiers ); } - if let Some(keybinding_string) = produce_neovim_keybinding_string(keycode, None, modifiers) + if let Some(keybinding_string) = + neovim_keybinding_string(keycode, None, modifiers, handle_qwerty_layout) { self.ui_command_sender .send(UiCommand::Keyboard(keybinding_string)) @@ -358,7 +356,7 @@ impl WinitWindowWrapper { let ui_command_sender = self.ui_command_sender.clone(); if REDRAW_SCHEDULER.should_draw() || SETTINGS.get::().no_idle { - debug!("Render Triggered"); + log::debug!("Render Triggered"); let renderer = &mut self.renderer; self.skulpin_renderer.draw( @@ -394,7 +392,7 @@ pub fn start_loop( } Icon::from_rgba(rgba, width, height).expect("Failed to create icon object") }; - info!("icon created"); + log::info!("icon created"); let event_loop = EventLoop::new(); let winit_window = winit::window::WindowBuilder::new() @@ -406,9 +404,7 @@ pub fn start_loop( .with_window_icon(Some(icon)) .build(&event_loop) .expect("Failed to create window"); - info!("window created"); - - let scale_factor = winit_window.scale_factor(); + log::info!("window created"); let skulpin_renderer = { let winit_window_wrapper = WinitWindow::new(&winit_window); @@ -435,7 +431,6 @@ pub fn start_loop( current_modifiers: None, title: String::from("Neovide"), previous_size: logical_size, - transparency: 1.0, fullscreen: false, cached_size: LogicalSize::new(0, 0), cached_position: LogicalSize::new(0, 0), @@ -445,7 +440,7 @@ pub fn start_loop( }; let mut was_animating = false; - let mut previous_frame_start = Instant::now(); + let previous_frame_start = Instant::now(); event_loop.run(move |e, _window_target, control_flow| { if !running.load(Ordering::Relaxed) { @@ -484,7 +479,7 @@ pub fn start_loop( was_animating = animating; } Err(error) => { - error!("Render failed: {}", error); + log::error!("Render failed: {}", error); window_wrapper.running.store(false, Ordering::Relaxed); return; }