diff options
author | Jason Heard <jasonh@pandell.com> | 2021-07-29 09:40:51 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 15:40:51 +0000 |
commit | 3c309a0953566fe6f726b84eb117fd9cfa42df3d (patch) | |
tree | d6f4c6200bc4f9a6abb192adeee5bb15b4603815 | |
parent | 96a098c358870e8be41921f19ed72810651106ae (diff) | |
download | alacritty-3c309a0953566fe6f726b84eb117fd9cfa42df3d.tar.gz alacritty-3c309a0953566fe6f726b84eb117fd9cfa42df3d.zip |
Add ExpandSelection mouse binding action
Fixes #4132.
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | alacritty.yml | 10 | ||||
-rw-r--r-- | alacritty/src/config/bindings.rs | 31 | ||||
-rw-r--r-- | alacritty/src/config/mod.rs | 4 | ||||
-rw-r--r-- | alacritty/src/event.rs | 36 | ||||
-rw-r--r-- | alacritty/src/input.rs | 53 |
6 files changed, 91 insertions, 47 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 796d1c3c..9e2ec6b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## 0.10.0-dev +### Changed + +- `ExpandSelection` is now a configurable mouse binding action + ## 0.9.0 ### Packaging diff --git a/alacritty.yml b/alacritty.yml index a7628203..e93f3f74 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -507,13 +507,19 @@ # - Right # - Numeric identifier such as `5` # -# - `action` (see key bindings) +# - `action` (see key bindings for actions not exclusive to mouse mode) +# +# - Mouse exclusive actions: +# +# - ExpandSelection +# Expand the selection to the current mouse cursor location. # # And optionally: # # - `mods` (see key bindings) #mouse_bindings: -# - { mouse: Middle, action: PasteSelection } +# - { mouse: Right, action: ExpandSelection } +# - { mouse: Middle, mode: ~Vi, action: PasteSelection } # Key bindings # diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index 57237ad3..a4271430 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -109,6 +109,10 @@ pub enum Action { #[config(skip)] Search(SearchAction), + /// Perform mouse binding exclusive action. + #[config(skip)] + Mouse(MouseAction), + /// Paste contents of system clipboard. Paste, @@ -227,12 +231,19 @@ impl From<SearchAction> for Action { } } +impl From<MouseAction> for Action { + fn from(action: MouseAction) -> Self { + Self::Mouse(action) + } +} + /// Display trait used for error logging. impl Display for Action { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Action::ViMotion(motion) => motion.fmt(f), Action::Vi(action) => action.fmt(f), + Action::Mouse(action) => action.fmt(f), _ => write!(f, "{:?}", self), } } @@ -283,6 +294,13 @@ pub enum SearchAction { SearchHistoryNext, } +/// Mouse binding specific actions. +#[derive(ConfigDeserialize, Debug, Copy, Clone, PartialEq, Eq)] +pub enum MouseAction { + /// Expand the selection to the current mouse cursor position. + ExpandSelection, +} + macro_rules! bindings { ( KeyBinding; @@ -343,6 +361,7 @@ macro_rules! bindings { pub fn default_mouse_bindings() -> Vec<MouseBinding> { bindings!( MouseBinding; + MouseButton::Right; MouseAction::ExpandSelection; MouseButton::Middle, ~BindingMode::VI; Action::PasteSelection; ) } @@ -1027,6 +1046,9 @@ impl<'a> Deserialize<'a> for RawBinding { SearchAction::deserialize(value.clone()) { Some(search_action.into()) + } else if let Ok(mouse_action) = MouseAction::deserialize(value.clone()) + { + Some(mouse_action.into()) } else { match Action::deserialize(value.clone()).map_err(V::Error::custom) { Ok(action) => Some(action), @@ -1102,6 +1124,15 @@ impl<'a> Deserialize<'a> for RawBinding { } action }, + (Some(action @ Action::Mouse(_)), None, None) => { + if mouse.is_none() { + return Err(V::Error::custom(format!( + "action `{}` is only available for mouse bindings", + action, + ))); + } + action + }, (Some(action), None, None) => action, (None, Some(chars), None) => Action::Esc(chars), (None, None, Some(cmd)) => Action::Command(cmd), diff --git a/alacritty/src/config/mod.rs b/alacritty/src/config/mod.rs index 840a4b68..43cade6d 100644 --- a/alacritty/src/config/mod.rs +++ b/alacritty/src/config/mod.rs @@ -22,7 +22,9 @@ mod bindings; mod mouse; use crate::cli::Options; -pub use crate::config::bindings::{Action, Binding, BindingMode, Key, SearchAction, ViAction}; +pub use crate::config::bindings::{ + Action, Binding, BindingMode, Key, MouseAction, SearchAction, ViAction, +}; #[cfg(test)] pub use crate::config::mouse::{ClickHandler, Mouse}; use crate::config::ui_config::UiConfig; diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 37d28bb9..bc9c305a 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -671,6 +671,42 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } } + /// Expand the selection to the current mouse cursor position. + #[inline] + fn expand_selection(&mut self) { + let selection_type = match self.mouse().click_state { + ClickState::Click => { + if self.modifiers().ctrl() { + SelectionType::Block + } else { + SelectionType::Simple + } + }, + ClickState::DoubleClick => SelectionType::Semantic, + ClickState::TripleClick => SelectionType::Lines, + ClickState::None => return, + }; + + // Load mouse point, treating message bar and padding as the closest cell. + let display_offset = self.terminal().grid().display_offset(); + let point = self.mouse().point(&self.size_info(), display_offset); + + let cell_side = self.mouse().cell_side; + + let selection = match &mut self.terminal_mut().selection { + Some(selection) => selection, + None => return, + }; + + selection.ty = selection_type; + self.update_selection(point, cell_side); + + // Move vi mode cursor to mouse click position. + if self.terminal().mode().contains(TermMode::VI) && !self.search_active() { + self.terminal_mut().vi_mode_cursor.point = point; + } + } + /// Paste a text into the terminal. fn paste(&mut self, text: &str) { if self.search_active() { diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index 3258137c..98a1b723 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -29,7 +29,7 @@ use alacritty_terminal::term::{ClipboardType, SizeInfo, Term, TermMode}; use alacritty_terminal::vi_mode::ViMotion; use crate::clipboard::Clipboard; -use crate::config::{Action, BindingMode, Config, Key, SearchAction, ViAction}; +use crate::config::{Action, BindingMode, Config, Key, MouseAction, SearchAction, ViAction}; use crate::daemon::start_daemon; use crate::display::hint::HintMatch; use crate::display::window::Window; @@ -104,6 +104,7 @@ pub trait ActionContext<T: EventListener> { fn toggle_vi_mode(&mut self) {} fn hint_input(&mut self, _character: char) {} fn trigger_hint(&mut self, _hint: &HintMatch) {} + fn expand_selection(&mut self) {} fn paste(&mut self, _text: &str) {} } @@ -231,6 +232,7 @@ impl<T: EventListener> Execute<T> for Action { Action::Search(SearchAction::SearchDeleteWord) => ctx.search_pop_word(), Action::Search(SearchAction::SearchHistoryPrevious) => ctx.search_history_previous(), Action::Search(SearchAction::SearchHistoryNext) => ctx.search_history_next(), + Action::Mouse(MouseAction::ExpandSelection) => ctx.expand_selection(), Action::SearchForward => ctx.start_search(Direction::Right), Action::SearchBackward => ctx.start_search(Direction::Left), Action::Copy => ctx.copy_selection(ClipboardType::Clipboard), @@ -531,51 +533,12 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { let display_offset = self.ctx.terminal().grid().display_offset(); let point = self.ctx.mouse().point(&self.ctx.size_info(), display_offset); - match button { - MouseButton::Left => self.on_left_click(point), - MouseButton::Right => self.on_right_click(point), - // Do nothing when using buttons other than LMB. - _ => self.ctx.mouse_mut().click_state = ClickState::None, + if let MouseButton::Left = button { + self.on_left_click(point) } } } - /// Handle selection expansion on right click. - fn on_right_click(&mut self, point: Point) { - match self.ctx.mouse().click_state { - ClickState::Click => { - let selection_type = if self.ctx.modifiers().ctrl() { - SelectionType::Block - } else { - SelectionType::Simple - }; - - self.expand_selection(point, selection_type); - }, - ClickState::DoubleClick => self.expand_selection(point, SelectionType::Semantic), - ClickState::TripleClick => self.expand_selection(point, SelectionType::Lines), - ClickState::None => (), - } - } - - /// Expand existing selection. - fn expand_selection(&mut self, point: Point, selection_type: SelectionType) { - let cell_side = self.ctx.mouse().cell_side; - - let selection = match &mut self.ctx.terminal_mut().selection { - Some(selection) => selection, - None => return, - }; - - selection.ty = selection_type; - self.ctx.update_selection(point, cell_side); - - // Move vi mode cursor to mouse click position. - if self.ctx.terminal().mode().contains(TermMode::VI) && !self.ctx.search_active() { - self.ctx.terminal_mut().vi_mode_cursor.point = point; - } - } - /// Handle left click selection and vi mode cursor movement. fn on_left_click(&mut self, point: Point) { let side = self.ctx.mouse().cell_side; @@ -749,8 +712,9 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> { } else { match state { ElementState::Pressed => { - self.process_mouse_bindings(button); + // Process mouse press before bindings to update the `click_state`. self.on_mouse_press(button); + self.process_mouse_bindings(button); }, ElementState::Released => self.on_mouse_release(button), } @@ -1138,6 +1102,7 @@ mod tests { let mut mouse = Mouse { click_state: $initial_state, + last_click_button: $initial_button, ..Mouse::default() }; @@ -1239,7 +1204,7 @@ mod tests { }, window_id: unsafe { std::mem::transmute_copy(&0) }, }, - end_state: ClickState::None, + end_state: ClickState::Click, } test_clickstate! { |