diff --git a/CHANGELOG.md b/CHANGELOG.md index b348b372..0f12daea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Warnings for unused configuration file options - Config option `persist` in `hints` config section - Support for dynamically loading conpty.dll on Windows +- Support for keybindings with dead keys +- `Back`/`Forward` mouse buttons support in bindings ### Changed @@ -29,6 +31,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Deprecated config option `key_bindings`, use `keyboard.bindings` - Deprecated config option `mouse_bindings`, use `mouse.bindings` - The default colorscheme is now based on base16 classic dark +- IME popup now tries to not obscure the current cursor line + +### Fixed + +- Unconditional query of xdg-portal settings on Wayland +- `Maximized` startup mode not filling the screen properly on GNOME Wayland +- `OptionAsAlt` with `OnlyLeft`/`OnlyRight` settings not working properly on macOS +- Default Vi key bindings for `Last`/`First` actions not working on X11/Wayland ### Removed diff --git a/Cargo.lock b/Cargo.lock index 5017ba86..b45e2414 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ "serde_yaml", "toml 0.7.4", "unicode-width", - "wayland-client", + "wayland-client 0.29.5", "windows-sys 0.48.0", "winit", "x11-dl", @@ -184,6 +184,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "autocfg" version = "1.1.0" @@ -523,6 +529,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "cursor-icon" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740bb192a8e2d1350119916954f4409ee7f62f149b536911eeb78ba5a20526bf" +dependencies = [ + "serde", +] + [[package]] name = "dirs" version = "5.0.1" @@ -897,9 +912,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -957,9 +969,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1108,6 +1120,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1261,7 +1282,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -1274,7 +1295,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -1286,6 +1307,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", + "memoffset 0.7.1", "static_assertions", ] @@ -1506,6 +1528,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-xml" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.28" @@ -1617,14 +1648,13 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sctk-adwaita" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" +checksum = "2704a44480b79e10d2185d1d246e86b02e177e33bdaaaab3b1f65fdf13771448" dependencies = [ "crossfont", "log", - "memmap2", - "smithay-client-toolkit", + "smithay-client-toolkit 0.17.0", "tiny-skia", ] @@ -1775,16 +1805,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" dependencies = [ "bitflags 1.3.2", - "calloop", "dlib", "lazy_static", "log", "memmap2", "nix 0.24.3", "pkg-config", - "wayland-client", - "wayland-cursor", - "wayland-protocols", + "wayland-client 0.29.5", + "wayland-cursor 0.29.5", + "wayland-protocols 0.29.5", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1476c3d89bb67079264b88aaf4f14358353318397e083b7c4e8c14517f55de7" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.26.2", + "thiserror", + "wayland-backend", + "wayland-client 0.30.2", + "wayland-cursor 0.30.0", + "wayland-protocols 0.30.0", + "wayland-protocols-wlr", + "wayland-scanner 0.30.1", ] [[package]] @@ -1793,8 +1844,17 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" dependencies = [ - "smithay-client-toolkit", - "wayland-client", + "smithay-client-toolkit 0.16.0", + "wayland-client 0.29.5", +] + +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", ] [[package]] @@ -1873,7 +1933,6 @@ dependencies = [ "arrayvec", "bytemuck", "cfg-if 1.0.0", - "png", "tiny-skia-path", ] @@ -1937,6 +1996,12 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "unicode-width" version = "0.1.10" @@ -2021,9 +2086,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2031,9 +2096,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -2045,10 +2110,22 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen-macro" -version = "0.2.86" +name = "wasm-bindgen-futures" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2056,9 +2133,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -2069,9 +2146,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "wayland-backend" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b48e27457e8da3b2260ac60d0a94512f5cba36448679f3747c0865b7893ed8" +dependencies = [ + "cc", + "downcast-rs", + "io-lifetimes", + "nix 0.26.2", + "scoped-tls", + "smallvec", + "wayland-sys 0.30.1", +] [[package]] name = "wayland-client" @@ -2085,10 +2177,23 @@ dependencies = [ "nix 0.24.3", "scoped-tls", "wayland-commons", - "wayland-scanner", + "wayland-scanner 0.29.5", "wayland-sys 0.29.5", ] +[[package]] +name = "wayland-client" +version = "0.30.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489c9654770f674fc7e266b3c579f4053d7551df0ceb392f153adb1f9ed06ac8" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "nix 0.26.2", + "wayland-backend", + "wayland-scanner 0.30.1", +] + [[package]] name = "wayland-commons" version = "0.29.5" @@ -2108,7 +2213,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ "nix 0.24.3", - "wayland-client", + "wayland-client 0.29.5", + "xcursor", +] + +[[package]] +name = "wayland-cursor" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0c3a0d5b4b688b07b0442362d3ed6bf04724fcc16cd69ab6285b90dbc487aa" +dependencies = [ + "nix 0.26.2", + "wayland-client 0.30.2", "xcursor", ] @@ -2119,9 +2235,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" dependencies = [ "bitflags 1.3.2", - "wayland-client", + "wayland-client 0.29.5", "wayland-commons", - "wayland-scanner", + "wayland-scanner 0.29.5", +] + +[[package]] +name = "wayland-protocols" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fefbeb8a360abe67ab7c2efe1d297a1a50ee011f5460791bc18870c26bb84e2" +dependencies = [ + "bitflags 1.3.2", + "wayland-backend", + "wayland-client 0.30.2", + "wayland-scanner 0.30.1", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce991093320e4a6a525876e6b629ab24da25f9baef0c2e0080ad173ec89588a" +dependencies = [ + "bitflags 1.3.2", + "wayland-backend", + "wayland-client 0.30.2", + "wayland-protocols 0.30.0", + "wayland-scanner 0.30.1", ] [[package]] @@ -2135,6 +2276,17 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "wayland-scanner" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b873b257fbc32ec909c0eb80dea312076a67014e65e245f5eb69a6b8ab330e" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + [[package]] name = "wayland-sys" version = "0.29.5" @@ -2160,14 +2312,25 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19353897b48e2c4d849a2d73cb0aeb16dc2be4e00c565abfc11eb65a806e47de" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.2.8" @@ -2354,21 +2517,26 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winit" -version = "0.28.6" +version = "0.29.0-beta.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866db3f712fffba75d31bf0cdecf357c8aeafd158c5b7ab51dba2a2b2d47f196" +checksum = "2f1afaf8490cc3f1309520ebb53a4cd3fc3642c7df8064a4b074bb9867998d44" dependencies = [ "android-activity", - "bitflags 1.3.2", + "atomic-waker", + "bitflags 2.3.1", + "calloop", "cfg_aliases", "core-foundation", "core-graphics", + "cursor-icon", "dispatch", - "instant", + "fnv", + "js-sys", "libc", "log", - "mio 0.8.8", + "memmap2", "ndk", + "ndk-sys", "objc2", "once_cell", "orbclient", @@ -2377,15 +2545,19 @@ dependencies = [ "redox_syscall 0.3.5", "sctk-adwaita", "serde", - "smithay-client-toolkit", + "smithay-client-toolkit 0.17.0", + "smol_str", + "unicode-segmentation", "wasm-bindgen", - "wayland-client", - "wayland-commons", - "wayland-protocols", - "wayland-scanner", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client 0.30.2", + "wayland-protocols 0.30.0", "web-sys", - "windows-sys 0.45.0", + "web-time", + "windows-sys 0.48.0", "x11-dl", + "xkbcommon-dl", ] [[package]] @@ -2485,6 +2657,25 @@ dependencies = [ "home", ] +[[package]] +name = "xkbcommon-dl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "640e2c59cabea03b04fb0a34ca0fa7caaa1a50f7e588776fcda43a6a8ca28165" +dependencies = [ + "bitflags 2.3.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + [[package]] name = "xml-rs" version = "0.8.14" diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index da39e754..5ab00f2b 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -41,7 +41,7 @@ serde_json = "1" serde_yaml = "0.8" toml = "0.7.1" unicode-width = "0.1" -winit = { version = "0.28.2", default-features = false, features = ["serde"] } +winit = { version = "0.29.0-beta.0", default-features = false, features = ["serde"] } [build-dependencies] gl_generator = "0.14.0" diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 8fd16361..b6cf9e50 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -6,8 +6,10 @@ use bitflags::bitflags; use serde::de::{self, Error as SerdeError, MapAccess, Unexpected, Visitor}; use serde::{Deserialize, Deserializer}; use toml::Value as SerdeValue; -use winit::event::VirtualKeyCode::*; -use winit::event::{ModifiersState, MouseButton, VirtualKeyCode}; +use winit::event::MouseButton; +use winit::keyboard::Key::*; +use winit::keyboard::{Key, KeyCode, KeyLocation, ModifiersState}; +use winit::platform::scancode::KeyCodeExtScancode; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; @@ -41,7 +43,7 @@ pub struct Binding { } /// Bindings that are triggered by a keyboard key. -pub type KeyBinding = Binding; +pub type KeyBinding = Binding; /// Bindings that are triggered by a mouse button. pub type MouseBinding = Binding; @@ -309,32 +311,11 @@ pub enum MouseAction { } macro_rules! bindings { - ( - KeyBinding; - $( - $key:ident - $(,$mods:expr)* - $(,+$mode:expr)* - $(,~$notmode:expr)* - ;$action:expr - );* - $(;)* - ) => {{ - bindings!( - KeyBinding; - $( - Key::Keycode($key) - $(,$mods)* - $(,+$mode)* - $(,~$notmode)* - ;$action - );* - ) - }}; ( $ty:ident; $( $key:expr + $(=>$location:expr)? $(,$mods:expr)* $(,+$mode:expr)* $(,~$notmode:expr)* @@ -353,7 +334,7 @@ macro_rules! bindings { $(_notmode.insert($notmode);)* v.push($ty { - trigger: $key, + trigger: trigger!($ty, $key, $($location)?), mods: _mods, mode: _mode, notmode: _notmode, @@ -365,199 +346,147 @@ macro_rules! bindings { }}; } +macro_rules! trigger { + (KeyBinding, $key:literal, $location:expr) => {{ + BindingKey::Keycode { key: Character($key.into()), location: $location } + }}; + (KeyBinding, $key:literal,) => {{ + BindingKey::Keycode { key: Character($key.into()), location: KeyLocation::Standard } + }}; + (KeyBinding, $key:expr,) => {{ + BindingKey::Keycode { key: $key, location: KeyLocation::Standard } + }}; + ($ty:ident, $key:expr,) => {{ + $key + }}; +} + pub fn default_mouse_bindings() -> Vec { bindings!( MouseBinding; - MouseButton::Right; MouseAction::ExpandSelection; - MouseButton::Right, ModifiersState::CTRL; MouseAction::ExpandSelection; - MouseButton::Middle, ~BindingMode::VI; Action::PasteSelection; + MouseButton::Right; MouseAction::ExpandSelection; + MouseButton::Right, ModifiersState::CONTROL; MouseAction::ExpandSelection; + MouseButton::Middle, ~BindingMode::VI; Action::PasteSelection; ) } pub fn default_key_bindings() -> Vec { let mut bindings = bindings!( KeyBinding; - Copy; Action::Copy; + Copy; Action::Copy; Copy, +BindingMode::VI; Action::ClearSelection; Paste, ~BindingMode::VI; Action::Paste; - L, ModifiersState::CTRL; Action::ClearLogNotice; - L, ModifiersState::CTRL, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x0c".into()); - Tab, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[Z".into()); - Back, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b\x7f".into()); - Back, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x7f".into()); - Home, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollToTop; - End, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollToBottom; - PageUp, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollPageUp; - PageDown, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollPageDown; - Home, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, - ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[1;2H".into()); - End, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, - ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[1;2F".into()); - PageUp, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, - ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[5;2~".into()); - PageDown, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, - ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[6;2~".into()); - Home, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOH".into()); - Home, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[H".into()); - End, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOF".into()); - End, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[F".into()); - Up, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOA".into()); - Up, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[A".into()); - Down, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOB".into()); - Down, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[B".into()); - Right, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOC".into()); - Right, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[C".into()); - Left, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1bOD".into()); - Left, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[D".into()); - Back, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x7f".into()); - Insert, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[2~".into()); - Delete, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[3~".into()); - PageUp, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[5~".into()); - PageDown, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[6~".into()); - F1, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOP".into()); - F2, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOQ".into()); - F3, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOR".into()); - F4, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOS".into()); - F5, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[15~".into()); - F6, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[17~".into()); - F7, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[18~".into()); - F8, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[19~".into()); - F9, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[20~".into()); - F10, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[21~".into()); - F11, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[23~".into()); - F12, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[24~".into()); - F13, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[25~".into()); - F14, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[26~".into()); - F15, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[28~".into()); - F16, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[29~".into()); - F17, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[31~".into()); - F18, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[32~".into()); - F19, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[33~".into()); - F20, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[34~".into()); - NumpadEnter, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\n".into()); - Space, ModifiersState::SHIFT | ModifiersState::CTRL, ~BindingMode::SEARCH; - Action::ToggleViMode; - Space, ModifiersState::SHIFT | ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToBottom; - Escape, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ClearSelection; - I, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ToggleViMode; - I, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToBottom; - C, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ToggleViMode; - Y, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollLineUp; - E, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollLineDown; - G, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToTop; - G, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollToBottom; - B, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollPageUp; - F, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollPageDown; - U, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollHalfPageUp; - D, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ScrollHalfPageDown; - Y, +BindingMode::VI, ~BindingMode::SEARCH; Action::Copy; - Y, +BindingMode::VI, ~BindingMode::SEARCH; - Action::ClearSelection; - Slash, +BindingMode::VI, ~BindingMode::SEARCH; - Action::SearchForward; - Slash, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - Action::SearchBackward; - V, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::ToggleNormalSelection; - V, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::ToggleLineSelection; - V, ModifiersState::CTRL, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::ToggleBlockSelection; - V, ModifiersState::ALT, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::ToggleSemanticSelection; - N, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::SearchNext; - N, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::SearchPrevious; - Return, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::Open; - Z, +BindingMode::VI, ~BindingMode::SEARCH; - ViAction::CenterAroundViCursor; - K, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Up; - J, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Down; - H, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Left; - L, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Right; - Up, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Up; - Down, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Down; - Left, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Left; - Right, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Right; - Key0, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::First; - Key4, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Last; - Key6, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::FirstOccupied; - H, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::High; - M, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Middle; - L, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Low; - B, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::SemanticLeft; - W, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::SemanticRight; - E, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::SemanticRightEnd; - B, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::WordLeft; - W, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::WordRight; - E, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::WordRightEnd; - Key5, ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; - ViMotion::Bracket; - Return, +BindingMode::SEARCH, +BindingMode::VI; - SearchAction::SearchConfirm; - Escape, +BindingMode::SEARCH; SearchAction::SearchCancel; - C, ModifiersState::CTRL, +BindingMode::SEARCH; SearchAction::SearchCancel; - U, ModifiersState::CTRL, +BindingMode::SEARCH; SearchAction::SearchClear; - W, ModifiersState::CTRL, +BindingMode::SEARCH; SearchAction::SearchDeleteWord; - P, ModifiersState::CTRL, +BindingMode::SEARCH; SearchAction::SearchHistoryPrevious; - N, ModifiersState::CTRL, +BindingMode::SEARCH; SearchAction::SearchHistoryNext; - Up, +BindingMode::SEARCH; SearchAction::SearchHistoryPrevious; - Down, +BindingMode::SEARCH; SearchAction::SearchHistoryNext; - Return, +BindingMode::SEARCH, ~BindingMode::VI; - SearchAction::SearchFocusNext; - Return, ModifiersState::SHIFT, +BindingMode::SEARCH, ~BindingMode::VI; - SearchAction::SearchFocusPrevious; + "l", ModifiersState::CONTROL; Action::ClearLogNotice; + "l", ModifiersState::CONTROL, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x0c".into()); + Tab, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[Z".into()); + Backspace, ModifiersState::ALT, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b\x7f".into()); + Backspace, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x7f".into()); + Home, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollToTop; + End, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollToBottom; + PageUp, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollPageUp; + PageDown, ModifiersState::SHIFT, ~BindingMode::ALT_SCREEN; Action::ScrollPageDown; + Home, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[1;2H".into()); + End, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[1;2F".into()); + PageUp, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[5;2~".into()); + PageDown, ModifiersState::SHIFT, +BindingMode::ALT_SCREEN, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[6;2~".into()); + Home, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOH".into()); + Home, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[H".into()); + End, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOF".into()); + End, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[F".into()); + ArrowUp, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOA".into()); + ArrowUp, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[A".into()); + ArrowDown, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOB".into()); + ArrowDown, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[B".into()); + ArrowRight, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOC".into()); + ArrowRight, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[C".into()); + ArrowLeft, +BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOD".into()); + ArrowLeft, ~BindingMode::APP_CURSOR, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[D".into()); + Backspace, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x7f".into()); + Insert, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[2~".into()); + Delete, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[3~".into()); + PageUp, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[5~".into()); + PageDown, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[6~".into()); + F1, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOP".into()); + F2, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOQ".into()); + F3, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOR".into()); + F4, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1bOS".into()); + F5, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[15~".into()); + F6, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[17~".into()); + F7, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[18~".into()); + F8, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[19~".into()); + F9, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[20~".into()); + F10, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[21~".into()); + F11, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[23~".into()); + F12, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[24~".into()); + F13, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[25~".into()); + F14, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[26~".into()); + F15, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[28~".into()); + F16, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[29~".into()); + F17, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[31~".into()); + F18, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[32~".into()); + F19, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[33~".into()); + F20, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[34~".into()); + + // Vi mode. + Space, ModifiersState::SHIFT | ModifiersState::CONTROL, ~BindingMode::SEARCH; Action::ToggleViMode; + Space, ModifiersState::SHIFT | ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToBottom; + Escape, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; + "i", +BindingMode::VI, ~BindingMode::SEARCH; Action::ToggleViMode; + "i", +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToBottom; + "c", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ToggleViMode; + "y", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollLineUp; + "e", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollLineDown; + "g", +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToTop; + "g", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollToBottom; + "b", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollPageUp; + "f", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollPageDown; + "u", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollHalfPageUp; + "d", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; Action::ScrollHalfPageDown; + "y", +BindingMode::VI, ~BindingMode::SEARCH; Action::Copy; + "y", +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; + "/", +BindingMode::VI, ~BindingMode::SEARCH; Action::SearchForward; + "/", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::SearchBackward; + "v", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleNormalSelection; + "v", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleLineSelection; + "v", ModifiersState::CONTROL, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleBlockSelection; + "v", ModifiersState::ALT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::ToggleSemanticSelection; + "n", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::SearchNext; + "n", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::SearchPrevious; + Enter, +BindingMode::VI, ~BindingMode::SEARCH; ViAction::Open; + "z", +BindingMode::VI, ~BindingMode::SEARCH; ViAction::CenterAroundViCursor; + "k", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Up; + "j", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Down; + "h", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Left; + "l", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Right; + ArrowUp, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Up; + ArrowDown, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Down; + ArrowLeft, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Left; + ArrowRight, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Right; + "0", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::First; + "4", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Last; + "6", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::FirstOccupied; + "H", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::High; + "M", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Middle; + "L", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Low; + "b", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::SemanticLeft; + "w", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::SemanticRight; + "e", +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::SemanticRightEnd; + "b", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::WordLeft; + "w", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::WordRight; + "e", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::WordRightEnd; + "5", ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; ViMotion::Bracket; + Enter, +BindingMode::VI, +BindingMode::SEARCH; SearchAction::SearchConfirm; + // Plain search. + Escape, +BindingMode::SEARCH; SearchAction::SearchCancel; + "c", ModifiersState::CONTROL, +BindingMode::SEARCH; SearchAction::SearchCancel; + "u", ModifiersState::CONTROL, +BindingMode::SEARCH; SearchAction::SearchClear; + "w", ModifiersState::CONTROL, +BindingMode::SEARCH; SearchAction::SearchDeleteWord; + "p", ModifiersState::CONTROL, +BindingMode::SEARCH; SearchAction::SearchHistoryPrevious; + "n", ModifiersState::CONTROL, +BindingMode::SEARCH; SearchAction::SearchHistoryNext; + ArrowUp, +BindingMode::SEARCH; SearchAction::SearchHistoryPrevious; + ArrowDown, +BindingMode::SEARCH; SearchAction::SearchHistoryNext; + Enter, +BindingMode::SEARCH, ~BindingMode::VI; SearchAction::SearchFocusNext; + Enter, ModifiersState::SHIFT, +BindingMode::SEARCH, ~BindingMode::VI; SearchAction::SearchFocusPrevious; ); // Code Modifiers @@ -576,82 +505,52 @@ pub fn default_key_bindings() -> Vec { ModifiersState::SHIFT, ModifiersState::ALT, ModifiersState::SHIFT | ModifiersState::ALT, - ModifiersState::CTRL, - ModifiersState::SHIFT | ModifiersState::CTRL, - ModifiersState::ALT | ModifiersState::CTRL, - ModifiersState::SHIFT | ModifiersState::ALT | ModifiersState::CTRL, + ModifiersState::CONTROL, + ModifiersState::SHIFT | ModifiersState::CONTROL, + ModifiersState::ALT | ModifiersState::CONTROL, + ModifiersState::SHIFT | ModifiersState::ALT | ModifiersState::CONTROL, ]; for (index, mods) in modifiers.drain(..).enumerate() { let modifiers_code = index + 2; bindings.extend(bindings!( KeyBinding; - Delete, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[3;{}~", modifiers_code)); - Up, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}A", modifiers_code)); - Down, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}B", modifiers_code)); - Right, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}C", modifiers_code)); - Left, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}D", modifiers_code)); - F1, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}P", modifiers_code)); - F2, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}Q", modifiers_code)); - F3, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}R", modifiers_code)); - F4, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}S", modifiers_code)); - F5, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[15;{}~", modifiers_code)); - F6, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[17;{}~", modifiers_code)); - F7, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[18;{}~", modifiers_code)); - F8, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[19;{}~", modifiers_code)); - F9, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[20;{}~", modifiers_code)); - F10, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[21;{}~", modifiers_code)); - F11, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[23;{}~", modifiers_code)); - F12, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[24;{}~", modifiers_code)); - F13, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[25;{}~", modifiers_code)); - F14, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[26;{}~", modifiers_code)); - F15, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[28;{}~", modifiers_code)); - F16, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[29;{}~", modifiers_code)); - F17, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[31;{}~", modifiers_code)); - F18, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[32;{}~", modifiers_code)); - F19, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[33;{}~", modifiers_code)); - F20, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[34;{}~", modifiers_code)); + Delete, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[3;{}~", modifiers_code)); + ArrowUp, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}A", modifiers_code)); + ArrowDown, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}B", modifiers_code)); + ArrowRight, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}C", modifiers_code)); + ArrowLeft, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}D", modifiers_code)); + F1, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}P", modifiers_code)); + F2, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}Q", modifiers_code)); + F3, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}R", modifiers_code)); + F4, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}S", modifiers_code)); + F5, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[15;{}~", modifiers_code)); + F6, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[17;{}~", modifiers_code)); + F7, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[18;{}~", modifiers_code)); + F8, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[19;{}~", modifiers_code)); + F9, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[20;{}~", modifiers_code)); + F10, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[21;{}~", modifiers_code)); + F11, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[23;{}~", modifiers_code)); + F12, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[24;{}~", modifiers_code)); + F13, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[25;{}~", modifiers_code)); + F14, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[26;{}~", modifiers_code)); + F15, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[28;{}~", modifiers_code)); + F16, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[29;{}~", modifiers_code)); + F17, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[31;{}~", modifiers_code)); + F18, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[32;{}~", modifiers_code)); + F19, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[33;{}~", modifiers_code)); + F20, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[34;{}~", modifiers_code)); )); // We're adding the following bindings with `Shift` manually above, so skipping them here. if modifiers_code != 2 { bindings.extend(bindings!( KeyBinding; - Insert, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[2;{}~", modifiers_code)); - PageUp, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[5;{}~", modifiers_code)); - PageDown, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[6;{}~", modifiers_code)); - End, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}F", modifiers_code)); - Home, mods, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc(format!("\x1b[1;{}H", modifiers_code)); + Insert, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[2;{}~", modifiers_code)); + PageUp, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[5;{}~", modifiers_code)); + PageDown, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[6;{}~", modifiers_code)); + End, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}F", modifiers_code)); + Home, mods, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc(format!("\x1b[1;{}H", modifiers_code)); )); } } @@ -665,21 +564,18 @@ pub fn default_key_bindings() -> Vec { fn common_keybindings() -> Vec { bindings!( KeyBinding; - V, ModifiersState::CTRL | ModifiersState::SHIFT, ~BindingMode::VI; Action::Paste; - C, ModifiersState::CTRL | ModifiersState::SHIFT; Action::Copy; - F, ModifiersState::CTRL | ModifiersState::SHIFT, ~BindingMode::SEARCH; - Action::SearchForward; - B, ModifiersState::CTRL | ModifiersState::SHIFT, ~BindingMode::SEARCH; - Action::SearchBackward; - C, ModifiersState::CTRL | ModifiersState::SHIFT, - +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; - Insert, ModifiersState::SHIFT, ~BindingMode::VI; Action::PasteSelection; - Key0, ModifiersState::CTRL; Action::ResetFontSize; - Equals, ModifiersState::CTRL; Action::IncreaseFontSize; - Plus, ModifiersState::CTRL; Action::IncreaseFontSize; - NumpadAdd, ModifiersState::CTRL; Action::IncreaseFontSize; - Minus, ModifiersState::CTRL; Action::DecreaseFontSize; - NumpadSubtract, ModifiersState::CTRL; Action::DecreaseFontSize; + "c", ModifiersState::CONTROL | ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; + "v", ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::VI; Action::Paste; + "f", ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::SEARCH; Action::SearchForward; + "b", ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::SEARCH; Action::SearchBackward; + Insert, ModifiersState::SHIFT, ~BindingMode::VI; Action::PasteSelection; + "c", ModifiersState::CONTROL | ModifiersState::SHIFT; Action::Copy; + "0", ModifiersState::CONTROL; Action::ResetFontSize; + "=", ModifiersState::CONTROL; Action::IncreaseFontSize; + "+", ModifiersState::CONTROL; Action::IncreaseFontSize; + "-", ModifiersState::CONTROL; Action::DecreaseFontSize; + "+" => KeyLocation::Numpad, ModifiersState::CONTROL; Action::IncreaseFontSize; + "-" => KeyLocation::Numpad, ModifiersState::CONTROL; Action::DecreaseFontSize; ) } @@ -692,7 +588,7 @@ pub fn platform_key_bindings() -> Vec { pub fn platform_key_bindings() -> Vec { let mut bindings = bindings!( KeyBinding; - Return, ModifiersState::ALT; Action::ToggleFullscreen; + Enter, ModifiersState::ALT; Action::ToggleFullscreen; ); bindings.extend(common_keybindings()); bindings @@ -702,29 +598,27 @@ pub fn platform_key_bindings() -> Vec { pub fn platform_key_bindings() -> Vec { bindings!( KeyBinding; - Key0, ModifiersState::LOGO; Action::ResetFontSize; - Equals, ModifiersState::LOGO; Action::IncreaseFontSize; - Plus, ModifiersState::LOGO; Action::IncreaseFontSize; - NumpadAdd, ModifiersState::LOGO; Action::IncreaseFontSize; - Minus, ModifiersState::LOGO; Action::DecreaseFontSize; - NumpadSubtract, ModifiersState::LOGO; Action::DecreaseFontSize; - Insert, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x1b[2;2~".into()); - K, ModifiersState::LOGO, ~BindingMode::VI, ~BindingMode::SEARCH; - Action::Esc("\x0c".into()); - K, ModifiersState::LOGO, ~BindingMode::VI, ~BindingMode::SEARCH; Action::ClearHistory; - V, ModifiersState::LOGO, ~BindingMode::VI; Action::Paste; - N, ModifiersState::LOGO; Action::CreateNewWindow; - F, ModifiersState::CTRL | ModifiersState::LOGO; Action::ToggleFullscreen; - C, ModifiersState::LOGO; Action::Copy; - C, ModifiersState::LOGO, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; - H, ModifiersState::LOGO; Action::Hide; - H, ModifiersState::LOGO | ModifiersState::ALT; Action::HideOtherApplications; - M, ModifiersState::LOGO; Action::Minimize; - Q, ModifiersState::LOGO; Action::Quit; - W, ModifiersState::LOGO; Action::Quit; - F, ModifiersState::LOGO, ~BindingMode::SEARCH; Action::SearchForward; - B, ModifiersState::LOGO, ~BindingMode::SEARCH; Action::SearchBackward; + "c", ModifiersState::SUPER, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection; + Insert, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[2;2~".into()); + "0", ModifiersState::SUPER; Action::ResetFontSize; + "=", ModifiersState::SUPER; Action::IncreaseFontSize; + "+", ModifiersState::SUPER; Action::IncreaseFontSize; + "-", ModifiersState::SUPER; Action::DecreaseFontSize; + "k", ModifiersState::SUPER, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x0c".into()); + "k", ModifiersState::SUPER, ~BindingMode::VI, ~BindingMode::SEARCH; Action::ClearHistory; + "v", ModifiersState::SUPER, ~BindingMode::VI; Action::Paste; + "n", ModifiersState::SUPER; Action::CreateNewWindow; + "f", ModifiersState::CONTROL | ModifiersState::SUPER; Action::ToggleFullscreen; + "c", ModifiersState::SUPER; Action::Copy; + "h", ModifiersState::SUPER; Action::Hide; + "h", ModifiersState::SUPER | ModifiersState::ALT; Action::HideOtherApplications; + "m", ModifiersState::SUPER; Action::Minimize; + "q", ModifiersState::SUPER; Action::Quit; + "w", ModifiersState::SUPER; Action::Quit; + "f", ModifiersState::SUPER, ~BindingMode::SEARCH; Action::SearchForward; + "b", ModifiersState::SUPER, ~BindingMode::SEARCH; Action::SearchBackward; + "+" => KeyLocation::Numpad, ModifiersState::SUPER; Action::IncreaseFontSize; + "-" => KeyLocation::Numpad, ModifiersState::SUPER; Action::DecreaseFontSize; ) } @@ -734,23 +628,83 @@ pub fn platform_key_bindings() -> Vec { vec![] } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub enum Key { - Scancode(u32), - Keycode(VirtualKeyCode), +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub enum BindingKey { + Scancode(KeyCode), + Keycode { key: Key, location: KeyLocation }, } -impl<'a> Deserialize<'a> for Key { +impl<'a> Deserialize<'a> for BindingKey { fn deserialize(deserializer: D) -> Result where D: Deserializer<'a>, { let value = SerdeValue::deserialize(deserializer)?; match u32::deserialize(value.clone()) { - Ok(scancode) => Ok(Key::Scancode(scancode)), + Ok(scancode) => Ok(BindingKey::Scancode(KeyCode::from_scancode(scancode))), Err(_) => { - let keycode = VirtualKeyCode::deserialize(value).map_err(D::Error::custom)?; - Ok(Key::Keycode(keycode)) + let keycode = String::deserialize(value.clone()).map_err(D::Error::custom)?; + let (key, location) = if keycode.chars().count() == 1 { + (Key::Character(keycode.to_lowercase().into()), KeyLocation::Standard) + } else { + // Translate legacy winit codes into their modern counterparts. + match keycode.as_str() { + "Up" => (Key::ArrowUp, KeyLocation::Standard), + "Back" => (Key::Backspace, KeyLocation::Standard), + "Down" => (Key::ArrowDown, KeyLocation::Standard), + "Left" => (Key::ArrowLeft, KeyLocation::Standard), + "Right" => (Key::ArrowRight, KeyLocation::Standard), + "At" => (Key::Character("@".into()), KeyLocation::Standard), + "Colon" => (Key::Character(":".into()), KeyLocation::Standard), + "Period" => (Key::Character(".".into()), KeyLocation::Standard), + "Return" => (Key::Enter, KeyLocation::Standard), + "LBracket" => (Key::Character("[".into()), KeyLocation::Standard), + "RBracket" => (Key::Character("]".into()), KeyLocation::Standard), + "Semicolon" => (Key::Character(";".into()), KeyLocation::Standard), + "Backslash" => (Key::Character("\\".into()), KeyLocation::Standard), + "Plus" => (Key::Character("+".into()), KeyLocation::Standard), + "Comma" => (Key::Character(",".into()), KeyLocation::Standard), + "Slash" => (Key::Character("/".into()), KeyLocation::Standard), + "Equals" => (Key::Character("=".into()), KeyLocation::Standard), + "Minus" => (Key::Character("-".into()), KeyLocation::Standard), + "Asterisk" => (Key::Character("*".into()), KeyLocation::Standard), + "Key1" => (Key::Character("1".into()), KeyLocation::Standard), + "Key2" => (Key::Character("2".into()), KeyLocation::Standard), + "Key3" => (Key::Character("3".into()), KeyLocation::Standard), + "Key4" => (Key::Character("4".into()), KeyLocation::Standard), + "Key5" => (Key::Character("5".into()), KeyLocation::Standard), + "Key6" => (Key::Character("6".into()), KeyLocation::Standard), + "Key7" => (Key::Character("7".into()), KeyLocation::Standard), + "Key8" => (Key::Character("8".into()), KeyLocation::Standard), + "Key9" => (Key::Character("9".into()), KeyLocation::Standard), + "Key0" => (Key::Character("0".into()), KeyLocation::Standard), + + // Special case numpad. + "NumpadEnter" => (Key::Enter, KeyLocation::Numpad), + "NumpadAdd" => (Key::Character("+".into()), KeyLocation::Numpad), + "NumpadComma" => (Key::Character(",".into()), KeyLocation::Numpad), + "NumpadDivide" => (Key::Character("/".into()), KeyLocation::Numpad), + "NumpadEquals" => (Key::Character("=".into()), KeyLocation::Numpad), + "NumpadSubtract" => (Key::Character("-".into()), KeyLocation::Numpad), + "NumpadMultiply" => (Key::Character("*".into()), KeyLocation::Numpad), + "Numpad1" => (Key::Character("1".into()), KeyLocation::Numpad), + "Numpad2" => (Key::Character("2".into()), KeyLocation::Numpad), + "Numpad3" => (Key::Character("3".into()), KeyLocation::Numpad), + "Numpad4" => (Key::Character("4".into()), KeyLocation::Numpad), + "Numpad5" => (Key::Character("5".into()), KeyLocation::Numpad), + "Numpad6" => (Key::Character("6".into()), KeyLocation::Numpad), + "Numpad7" => (Key::Character("7".into()), KeyLocation::Numpad), + "Numpad8" => (Key::Character("8".into()), KeyLocation::Numpad), + "Numpad9" => (Key::Character("9".into()), KeyLocation::Numpad), + "Numpad0" => (Key::Character("0".into()), KeyLocation::Numpad), + _ => ( + Key::deserialize(value).map_err(D::Error::custom)?, + KeyLocation::Standard, + ), + } + }; + + Ok(BindingKey::Keycode { key, location }) }, } } @@ -891,7 +845,7 @@ impl<'a> Deserialize<'a> for MouseButtonWrapper { /// `KeyBinding` or `MouseBinding`. #[derive(PartialEq, Eq)] struct RawBinding { - key: Option, + key: Option, mouse: Option, mods: ModifiersState, mode: BindingMode, @@ -994,7 +948,7 @@ impl<'a> Deserialize<'a> for RawBinding { V: MapAccess<'a>, { let mut mods: Option = None; - let mut key: Option = None; + let mut key: Option = None; let mut chars: Option = None; let mut action: Option = None; let mut mode: Option = None; @@ -1014,7 +968,11 @@ impl<'a> Deserialize<'a> for RawBinding { let value = map.next_value::()?; match value.as_integer() { Some(scancode) => match u32::try_from(scancode) { - Ok(scancode) => key = Some(Key::Scancode(scancode)), + Ok(scancode) => { + key = Some(BindingKey::Scancode(KeyCode::from_scancode( + scancode, + ))) + }, Err(_) => { return Err(::custom(format!( "Invalid key binding, scancode is too big: {}", @@ -1023,7 +981,9 @@ impl<'a> Deserialize<'a> for RawBinding { }, }, None => { - key = Some(Key::deserialize(value).map_err(V::Error::custom)?); + key = Some( + BindingKey::deserialize(value).map_err(V::Error::custom)?, + ) }, } }, @@ -1196,10 +1156,10 @@ impl<'a> de::Deserialize<'a> for ModsWrapper { let mut res = ModifiersState::empty(); for modifier in value.split('|') { match modifier.trim().to_lowercase().as_str() { - "command" | "super" => res.insert(ModifiersState::LOGO), + "command" | "super" => res.insert(ModifiersState::SUPER), "shift" => res.insert(ModifiersState::SHIFT), "alt" | "option" => res.insert(ModifiersState::ALT), - "control" => res.insert(ModifiersState::CTRL), + "control" => res.insert(ModifiersState::CONTROL), "none" => (), _ => return Err(E::invalid_value(Unexpected::Str(modifier), &self)), } @@ -1217,7 +1177,7 @@ impl<'a> de::Deserialize<'a> for ModsWrapper { mod tests { use super::*; - use winit::event::ModifiersState; + use winit::keyboard::ModifiersState; type MockBinding = Binding; @@ -1380,7 +1340,7 @@ mod tests { #[test] fn binding_trigger_mods() { let binding = MockBinding { - mods: ModifiersState::ALT | ModifiersState::LOGO, + mods: ModifiersState::ALT | ModifiersState::SUPER, ..MockBinding::default() }; diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index 9221050b..883ea99f 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -26,7 +26,7 @@ mod mouse; use crate::cli::Options; pub use crate::config::bindings::{ - Action, Binding, BindingMode, Key, MouseAction, SearchAction, ViAction, + Action, Binding, BindingKey, BindingMode, MouseAction, SearchAction, ViAction, }; #[cfg(test)] pub use crate::config::mouse::Mouse; diff --git a/alacritty/src/config/ui_config.rs b/alacritty/src/config/ui_config.rs index 62721781..a2e8d4e1 100644 --- a/alacritty/src/config/ui_config.rs +++ b/alacritty/src/config/ui_config.rs @@ -7,7 +7,7 @@ use log::{error, warn}; use serde::de::{Error as SerdeError, MapAccess, Visitor}; use serde::{self, Deserialize, Deserializer}; use unicode_width::UnicodeWidthChar; -use winit::event::{ModifiersState, VirtualKeyCode}; +use winit::keyboard::{Key, KeyLocation, ModifiersState}; use alacritty_config_derive::{ConfigDeserialize, SerdeReplace}; use alacritty_terminal::config::{Config as TerminalConfig, Program, LOG_TARGET_CONFIG}; @@ -15,7 +15,7 @@ use alacritty_terminal::term::search::RegexSearch; use crate::config::bell::BellConfig; use crate::config::bindings::{ - self, Action, Binding, Key, KeyBinding, ModeWrapper, ModsWrapper, MouseBinding, + self, Action, Binding, BindingKey, KeyBinding, ModeWrapper, ModsWrapper, MouseBinding, }; use crate::config::color::Colors; use crate::config::debug::Debug; @@ -131,13 +131,13 @@ impl UiConfig { }; for hint in &self.hints.enabled { - let binding = match hint.binding { + let binding = match &hint.binding { Some(binding) => binding, None => continue, }; let binding = KeyBinding { - trigger: binding.key, + trigger: binding.key.clone(), mods: binding.mods.0, mode: binding.mode.mode, notmode: binding.mode.not_mode, @@ -208,7 +208,7 @@ pub fn deserialize_bindings<'a, D, T>( ) -> Result>, D::Error> where D: Deserializer<'a>, - T: Copy + Eq, + T: Clone + Eq, Binding: Deserialize<'a>, { let values = Vec::::deserialize(deserializer)?; @@ -278,8 +278,11 @@ impl Default for Hints { post_processing: true, mouse: Some(HintMouse { enabled: true, mods: Default::default() }), binding: Some(HintBinding { - key: Key::Keycode(VirtualKeyCode::U), - mods: ModsWrapper(ModifiersState::SHIFT | ModifiersState::CTRL), + key: BindingKey::Keycode { + key: Key::Character("u".into()), + location: KeyLocation::Standard, + }, + mods: ModsWrapper(ModifiersState::SHIFT | ModifiersState::CONTROL), mode: Default::default(), }), }], @@ -454,10 +457,10 @@ impl<'de> Deserialize<'de> for HintContent { } /// Binding for triggering a keyboard hint. -#[derive(Deserialize, Copy, Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct HintBinding { - pub key: Key, + pub key: BindingKey, #[serde(default)] pub mods: ModsWrapper, #[serde(default)] diff --git a/alacritty/src/display/hint.rs b/alacritty/src/display/hint.rs index 0ff070ec..7e2e4126 100644 --- a/alacritty/src/display/hint.rs +++ b/alacritty/src/display/hint.rs @@ -2,7 +2,7 @@ use std::cmp::Reverse; use std::collections::HashSet; use std::iter; -use winit::event::ModifiersState; +use winit::keyboard::ModifiersState; use alacritty_terminal::grid::{BidirectionalIterator, Dimensions}; use alacritty_terminal::index::{Boundary, Column, Direction, Line, Point}; diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index 98dd04ad..c992e9cc 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -15,9 +15,10 @@ use glutin::surface::{Rect as DamageRect, Surface, SwapInterval, WindowSurface}; use log::{debug, info}; use parking_lot::MutexGuard; +use raw_window_handle::RawWindowHandle; use serde::{Deserialize, Serialize}; use winit::dpi::PhysicalSize; -use winit::event::ModifiersState; +use winit::keyboard::ModifiersState; use winit::window::CursorIcon; use crossfont::{self, Rasterize, Rasterizer}; @@ -393,10 +394,7 @@ impl Display { gl_context: NotCurrentContext, config: &UiConfig, ) -> Result { - #[cfg(any(not(feature = "wayland"), target_os = "macos", windows))] - let is_wayland = false; - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - let is_wayland = window.wayland_surface().is_some(); + let is_wayland = matches!(window.raw_window_handle(), RawWindowHandle::Wayland(_)); let scale_factor = window.scale_factor as f32; let rasterizer = Rasterizer::new(scale_factor)?; @@ -1048,7 +1046,7 @@ impl Display { // highlighted hint could be disrupted by the old preview. dirty = self.hint_mouse_point.map_or(false, |p| p.line != point.line); self.hint_mouse_point = Some(point); - self.window.set_mouse_cursor(CursorIcon::Hand); + self.window.set_mouse_cursor(CursorIcon::Pointer); } else if self.highlighted_hint.is_some() { self.hint_mouse_point = None; if term.mode().intersects(TermMode::MOUSE_MODE) && !term.mode().contains(TermMode::VI) { diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index 962f93a1..185e7305 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -408,7 +408,14 @@ impl Window { let nspot_x = f64::from(size.padding_x() + point.column.0 as f32 * size.cell_width()); let nspot_y = f64::from(size.padding_y() + (point.line + 1) as f32 * size.cell_height()); - self.window.set_ime_position(PhysicalPosition::new(nspot_x, nspot_y)); + // Exclude the rest of the line since we edit from left to right. + let width = size.width as f64 - nspot_x; + let height = size.cell_height as f64; + + self.window.set_ime_cursor_area( + PhysicalPosition::new(nspot_x, nspot_y), + PhysicalSize::new(width, height), + ); } /// Disable macOS window shadows. diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 5fac1ced..52222080 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -19,11 +19,11 @@ use log::{debug, error, info, warn}; use wayland_client::{Display as WaylandDisplay, EventQueue}; use winit::dpi::PhysicalSize; use winit::event::{ - ElementState, Event as WinitEvent, Ime, ModifiersState, MouseButton, StartCause, + ElementState, Event as WinitEvent, Ime, Modifiers, MouseButton, StartCause, Touch as TouchEvent, WindowEvent, }; use winit::event_loop::{ - ControlFlow, DeviceEventFilter, EventLoop, EventLoopProxy, EventLoopWindowTarget, + ControlFlow, DeviceEvents, EventLoop, EventLoopProxy, EventLoopWindowTarget, }; use winit::platform::run_return::EventLoopExtRunReturn; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] @@ -191,9 +191,7 @@ pub struct ActionContext<'a, N, T> { pub clipboard: &'a mut Clipboard, pub mouse: &'a mut Mouse, pub touch: &'a mut TouchPurpose, - pub received_count: &'a mut usize, - pub suppress_chars: &'a mut bool, - pub modifiers: &'a mut ModifiersState, + pub modifiers: &'a mut Modifiers, pub display: &'a mut Display, pub message_buffer: &'a mut MessageBuffer, pub config: &'a UiConfig, @@ -349,17 +347,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon } #[inline] - fn received_count(&mut self) -> &mut usize { - self.received_count - } - - #[inline] - fn suppress_chars(&mut self) -> &mut bool { - self.suppress_chars - } - - #[inline] - fn modifiers(&mut self) -> &mut ModifiersState { + fn modifiers(&mut self) -> &mut Modifiers { self.modifiers } @@ -750,7 +738,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon fn expand_selection(&mut self) { let selection_type = match self.mouse().click_state { ClickState::Click => { - if self.modifiers().ctrl() { + if self.modifiers().state().control_key() { SelectionType::Block } else { SelectionType::Simple @@ -1304,11 +1292,10 @@ impl input::Processor> { self.ctx.display.pending_update.set_dimensions(size); }, - WindowEvent::KeyboardInput { input, is_synthetic: false, .. } => { - self.key_input(input); + WindowEvent::KeyboardInput { event, is_synthetic: false, .. } => { + self.key_input(event); }, WindowEvent::ModifiersChanged(modifiers) => self.modifiers_input(modifiers), - WindowEvent::ReceivedCharacter(c) => self.received_char(c), WindowEvent::MouseInput { state, button, .. } => { self.ctx.window().set_mouse_visible(true); self.mouse_input(state, button); @@ -1507,7 +1494,7 @@ impl Processor { let mut clipboard = Clipboard::new(); // Disable all device events, since we don't care about them. - event_loop.set_device_event_filter(DeviceEventFilter::Always); + event_loop.listen_device_events(DeviceEvents::Never); let exit_code = event_loop.run_return(move |event, event_loop, control_flow| { if self.config.debug.print_events { diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index a9925088..867099a9 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -17,12 +17,16 @@ use std::time::{Duration, Instant}; use log::debug; use winit::dpi::PhysicalPosition; use winit::event::{ - ElementState, KeyboardInput, ModifiersState, MouseButton, MouseScrollDelta, - Touch as TouchEvent, TouchPhase, + ElementState, KeyEvent, Modifiers, MouseButton, MouseScrollDelta, Touch as TouchEvent, + TouchPhase, }; use winit::event_loop::EventLoopWindowTarget; #[cfg(target_os = "macos")] +use winit::keyboard::ModifiersKeyState; +use winit::keyboard::ModifiersState; +#[cfg(target_os = "macos")] use winit::platform::macos::{EventLoopWindowTargetExtMacOS, OptionAsAlt}; +use winit::platform::modifier_supplement::KeyEventExtModifierSupplement; use winit::window::CursorIcon; use alacritty_terminal::ansi::{ClearMode, Handler}; @@ -35,7 +39,9 @@ use alacritty_terminal::term::{ClipboardType, Term, TermMode}; use alacritty_terminal::vi_mode::ViMotion; use crate::clipboard::Clipboard; -use crate::config::{Action, BindingMode, Key, MouseAction, SearchAction, UiConfig, ViAction}; +use crate::config::{ + Action, BindingKey, BindingMode, MouseAction, SearchAction, UiConfig, ViAction, +}; use crate::display::hint::HintMatch; use crate::display::window::Window; use crate::display::{Display, SizeInfo}; @@ -88,9 +94,7 @@ pub trait ActionContext { fn mouse_mut(&mut self) -> &mut Mouse; fn mouse(&self) -> &Mouse; fn touch_purpose(&mut self) -> &mut TouchPurpose; - fn received_count(&mut self) -> &mut usize; - fn suppress_chars(&mut self) -> &mut bool; - fn modifiers(&mut self) -> &mut ModifiersState; + fn modifiers(&mut self) -> &mut Modifiers; fn scroll(&mut self, _scroll: Scroll) {} fn window(&mut self) -> &mut Window; fn display(&mut self) -> &mut Display; @@ -421,7 +425,8 @@ impl> Processor { // Don't launch URLs if mouse has moved. self.ctx.mouse_mut().block_hint_launcher = true; - if (lmb_pressed || rmb_pressed) && (self.ctx.modifiers().shift() || !self.ctx.mouse_mode()) + if (lmb_pressed || rmb_pressed) + && (self.ctx.modifiers().state().shift_key() || !self.ctx.mouse_mode()) { self.ctx.update_selection(point, cell_side); } else if cell_changed @@ -472,14 +477,14 @@ impl> Processor { // Calculate modifiers value. let mut mods = 0; - let modifiers = self.ctx.modifiers(); - if modifiers.shift() { + let modifiers = self.ctx.modifiers().state(); + if modifiers.shift_key() { mods += 4; } - if modifiers.alt() { + if modifiers.alt_key() { mods += 8; } - if modifiers.ctrl() { + if modifiers.control_key() { mods += 16; } @@ -539,7 +544,7 @@ impl> Processor { fn on_mouse_press(&mut self, button: MouseButton) { // Handle mouse mode. - if !self.ctx.modifiers().shift() && self.ctx.mouse_mode() { + if !self.ctx.modifiers().state().shift_key() && self.ctx.mouse_mode() { self.ctx.mouse_mut().click_state = ClickState::None; let code = match button { @@ -547,7 +552,7 @@ impl> Processor { MouseButton::Middle => 1, MouseButton::Right => 2, // Can't properly report more than three buttons.. - MouseButton::Other(_) => return, + MouseButton::Back | MouseButton::Forward | MouseButton::Other(_) => return, }; self.mouse_report(code, ElementState::Pressed); @@ -591,7 +596,7 @@ impl> Processor { self.ctx.clear_selection(); // Start new empty selection. - if self.ctx.modifiers().ctrl() { + if self.ctx.modifiers().state().control_key() { self.ctx.start_selection(SelectionType::Block, point, side); } else { self.ctx.start_selection(SelectionType::Simple, point, side); @@ -616,13 +621,13 @@ impl> Processor { } fn on_mouse_release(&mut self, button: MouseButton) { - if !self.ctx.modifiers().shift() && self.ctx.mouse_mode() { + if !self.ctx.modifiers().state().shift_key() && self.ctx.mouse_mode() { let code = match button { MouseButton::Left => 0, MouseButton::Middle => 1, MouseButton::Right => 2, // Can't properly report more than three buttons. - MouseButton::Other(_) => return, + MouseButton::Back | MouseButton::Forward | MouseButton::Other(_) => return, }; self.mouse_report(code, ElementState::Released); return; @@ -705,7 +710,7 @@ impl> Processor { .terminal() .mode() .contains(TermMode::ALT_SCREEN | TermMode::ALTERNATE_SCROLL) - && !self.ctx.modifiers().shift() + && !self.ctx.modifiers().state().shift_key() { let multiplier = f64::from(self.ctx.config().terminal_config.scrolling.multiplier); @@ -870,6 +875,25 @@ impl> Processor { } } + /// Reset mouse cursor based on modifier and terminal state. + #[inline] + pub fn reset_mouse_cursor(&mut self) { + let mouse_state = self.cursor_state(); + self.ctx.window().set_mouse_cursor(mouse_state); + } + + /// Modifier state change. + pub fn modifiers_input(&mut self, modifiers: Modifiers) { + *self.ctx.modifiers() = modifiers; + + // Prompt hint highlight update. + self.ctx.mouse_mut().hint_highlight_dirty = true; + + // Update mouse state and check for URL change. + let mouse_state = self.cursor_state(); + self.ctx.window().set_mouse_cursor(mouse_state); + } + pub fn mouse_input(&mut self, state: ElementState, button: MouseButton) { match button { MouseButton::Left => self.ctx.mouse_mut().left_button_state = state, @@ -879,7 +903,7 @@ impl> Processor { } // Skip normal mouse events if the message bar has been clicked. - if self.message_bar_cursor_state() == Some(CursorIcon::Hand) + if self.message_bar_cursor_state() == Some(CursorIcon::Pointer) && state == ElementState::Pressed { let size = self.ctx.size_info(); @@ -894,7 +918,7 @@ impl> Processor { let new_icon = match current_lines.cmp(&new_lines) { Ordering::Less => CursorIcon::Default, - Ordering::Equal => CursorIcon::Hand, + Ordering::Equal => CursorIcon::Pointer, Ordering::Greater => { if self.ctx.mouse_mode() { CursorIcon::Default @@ -917,139 +941,6 @@ impl> Processor { } } - /// Process key input. - pub fn key_input(&mut self, input: KeyboardInput) { - // IME input will be applied on commit and shouldn't trigger key bindings. - if self.ctx.display().ime.preedit().is_some() { - return; - } - - // All key bindings are disabled while a hint is being selected. - if self.ctx.display().hint_state.active() { - *self.ctx.suppress_chars() = false; - return; - } - - // Reset search delay when the user is still typing. - if self.ctx.search_active() { - let timer_id = TimerId::new(Topic::DelayedSearch, self.ctx.window().id()); - let scheduler = self.ctx.scheduler_mut(); - if let Some(timer) = scheduler.unschedule(timer_id) { - scheduler.schedule(timer.event, TYPING_SEARCH_DELAY, false, timer.id); - } - } - - // Reset character suppression. - *self.ctx.suppress_chars() = false; - - if let ElementState::Pressed = input.state { - *self.ctx.received_count() = 0; - self.process_key_bindings(input); - } - } - - /// Modifier state change. - pub fn modifiers_input(&mut self, modifiers: ModifiersState) { - *self.ctx.modifiers() = modifiers; - - // Prompt hint highlight update. - self.ctx.mouse_mut().hint_highlight_dirty = true; - - // Update mouse state and check for URL change. - let mouse_state = self.cursor_state(); - self.ctx.window().set_mouse_cursor(mouse_state); - } - - /// Reset mouse cursor based on modifier and terminal state. - #[inline] - pub fn reset_mouse_cursor(&mut self) { - let mouse_state = self.cursor_state(); - self.ctx.window().set_mouse_cursor(mouse_state); - } - - /// Process a received character. - pub fn received_char(&mut self, c: char) { - let suppress_chars = *self.ctx.suppress_chars(); - - // Don't insert chars when we have IME running. - if self.ctx.display().ime.preedit().is_some() { - return; - } - - // Handle hint selection over anything else. - if self.ctx.display().hint_state.active() && !suppress_chars { - self.ctx.hint_input(c); - return; - } - - // Pass keys to search and ignore them during `suppress_chars`. - let search_active = self.ctx.search_active(); - if suppress_chars || search_active || self.ctx.terminal().mode().contains(TermMode::VI) { - if search_active && !suppress_chars { - self.ctx.search_input(c); - } - - return; - } - - self.ctx.on_terminal_input_start(); - - let utf8_len = c.len_utf8(); - let mut bytes = vec![0; utf8_len]; - c.encode_utf8(&mut bytes[..]); - - #[cfg(not(target_os = "macos"))] - let alt_send_esc = true; - - // Don't send ESC when `OptionAsAlt` is used. This doesn't handle - // `Only{Left,Right}` variants due to inability to distinguish them. - #[cfg(target_os = "macos")] - let alt_send_esc = self.ctx.config().window.option_as_alt != OptionAsAlt::None; - - if alt_send_esc - && *self.ctx.received_count() == 0 - && self.ctx.modifiers().alt() - && utf8_len == 1 - { - bytes.insert(0, b'\x1b'); - } - - self.ctx.write_to_pty(bytes); - - *self.ctx.received_count() += 1; - } - - /// Attempt to find a binding and execute its action. - /// - /// The provided mode, mods, and key must match what is allowed by a binding - /// for its action to be executed. - fn process_key_bindings(&mut self, input: KeyboardInput) { - let mode = BindingMode::new(self.ctx.terminal().mode(), self.ctx.search_active()); - let mods = *self.ctx.modifiers(); - let mut suppress_chars = None; - - for i in 0..self.ctx.config().key_bindings().len() { - let binding = &self.ctx.config().key_bindings()[i]; - - let key = match (binding.trigger, input.virtual_keycode) { - (Key::Scancode(_), _) => Key::Scancode(input.scancode), - (_, Some(key)) => Key::Keycode(key), - _ => continue, - }; - - if binding.is_triggered_by(mode, mods, &key) { - // Pass through the key if any of the bindings has the `ReceiveChar` action. - *suppress_chars.get_or_insert(true) &= binding.action != Action::ReceiveChar; - - // Binding was triggered; run the action. - binding.action.clone().execute(&mut self.ctx); - } - } - - // Don't suppress char if no bindings were triggered. - *self.ctx.suppress_chars() = suppress_chars.unwrap_or(false); - } - /// Attempt to find a binding and execute its action. /// /// The provided mode, mods, and key must match what is allowed by a binding @@ -1057,7 +948,7 @@ impl> Processor { fn process_mouse_bindings(&mut self, button: MouseButton) { let mode = BindingMode::new(self.ctx.terminal().mode(), self.ctx.search_active()); let mouse_mode = self.ctx.mouse_mode(); - let mods = *self.ctx.modifiers(); + let mods = self.ctx.modifiers().state(); for i in 0..self.ctx.config().mouse_bindings().len() { let mut binding = self.ctx.config().mouse_bindings()[i].clone(); @@ -1073,6 +964,108 @@ impl> Processor { } } + /// Process key input. + pub fn key_input(&mut self, key: KeyEvent) { + // IME input will be applied on commit and shouldn't trigger key bindings. + if key.state == ElementState::Released || self.ctx.display().ime.preedit().is_some() { + return; + } + + let text = key.text_with_all_modifiers().unwrap_or_default(); + + // All key bindings are disabled while a hint is being selected. + if self.ctx.display().hint_state.active() { + for character in text.chars() { + self.ctx.hint_input(character); + } + return; + } + + // Reset search delay when the user is still typing. + if self.ctx.search_active() { + let timer_id = TimerId::new(Topic::DelayedSearch, self.ctx.window().id()); + let scheduler = self.ctx.scheduler_mut(); + if let Some(timer) = scheduler.unschedule(timer_id) { + scheduler.schedule(timer.event, TYPING_SEARCH_DELAY, false, timer.id); + } + } + + // Key bindings suppress the character input. + if self.process_key_bindings(&key) { + return; + } + + if self.ctx.search_active() { + for character in text.chars() { + self.ctx.search_input(character); + } + + return; + } + + // Vi mode on its own doesn't have any input, the search input was done before. + if self.ctx.terminal().mode().contains(TermMode::VI) || text.is_empty() { + return; + } + + self.ctx.on_terminal_input_start(); + + let mut bytes = Vec::with_capacity(text.len() + 1); + if self.alt_send_esc() && text.len() == 1 { + bytes.push(b'\x1b'); + } + bytes.extend_from_slice(text.as_bytes()); + + self.ctx.write_to_pty(bytes); + } + + /// Whether we should send `ESC` due to `Alt` being pressed. + #[cfg(not(target_os = "macos"))] + fn alt_send_esc(&mut self) -> bool { + self.ctx.modifiers().state().alt_key() + } + + #[cfg(target_os = "macos")] + fn alt_send_esc(&mut self) -> bool { + let option_as_alt = self.ctx.config().window.option_as_alt; + option_as_alt == OptionAsAlt::Both + || (option_as_alt == OptionAsAlt::OnlyLeft + && self.ctx.modifiers().lalt_state() == ModifiersKeyState::Pressed) + || (option_as_alt == OptionAsAlt::OnlyRight + && self.ctx.modifiers().ralt_state() == ModifiersKeyState::Pressed) + } + + /// Attempt to find a binding and execute its action. + /// + /// The provided mode, mods, and key must match what is allowed by a binding + /// for its action to be executed. + fn process_key_bindings(&mut self, key: &KeyEvent) -> bool { + let mode = BindingMode::new(self.ctx.terminal().mode(), self.ctx.search_active()); + let mods = self.ctx.modifiers().state(); + + // Don't suppress char if no bindings were triggered. + let mut suppress_chars = None; + + for i in 0..self.ctx.config().key_bindings().len() { + let binding = &self.ctx.config().key_bindings()[i]; + + let key = match (&binding.trigger, &key.key_without_modifiers()) { + (BindingKey::Scancode(_), _) => BindingKey::Scancode(key.physical_key), + (_, code) => BindingKey::Keycode { key: code.clone(), location: key.location }, + }; + + if binding.is_triggered_by(mode, mods, &key) { + // Pass through the key if any of the bindings has the `ReceiveChar` action. + *suppress_chars.get_or_insert(true) &= binding.action != Action::ReceiveChar; + + // Binding was triggered; run the action. + binding.action.clone().execute(&mut self.ctx); + } + } + + suppress_chars.unwrap_or(false) + } + /// Check mouse icon state in relation to the message bar. fn message_bar_cursor_state(&self) -> Option { // Since search is above the message bar, the button is offset by search's height. @@ -1092,7 +1085,7 @@ impl> Processor { } else if mouse.y <= terminal_end + size.cell_height() as usize && point.column + message_bar::CLOSE_BUTTON_TEXT.len() >= size.columns() { - Some(CursorIcon::Hand) + Some(CursorIcon::Pointer) } else { Some(CursorIcon::Default) } @@ -1110,8 +1103,8 @@ impl> Processor { if let Some(mouse_state) = self.message_bar_cursor_state() { mouse_state } else if self.ctx.display().highlighted_hint.as_ref().map_or(false, hint_highlighted) { - CursorIcon::Hand - } else if !self.ctx.modifiers().shift() && self.ctx.mouse_mode() { + CursorIcon::Pointer + } else if !self.ctx.modifiers().state().shift_key() && self.ctx.mouse_mode() { CursorIcon::Default } else { CursorIcon::Text @@ -1158,7 +1151,8 @@ impl> Processor { mod tests { use super::*; - use winit::event::{DeviceId, Event as WinitEvent, VirtualKeyCode, WindowEvent}; + use winit::event::{DeviceId, Event as WinitEvent, WindowEvent}; + use winit::keyboard::Key; use winit::window::WindowId; use alacritty_terminal::event::Event as TerminalEvent; @@ -1166,7 +1160,7 @@ mod tests { use crate::config::Binding; use crate::message_bar::MessageBuffer; - const KEY: VirtualKeyCode = VirtualKeyCode::Key0; + const KEY: Key<&'static str> = Key::Character("0"); struct MockEventProxy; impl EventListener for MockEventProxy {} @@ -1177,9 +1171,7 @@ mod tests { pub mouse: &'a mut Mouse, pub clipboard: &'a mut Clipboard, pub message_buffer: &'a mut MessageBuffer, - pub received_count: usize, - pub suppress_chars: bool, - pub modifiers: ModifiersState, + pub modifiers: Modifiers, config: &'a UiConfig, } @@ -1240,15 +1232,7 @@ mod tests { unimplemented!(); } - fn received_count(&mut self) -> &mut usize { - &mut self.received_count - } - - fn suppress_chars(&mut self) -> &mut bool { - &mut self.suppress_chars - } - - fn modifiers(&mut self) -> &mut ModifiersState { + fn modifiers(&mut self) -> &mut Modifiers { &mut self.modifiers } @@ -1324,8 +1308,6 @@ mod tests { mouse: &mut mouse, size_info: &size, clipboard: &mut clipboard, - received_count: 0, - suppress_chars: false, modifiers: Default::default(), message_buffer: &mut message_buffer, config: &cfg, @@ -1379,7 +1361,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Left, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1396,7 +1377,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Right, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1413,7 +1393,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Middle, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1430,7 +1409,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Left, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1447,7 +1425,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Left, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1464,7 +1441,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Left, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1481,7 +1457,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Left, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1498,7 +1473,6 @@ mod tests { state: ElementState::Pressed, button: MouseButton::Right, device_id: unsafe { DeviceId::dummy() }, - modifiers: ModifiersState::default(), }, window_id: unsafe { WindowId::dummy() }, }, @@ -1524,10 +1498,10 @@ mod tests { test_process_binding! { name: process_binding_nomode_controlmod, - binding: Binding { trigger: KEY, mods: ModifiersState::CTRL, action: Action::from("\x1b[1;5D"), mode: BindingMode::empty(), notmode: BindingMode::empty() }, + binding: Binding { trigger: KEY, mods: ModifiersState::CONTROL, action: Action::from("\x1b[1;5D"), mode: BindingMode::empty(), notmode: BindingMode::empty() }, triggers: true, mode: BindingMode::empty(), - mods: ModifiersState::CTRL, + mods: ModifiersState::CONTROL, } test_process_binding! { @@ -1564,9 +1538,9 @@ mod tests { test_process_binding! { name: process_binding_fail_with_extra_mods, - binding: Binding { trigger: KEY, mods: ModifiersState::LOGO, action: Action::from("arst"), mode: BindingMode::empty(), notmode: BindingMode::empty() }, + binding: Binding { trigger: KEY, mods: ModifiersState::SUPER, action: Action::from("arst"), mode: BindingMode::empty(), notmode: BindingMode::empty() }, triggers: false, mode: BindingMode::empty(), - mods: ModifiersState::ALT | ModifiersState::LOGO, + mods: ModifiersState::ALT | ModifiersState::SUPER, } } diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index 502907ad..568f8c22 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -21,7 +21,7 @@ use raw_window_handle::HasRawDisplayHandle; use serde_json as json; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] use wayland_client::EventQueue; -use winit::event::{Event as WinitEvent, ModifiersState, WindowEvent}; +use winit::event::{Event as WinitEvent, Modifiers, WindowEvent}; use winit::event_loop::{EventLoopProxy, EventLoopWindowTarget}; use winit::window::WindowId; @@ -55,10 +55,8 @@ pub struct WindowContext { event_queue: Vec>, terminal: Arc>>, cursor_blink_timed_out: bool, - modifiers: ModifiersState, + modifiers: Modifiers, search_state: SearchState, - received_count: usize, - suppress_chars: bool, notifier: Notifier, font_size: Size, mouse: Mouse, @@ -248,9 +246,7 @@ impl WindowContext { config, notifier: Notifier(loop_tx), cursor_blink_timed_out: Default::default(), - suppress_chars: Default::default(), message_buffer: Default::default(), - received_count: Default::default(), search_state: Default::default(), event_queue: Default::default(), ipc_config: Default::default(), @@ -423,8 +419,6 @@ impl WindowContext { let context = ActionContext { cursor_blink_timed_out: &mut self.cursor_blink_timed_out, message_buffer: &mut self.message_buffer, - received_count: &mut self.received_count, - suppress_chars: &mut self.suppress_chars, search_state: &mut self.search_state, modifiers: &mut self.modifiers, font_size: &mut self.font_size, @@ -471,7 +465,7 @@ impl WindowContext { &terminal, &self.config, &self.mouse, - self.modifiers, + self.modifiers.state(), ); self.mouse.hint_highlight_dirty = false; } diff --git a/alacritty_config/Cargo.toml b/alacritty_config/Cargo.toml index b7ed5658..5665790c 100644 --- a/alacritty_config/Cargo.toml +++ b/alacritty_config/Cargo.toml @@ -14,4 +14,4 @@ serde = "1.0.163" toml = "0.7.1" [target.'cfg(target_os = "macos")'.dependencies] -winit = { version = "0.28.2", default-features = false, features = ["serde"] } +winit = { version = "0.29.0-beta.0", default-features = false, features = ["serde"] } diff --git a/extra/man/alacritty-bindings.5.scd b/extra/man/alacritty-bindings.5.scd index 988c1505..ddd4a6ea 100644 --- a/extra/man/alacritty-bindings.5.scd +++ b/extra/man/alacritty-bindings.5.scd @@ -153,7 +153,7 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Alt"_ : _"Vi|~Search"_ : _"ToggleSemanticSelection"_ -| _"Return"_ +| _"Enter"_ :[ : _"Vi|~Search"_ : _"Open"_ @@ -177,31 +177,31 @@ configuration. See *alacritty*(5) for full configuration format documentation. :[ : _"Vi|~Search"_ : _"Right"_ -| _"Up"_ +| _"ArrowUp"_ :[ : _"Vi|~Search"_ : _"Up"_ -| _"Down"_ +| _"ArrowDown"_ :[ : _"Vi|~Search"_ : _"Down"_ -| _"Left"_ +| _"ArrowLeft"_ :[ : _"Vi|~Search"_ : _"Left"_ -| _"Right"_ +| _"ArrowRight"_ :[ : _"Vi|~Search"_ : _"Right"_ -| _"Key0"_ +| _"0"_ :[ : _"Vi|~Search"_ : _"First"_ -| _"Key4"_ +| _"4"_ : _"Shift"_ : _"Vi|~Search"_ : _"Last"_ -| _"Key6"_ +| _"6"_ : _"Shift"_ : _"Vi|~Search"_ : _"FirstOccupied"_ @@ -241,15 +241,15 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Shift"_ : _"Vi|~Search"_ : _"WordRightEnd"_ -| _"Key5"_ +| _"5"_ : _"Shift"_ : _"Vi|~Search"_ : _"Bracket"_ -| _"Slash"_ +| _"/"_ :[ : _"Vi|~Search"_ : _"SearchForward"_ -| _"Slash"_ +| _"/"_ : _"Shift"_ : _"Vi|~Search"_ : _"SearchBackward"_ @@ -269,7 +269,7 @@ configuration. See *alacritty*(5) for full configuration format documentation. :[ *mods* :[ *mode* :[ *action* -| _"Return"_ +| _"Enter"_ :[ : _"Search|Vi"_ : _"SearchConfirm"_ @@ -297,15 +297,15 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Control"_ : _"Search"_ : _"SearchHistoryNext"_ -| _"Up"_ +| _"ArrowUp"_ :[ : _"Search"_ : _"SearchHistoryPrevious"_ -| _"Down"_ +| _"ArrowDown"_ :[ : _"Search"_ : _"SearchHistoryNext"_ -| _"Return"_ +| _"Enter"_ :[ : _"Search|~Vi"_ : _"SearchFocusNext"_ @@ -340,15 +340,15 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Shift"_ :[ : _"PasteSelection"_ -| _"Key0"_ +| _"0"_ : _"Control"_ :[ : _"ResetFontSize"_ -| _"Equals"_ +| _"="_ : _"Control"_ :[ : _"IncreaseFontSize"_ -| _"Plus"_ +| _"+"_ : _"Control"_ :[ : _"IncreaseFontSize"_ @@ -356,7 +356,7 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Control"_ :[ : _"IncreaseFontSize"_ -| _"Minus"_ +| _"-"_ : _"Control"_ :[ : _"DecreaseFontSize"_ @@ -371,7 +371,7 @@ configuration. See *alacritty*(5) for full configuration format documentation. :[ *mods* :[ *mode* :[ *action* -| _"Return"_ +| _"Enter"_ : _"Alt"_ :[ : _"ToggleFullscreen"_ @@ -390,15 +390,15 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Command"_ : _"~Vi|~Search"_ : _"ClearHistory"_ -| _"Key0"_ +| _"0"_ : _"Command"_ :[ : _"ResetFontSize"_ -| _"Equals"_ +| _"="_ : _"Command"_ :[ : _"IncreaseFontSize"_ -| _"Plus"_ +| _"+"_ : _"Command"_ :[ : _"IncreaseFontSize"_ @@ -406,7 +406,7 @@ configuration. See *alacritty*(5) for full configuration format documentation. : _"Command"_ :[ : _"IncreaseFontSize"_ -| _"Minus"_ +| _"-"_ : _"Command"_ :[ : _"DecreaseFontSize"_ diff --git a/extra/man/alacritty.5.scd b/extra/man/alacritty.5.scd index 78884e32..f0124dbe 100644 --- a/extra/man/alacritty.5.scd +++ b/extra/man/alacritty.5.scd @@ -656,11 +656,14 @@ This section documents the *[keyboard]* table of the configuration file. *key* - Identifier of the binding's key, for example: _"A"_, _"F1"_, or - _"Key0"_. + The regular keys like _"A"_, _"0"_, and _"Я"_ can be mapped directly + without any special syntax. Full list of named keys like _"F1"_ and the + syntax for dead keys can be found here:++ +https://docs.rs/winit/\*/winit/keyboard/enum.Key.html - A full list with available key codes can be found here:++ -https://docs.rs/winit/\*/winit/event/enum.VirtualKeyCode.html#variants + Numpad keys are prefixed by _Numpad_: "NumpadEnter" | "NumpadAdd" | + "NumpadComma" | "NumpadDivide" | "NumpadEquals" | "NumpadSubtract" | + "NumpadMultiply" | "Numpad[0-9]". The _key_ field also supports using scancodes, which are specified as a decimal number.