diff options
author | 2023-09-14 15:20:23 +0200 | |
---|---|---|
committer | 2023-09-14 15:20:23 +0200 | |
commit | f7d66899f1ae087a87be5d084ec1ee9a03dd4ecc (patch) | |
tree | ce448ec193bbdfe47c9ebf310aee854086add9ea /graphics | |
parent | edd591847599a3e47601646ce075cb5b71ea751b (diff) | |
download | iced-f7d66899f1ae087a87be5d084ec1ee9a03dd4ecc.tar.gz iced-f7d66899f1ae087a87be5d084ec1ee9a03dd4ecc.tar.bz2 iced-f7d66899f1ae087a87be5d084ec1ee9a03dd4ecc.zip |
Implement `Action::SelectWord` in `text::Editor`
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/Cargo.toml | 1 | ||||
-rw-r--r-- | graphics/src/text/editor.rs | 61 |
2 files changed, 61 insertions, 1 deletions
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 26bd1435..3165810b 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -34,6 +34,7 @@ raw-window-handle.workspace = true rustc-hash.workspace = true thiserror.workspace = true twox-hash.workspace = true +unicode-segmentation.workspace = true image.workspace = true image.optional = true diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index c6b2abd5..3fd2c4fe 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -274,7 +274,66 @@ impl editor::Editor for Editor { } } } - Action::SelectWord => todo!(), + Action::SelectWord => { + use unicode_segmentation::UnicodeSegmentation; + + let cursor = editor.cursor(); + + if let Some(line) = editor.buffer().lines.get(cursor.line) { + let (start, end) = + UnicodeSegmentation::unicode_word_indices(line.text()) + // Split words with dots + .flat_map(|(i, word)| { + word.split('.').scan(i, |current, word| { + let start = *current; + *current += word.len() + 1; + + Some((start, word)) + }) + }) + // Turn words into ranges + .map(|(i, word)| (i, i + word.len())) + // Find the word at cursor + .find(|&(start, end)| { + start <= cursor.index && cursor.index < end + }) + // Cursor is not in a word. Let's select its punctuation cluster. + .unwrap_or_else(|| { + let start = line.text()[..cursor.index] + .char_indices() + .rev() + .take_while(|(_, c)| { + c.is_ascii_punctuation() + }) + .map(|(i, _)| i) + .last() + .unwrap_or(cursor.index); + + let end = line.text()[cursor.index..] + .char_indices() + .skip_while(|(_, c)| { + c.is_ascii_punctuation() + }) + .map(|(i, _)| i + cursor.index) + .next() + .unwrap_or(cursor.index); + + (start, end) + }); + + if start != end { + editor.set_cursor(cosmic_text::Cursor { + index: start, + ..cursor + }); + + editor.set_select_opt(Some(cosmic_text::Cursor { + index: end, + ..cursor + })); + } + } + } Action::SelectLine => todo!(), // Editing events |