aboutsummaryrefslogtreecommitdiff
path: root/src/event.rs
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-06-15 21:43:28 -0700
committerJoe Wilm <jwilm@users.noreply.github.com>2017-06-19 21:31:50 -0700
commit63bcb4601198790ccdb96ffec4a360ce3080e685 (patch)
treec2fb6452215559082df60a46c40473bbd5353c9c /src/event.rs
parent3dfac443c7779646c96cadb06913518c458b0eb8 (diff)
downloadalacritty-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.rs54
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;
}
},