From 577cf91c7e3ae01f54c31300e78288757badb912 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sat, 7 Jan 2023 07:04:49 +0000 Subject: [PATCH 1/2] Make mouse click extend selection in select mode --- helix-term/src/ui/editor.rs | 40 +++++++++++++++++++++++++++---------- helix-view/src/editor.rs | 7 +++++-- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index fef62a292910..c652642605c8 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1086,6 +1086,15 @@ impl EditorView { if modifiers == KeyModifiers::ALT { let selection = doc.selection(view_id).clone(); doc.set_selection(view_id, selection.push(Range::point(pos))); + } else if editor.mode == Mode::Select { + // Discards non-primary selections for consistent UX with normal mode + let primary = doc.selection(view_id).primary().put_cursor( + doc.text().slice(..), + pos, + true, + ); + editor.mouse_down_range = Some(primary); + doc.set_selection(view_id, Selection::single(primary.anchor, primary.head)); } else { doc.set_selection(view_id, Selection::point(pos)); } @@ -1169,19 +1178,28 @@ impl EditorView { let (view, doc) = current!(cxt.editor); - if doc - .selection(view.id) - .primary() - .slice(doc.text().slice(..)) - .len_chars() - <= 1 - { - return EventResult::Ignored(None); - } + let should_yank = match cxt.editor.mouse_down_range { + Some(down_range) => doc.selection(view.id).primary() != down_range, + None => { + // This should not happen under normal cases. We fall back to the original + // behavior of yanking on non-single-char selections. + doc.selection(view.id) + .primary() + .slice(doc.text().slice(..)) + .len_chars() + > 1 + } + }; - commands::MappableCommand::yank_main_selection_to_primary_clipboard.execute(cxt); + cxt.editor.mouse_down_range = None; - EventResult::Consumed(None) + if should_yank { + commands::MappableCommand::yank_main_selection_to_primary_clipboard + .execute(cxt); + EventResult::Consumed(None) + } else { + EventResult::Ignored(None) + } } MouseEventKind::Up(MouseButton::Right) => { diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index eca488e74002..77bab8cd586f 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -41,7 +41,7 @@ pub use helix_core::diagnostic::Severity; use helix_core::{ auto_pairs::AutoPairs, syntax::{self, AutoPairConfig, IndentationHeuristic, LanguageServerFeature, SoftWrap}, - Change, LineEnding, Position, Selection, NATIVE_LINE_ENDING, + Change, LineEnding, Position, Range, Selection, NATIVE_LINE_ENDING, }; use helix_dap as dap; use helix_lsp::lsp; @@ -959,6 +959,8 @@ pub struct Editor { /// times during rendering and should not be set by other functions. pub cursor_cache: Cell>>, pub handlers: Handlers, + + pub mouse_down_range: Option, } pub type Motion = Box; @@ -1075,6 +1077,7 @@ impl Editor { needs_redraw: false, cursor_cache: Cell::new(None), handlers, + mouse_down_range: None, } } @@ -1889,7 +1892,7 @@ impl Editor { /// Switches the editor into normal mode. pub fn enter_normal_mode(&mut self) { - use helix_core::{graphemes, Range}; + use helix_core::graphemes; if self.mode == Mode::Normal { return; From 4f3dd4c9c79fa85a8def6853ea165d28d8375ee9 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Mon, 19 Feb 2024 12:37:11 +0000 Subject: [PATCH 2/2] chore: better readability with `Option::take()` --- helix-term/src/ui/editor.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index c652642605c8..a48ddcd29c7c 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -1178,7 +1178,7 @@ impl EditorView { let (view, doc) = current!(cxt.editor); - let should_yank = match cxt.editor.mouse_down_range { + let should_yank = match cxt.editor.mouse_down_range.take() { Some(down_range) => doc.selection(view.id).primary() != down_range, None => { // This should not happen under normal cases. We fall back to the original @@ -1191,8 +1191,6 @@ impl EditorView { } }; - cxt.editor.mouse_down_range = None; - if should_yank { commands::MappableCommand::yank_main_selection_to_primary_clipboard .execute(cxt);