diff options
author | Joe Wilm <joe@jwilm.com> | 2017-06-15 21:43:28 -0700 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-06-19 21:31:50 -0700 |
commit | 63bcb4601198790ccdb96ffec4a360ce3080e685 (patch) | |
tree | c2fb6452215559082df60a46c40473bbd5353c9c /src/event.rs | |
parent | 3dfac443c7779646c96cadb06913518c458b0eb8 (diff) | |
download | alacritty-63bcb4601198790ccdb96ffec4a360ce3080e685.tar.gz alacritty-63bcb4601198790ccdb96ffec4a360ce3080e685.zip |
Implement semantic and line selection dragging
Unlike the regular selection that is by cell, these selection modes
highlight either semantic groupings or entire lines while the mouse is
dragged.
Diffstat (limited to 'src/event.rs')
-rw-r--r-- | src/event.rs | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/src/event.rs b/src/event.rs index 2d50234d..abbad0ef 100644 --- a/src/event.rs +++ b/src/event.rs @@ -33,7 +33,7 @@ pub trait Notify { pub struct ActionContext<'a, N: 'a> { pub notifier: &'a mut N, pub terminal: &'a mut Term, - pub selection: &'a mut Selection, + pub selection: &'a mut Option<Selection>, pub size_info: &'a SizeInfo, pub mouse: &'a mut Mouse, } @@ -52,32 +52,46 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> { } fn copy_selection(&self, buffer: ::copypasta::Buffer) { - if let Some(selection) = self.selection.span() { - let buf = self.terminal.string_from_selection(&selection); - if !buf.is_empty() { - Clipboard::new() - .and_then(|mut clipboard| clipboard.store(buf, buffer)) - .unwrap_or_else(|err| { - warn!("Error storing selection to clipboard. {}", Red(err)); - }); - } + if let &mut Some(ref selection) = self.selection { + selection.to_span(self.terminal as &Term) + .map(|span| { + let buf = self.terminal.string_from_selection(&span); + if !buf.is_empty() { + Clipboard::new() + .and_then(|mut clipboard| clipboard.store(buf, buffer)) + .unwrap_or_else(|err| { + warn!("Error storing selection to clipboard. {}", Red(err)); + }); + } + }); } } fn clear_selection(&mut self) { - self.selection.clear(); + *self.selection = None; } fn update_selection(&mut self, point: Point, side: Side) { - self.selection.update(point, side); + // Update selection if one exists + if let &mut Some(ref mut selection) = self.selection { + selection.update(point, side); + return; + } + + // Otherwise, start a regular selection + self.simple_selection(point, side); + } + + fn simple_selection(&mut self, point: Point, side: Side) { + *self.selection = Some(Selection::simple(point, side)); } fn semantic_selection(&mut self, point: Point) { - self.terminal.semantic_selection(&mut self.selection, point) + *self.selection = Some(Selection::semantic(point, self.terminal as &Term)); } fn line_selection(&mut self, point: Point) { - self.terminal.line_selection(&mut self.selection, point) + *self.selection = Some(Selection::lines(point)); } fn mouse_coords(&self) -> Option<Point> { @@ -141,7 +155,7 @@ pub struct Processor<N> { resize_tx: mpsc::Sender<(u32, u32)>, ref_test: bool, size_info: SizeInfo, - pub selection: Selection, + pub selection: Option<Selection>, hide_cursor_when_typing: bool, hide_cursor: bool, } @@ -178,7 +192,7 @@ impl<N: Notify> Processor<N> { resize_tx: resize_tx, ref_test: ref_test, mouse: Default::default(), - selection: Default::default(), + selection: None, size_info: size_info, hide_cursor_when_typing: config.hide_cursor_when_typing(), hide_cursor: false, @@ -243,7 +257,13 @@ impl<N: Notify> Processor<N> { *hide_cursor = false; processor.mouse_moved(x as u32, y as u32); - if !processor.ctx.selection.is_empty() { + if !processor.ctx.selection.is_none() { + // TODO this should only be passed if the selection changes + // which happens when the point/side change *and* the mouse + // is still pressed. + // + // Right now, this causes lots of unnecessary redraws while + // selection is active. processor.ctx.terminal.dirty = true; } }, |