diff options
Diffstat (limited to 'alacritty/src/event.rs')
-rw-r--r-- | alacritty/src/event.rs | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index e635283b..9757893d 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -27,10 +27,10 @@ use alacritty_terminal::event::{Event, EventListener, Notify}; use alacritty_terminal::grid::Scroll; use alacritty_terminal::index::{Column, Line, Point, Side}; use alacritty_terminal::message_bar::{Message, MessageBuffer}; -use alacritty_terminal::selection::Selection; +use alacritty_terminal::selection::{Selection, SelectionType}; use alacritty_terminal::sync::FairMutex; use alacritty_terminal::term::cell::Cell; -use alacritty_terminal::term::{SizeInfo, Term}; +use alacritty_terminal::term::{SizeInfo, Term, TermMode}; #[cfg(not(windows))] use alacritty_terminal::tty; use alacritty_terminal::util::{limit, start_daemon}; @@ -40,6 +40,7 @@ use crate::config; use crate::config::Config; use crate::display::Display; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; +use crate::url::{Url, Urls}; use crate::window::Window; #[derive(Default, Clone, Debug, PartialEq)] @@ -68,6 +69,7 @@ pub struct ActionContext<'a, N, T> { pub display_update_pending: &'a mut DisplayUpdate, pub config: &'a mut Config, pub event_loop: &'a EventLoopWindowTarget<Event>, + pub urls: &'a Urls, font_size: &'a mut Size, } @@ -83,7 +85,12 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon fn scroll(&mut self, scroll: Scroll) { self.terminal.scroll_display(scroll); - if let ElementState::Pressed = self.mouse().left_button_state { + // Update selection + if self.terminal.mode().contains(TermMode::VI) + && self.terminal.selection().as_ref().map(|s| s.is_empty()) != Some(true) + { + self.update_selection(self.terminal.vi_mode_cursor.point, Side::Right); + } else if ElementState::Pressed == self.mouse().left_button_state { let (x, y) = (self.mouse().x, self.mouse().y); let size_info = self.size_info(); let point = size_info.pixels_to_coords(x, y); @@ -113,35 +120,35 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon let point = self.terminal.visible_to_buffer(point); // Update selection if one exists - if let Some(ref mut selection) = self.terminal.selection_mut() { + let vi_mode = self.terminal.mode().contains(TermMode::VI); + if let Some(selection) = self.terminal.selection_mut() { selection.update(point, side); - } - - self.terminal.dirty = true; - } - fn simple_selection(&mut self, point: Point, side: Side) { - let point = self.terminal.visible_to_buffer(point); - *self.terminal.selection_mut() = Some(Selection::simple(point, side)); - self.terminal.dirty = true; - } + if vi_mode { + selection.include_all(); + } - fn block_selection(&mut self, point: Point, side: Side) { - let point = self.terminal.visible_to_buffer(point); - *self.terminal.selection_mut() = Some(Selection::block(point, side)); - self.terminal.dirty = true; + self.terminal.dirty = true; + } } - fn semantic_selection(&mut self, point: Point) { + fn start_selection(&mut self, ty: SelectionType, point: Point, side: Side) { let point = self.terminal.visible_to_buffer(point); - *self.terminal.selection_mut() = Some(Selection::semantic(point)); + *self.terminal.selection_mut() = Some(Selection::new(ty, point, side)); self.terminal.dirty = true; } - fn line_selection(&mut self, point: Point) { - let point = self.terminal.visible_to_buffer(point); - *self.terminal.selection_mut() = Some(Selection::lines(point)); - self.terminal.dirty = true; + fn toggle_selection(&mut self, ty: SelectionType, point: Point, side: Side) { + match self.terminal.selection_mut() { + Some(selection) if selection.ty == ty && !selection.is_empty() => { + self.clear_selection(); + }, + Some(selection) if !selection.is_empty() => { + selection.ty = ty; + self.terminal.dirty = true; + }, + _ => self.start_selection(ty, point, side), + } } fn mouse_coords(&self) -> Option<Point> { @@ -156,6 +163,12 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon } #[inline] + fn mouse_mode(&self) -> bool { + self.terminal.mode().intersects(TermMode::MOUSE_MODE) + && !self.terminal.mode().contains(TermMode::VI) + } + + #[inline] fn mouse_mut(&mut self) -> &mut Mouse { self.mouse } @@ -254,8 +267,32 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon fn event_loop(&self) -> &EventLoopWindowTarget<Event> { self.event_loop } + + fn urls(&self) -> &Urls { + self.urls + } + + /// Spawn URL launcher when clicking on URLs. + fn launch_url(&self, url: Url) { + if self.mouse.block_url_launcher { + return; + } + + if let Some(ref launcher) = self.config.ui_config.mouse.url.launcher { + let mut args = launcher.args().to_vec(); + let start = self.terminal.visible_to_buffer(url.start()); + let end = self.terminal.visible_to_buffer(url.end()); + args.push(self.terminal.bounds_to_string(start, end)); + + match start_daemon(launcher.program(), &args) { + Ok(_) => debug!("Launched {} with args {:?}", launcher.program(), args), + Err(_) => warn!("Unable to launch {} with args {:?}", launcher.program(), args), + } + } + } } +#[derive(Debug)] pub enum ClickState { None, Click, @@ -264,6 +301,7 @@ pub enum ClickState { } /// State of the mouse +#[derive(Debug)] pub struct Mouse { pub x: usize, pub y: usize, @@ -412,10 +450,10 @@ impl<N: Notify + OnResize> Processor<N> { window: &mut self.display.window, font_size: &mut self.font_size, config: &mut self.config, + urls: &self.display.urls, event_loop, }; - let mut processor = - input::Processor::new(context, &self.display.urls, &self.display.highlighted_url); + let mut processor = input::Processor::new(context, &self.display.highlighted_url); for event in event_queue.drain(..) { Processor::handle_event(event, &mut processor); |