From fb37a9cb552afeaa5632bcc867cbb18a40f9ff98 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Fri, 13 Sep 2019 23:51:14 +0000 Subject: [PATCH] Fix empty block selection detection Fixes #2789. --- alacritty_terminal/src/selection.rs | 45 +++++++++++++++++++++++++++-- alacritty_terminal/src/tty/unix.rs | 2 +- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/alacritty_terminal/src/selection.rs b/alacritty_terminal/src/selection.rs index 132c691..ffe35e0 100644 --- a/alacritty_terminal/src/selection.rs +++ b/alacritty_terminal/src/selection.rs @@ -132,7 +132,7 @@ impl Selection { pub fn is_empty(&self) -> bool { match *self { - Selection::Simple { ref region } | Selection::Block { ref region } => { + Selection::Simple { ref region } => { let (start, end) = if Selection::points_need_swap(region.start.point, region.end.point) { (®ion.end, ®ion.start) @@ -140,13 +140,26 @@ impl Selection { (®ion.start, ®ion.end) }; - // Empty when single cell with identical sides or two cell with right+left sides + // Simple selection is empty when the points are identical + // or two adjacent cells have the sides right -> left start == end || (start.side == Side::Left && end.side == Side::Right - && start.point.line == end.point.line + && (start.point.line == end.point.line) && start.point.col == end.point.col + 1) }, + Selection::Block { region: Range { ref start, ref end } } => { + // Block selection is empty when the points' columns and sides are identical + // or two cells with adjacent columns have the sides right -> left, + // regardless of their lines + (start.point.col == end.point.col && start.side == end.side) + || (start.point.col == end.point.col + 1 + && start.side == Side::Left + && end.side == Side::Right) + || (end.point.col == start.point.col + 1 + && end.side == Side::Left + && start.side == Side::Right) + }, Selection::Semantic { .. } | Selection::Lines { .. } => false, } } @@ -589,4 +602,30 @@ mod test { is_block: false, }); } + + #[test] + fn simple_is_empty() { + let mut selection = Selection::simple(Point::new(0, Column(0)), Side::Right); + assert!(selection.is_empty()); + selection.update(Point::new(0, Column(1)), Side::Left); + assert!(selection.is_empty()); + selection.update(Point::new(1, Column(0)), Side::Right); + assert!(!selection.is_empty()); + } + + #[test] + fn block_is_empty() { + let mut selection = Selection::block(Point::new(0, Column(0)), Side::Right); + assert!(selection.is_empty()); + selection.update(Point::new(0, Column(1)), Side::Left); + assert!(selection.is_empty()); + selection.update(Point::new(0, Column(1)), Side::Right); + assert!(!selection.is_empty()); + selection.update(Point::new(1, Column(0)), Side::Right); + assert!(selection.is_empty()); + selection.update(Point::new(1, Column(1)), Side::Left); + assert!(selection.is_empty()); + selection.update(Point::new(1, Column(1)), Side::Right); + assert!(!selection.is_empty()); + } } diff --git a/alacritty_terminal/src/tty/unix.rs b/alacritty_terminal/src/tty/unix.rs index e666eeb..77b5db4 100644 --- a/alacritty_terminal/src/tty/unix.rs +++ b/alacritty_terminal/src/tty/unix.rs @@ -28,6 +28,7 @@ use mio::unix::EventedFd; use std::ffi::CStr; use std::fs::File; use std::io; +use std::mem::MaybeUninit; use std::os::unix::{ io::{AsRawFd, FromRawFd, RawFd}, process::CommandExt, @@ -35,7 +36,6 @@ use std::os::unix::{ use std::process::{Child, Command, Stdio}; use std::ptr; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::mem::MaybeUninit; /// Process ID of child process ///