Add select by word and double/triple click actions

This commit is contained in:
Jeremy Soller 2023-12-12 10:29:14 -07:00
parent 6566350276
commit 94e6cdefda
No known key found for this signature in database
GPG key ID: DCFCA852D3906975
3 changed files with 87 additions and 8 deletions

View file

@ -704,12 +704,9 @@ impl Edit for Editor {
// Adjust selection
match self.selection {
Selection::None => {}
Selection::Normal(ref mut select) => {
if select.line == line_i && select.index >= after_whitespace {
select.index += required_indent;
}
}
Selection::Line(ref mut select) => {
Selection::Normal(ref mut select)
| Selection::Line(ref mut select)
| Selection::Word(ref mut select) => {
if select.line == line_i && select.index >= after_whitespace {
select.index += required_indent;
}
@ -768,7 +765,9 @@ impl Edit for Editor {
// Adjust selection
match self.selection {
Selection::None => {}
Selection::Normal(ref mut select) | Selection::Line(ref mut select) => {
Selection::Normal(ref mut select)
| Selection::Line(ref mut select)
| Selection::Word(ref mut select) => {
if select.line == line_i && select.index > last_indent {
select.index -= after_whitespace - last_indent;
}
@ -791,6 +790,33 @@ impl Edit for Editor {
}
}
}
Action::DoubleClick { x, y } => {
self.set_selection(Selection::None);
if let Some(new_cursor) = self.buffer.hit(x as f32, y as f32) {
if new_cursor != self.cursor {
let color = self.cursor.color;
self.cursor = new_cursor;
self.cursor.color = color;
self.buffer.set_redraw(true);
}
self.selection = Selection::Word(self.cursor);
self.buffer.set_redraw(true);
}
}
Action::TripleClick { x, y } => {
self.set_selection(Selection::None);
if let Some(new_cursor) = self.buffer.hit(x as f32, y as f32) {
if new_cursor != self.cursor {
let color = self.cursor.color;
self.cursor = new_cursor;
self.cursor.color = color;
}
self.selection = Selection::Line(self.cursor);
self.buffer.set_redraw(true);
}
}
Action::Drag { x, y } => {
if self.selection == Selection::None {
self.selection = Selection::Normal(self.cursor);

View file

@ -1,6 +1,7 @@
#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};
use core::cmp;
use unicode_segmentation::UnicodeSegmentation;
#[cfg(feature = "swash")]
use crate::Color;
@ -69,6 +70,16 @@ pub enum Action {
x: i32,
y: i32,
},
/// Mouse double click at specified position
DoubleClick {
x: i32,
y: i32,
},
/// Mouse triple click at specified position
TripleClick {
x: i32,
y: i32,
},
/// Mouse drag to specified position
Drag {
x: i32,
@ -140,6 +151,8 @@ pub enum Selection {
Normal(Cursor),
/// Select by lines
Line(Cursor),
/// Select by words
Word(Cursor),
//TODO: Select block
}
@ -202,6 +215,46 @@ pub trait Edit {
let end_index = self.buffer().lines[end_line].text().len();
Some((Cursor::new(start_line, 0), Cursor::new(end_line, end_index)))
}
Selection::Word(select) => {
let (mut start, mut end) = match select.line.cmp(&cursor.line) {
cmp::Ordering::Greater => (cursor, select),
cmp::Ordering::Less => (select, cursor),
cmp::Ordering::Equal => {
/* select.line == cursor.line */
if select.index < cursor.index {
(select, cursor)
} else {
/* select.index >= cursor.index */
(cursor, select)
}
}
};
// Move start to beginning of word
{
let line = &self.buffer().lines[start.line];
start.index = line
.text()
.unicode_word_indices()
.rev()
.map(|(i, _)| i)
.find(|&i| i < start.index)
.unwrap_or(0);
}
// Move end to end of word
{
let line = &self.buffer().lines[end.line];
end.index = line
.text()
.unicode_word_indices()
.map(|(i, word)| i + word.len())
.find(|&i| i > end.index)
.unwrap_or(line.text().len());
}
Some((start, end))
}
}
}

View file

@ -413,7 +413,7 @@ impl<'a> Edit for ViEditor<'a> {
editor.insert_string(data, None);
} else {
match selection {
Selection::Normal(_) | Selection::None => {
Selection::None | Selection::Normal(_) | Selection::Word(_) => {
let mut cursor = editor.cursor();
if after {
let buffer = editor.buffer();