Make mouse click extend selection in select mode (#5436)

* Make mouse click extend selection in select mode

* chore: better readability with `Option::take()`
This commit is contained in:
Jonathan LEI 2024-02-19 22:08:26 +09:00 committed by GitHub
parent 787cc36092
commit cdef4f8a70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 14 deletions

View File

@ -1088,6 +1088,15 @@ fn handle_mouse_event(
if modifiers == KeyModifiers::ALT { if modifiers == KeyModifiers::ALT {
let selection = doc.selection(view_id).clone(); let selection = doc.selection(view_id).clone();
doc.set_selection(view_id, selection.push(Range::point(pos))); 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 { } else {
doc.set_selection(view_id, Selection::point(pos)); doc.set_selection(view_id, Selection::point(pos));
} }
@ -1171,19 +1180,26 @@ fn handle_mouse_event(
let (view, doc) = current!(cxt.editor); let (view, doc) = current!(cxt.editor);
if doc let should_yank = match cxt.editor.mouse_down_range.take() {
.selection(view.id) Some(down_range) => doc.selection(view.id).primary() != down_range,
.primary() None => {
.slice(doc.text().slice(..)) // This should not happen under normal cases. We fall back to the original
.len_chars() // behavior of yanking on non-single-char selections.
<= 1 doc.selection(view.id)
{ .primary()
return EventResult::Ignored(None); .slice(doc.text().slice(..))
.len_chars()
> 1
}
};
if should_yank {
commands::MappableCommand::yank_main_selection_to_primary_clipboard
.execute(cxt);
EventResult::Consumed(None)
} else {
EventResult::Ignored(None)
} }
commands::MappableCommand::yank_main_selection_to_primary_clipboard.execute(cxt);
EventResult::Consumed(None)
} }
MouseEventKind::Up(MouseButton::Right) => { MouseEventKind::Up(MouseButton::Right) => {

View File

@ -42,7 +42,7 @@
use helix_core::{ use helix_core::{
auto_pairs::AutoPairs, auto_pairs::AutoPairs,
syntax::{self, AutoPairConfig, IndentationHeuristic, LanguageServerFeature, SoftWrap}, 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_dap as dap;
use helix_lsp::lsp; use helix_lsp::lsp;
@ -964,6 +964,8 @@ pub struct Editor {
/// times during rendering and should not be set by other functions. /// times during rendering and should not be set by other functions.
pub cursor_cache: Cell<Option<Option<Position>>>, pub cursor_cache: Cell<Option<Option<Position>>>,
pub handlers: Handlers, pub handlers: Handlers,
pub mouse_down_range: Option<Range>,
} }
pub type Motion = Box<dyn Fn(&mut Editor)>; pub type Motion = Box<dyn Fn(&mut Editor)>;
@ -1080,6 +1082,7 @@ pub fn new(
needs_redraw: false, needs_redraw: false,
cursor_cache: Cell::new(None), cursor_cache: Cell::new(None),
handlers, handlers,
mouse_down_range: None,
} }
} }
@ -1978,7 +1981,7 @@ pub async fn flush_writes(&mut self) -> anyhow::Result<()> {
/// Switches the editor into normal mode. /// Switches the editor into normal mode.
pub fn enter_normal_mode(&mut self) { pub fn enter_normal_mode(&mut self) {
use helix_core::{graphemes, Range}; use helix_core::graphemes;
if self.mode == Mode::Normal { if self.mode == Mode::Normal {
return; return;