diff options
author | Dmitry Sharshakov | 2021-07-30 07:52:00 +0000 |
---|---|---|
committer | GitHub | 2021-07-30 07:52:00 +0000 |
commit | 8361de45dc20e428c538f784898e6c47646b6e8d (patch) | |
tree | a76526b6599e99e6152f5a6ac60d045d58a8682e /helix-term/src/ui | |
parent | 0fdb626c2cc5518b10a9bfbedc8b78cff3d360c9 (diff) |
Mouse selection support (#509)
* Initial mouse selection support
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Disable mouse event capture if editor crashes
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Translate screen coordinates to view position
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Select full lines by dragging on line numbers
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* editor: don't register dragging as a jump
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Count graphemes correctly
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Do not select lines when dragging on the line number bar
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Split out verify_screen_coords
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Do not iterate over the graphemes twice
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Switch view by clicking on it
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Add disable-mouse config option
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Support multiple selections with mouse
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Remove unnecessary check
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Refactor using match expression
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Rename local variable
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Rename mouse option
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Refactor code
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Fix dragging selection
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Fix crash when clicking past last line
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Count characters better
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Remove comparison not needed anymore
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Validate coordinates before resolving position
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Tidy up references to editor tree
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Better way to determine line end and avoid overflow
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Fix for last line
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
* Add unit tests for text_pos_at_screen_coords
Signed-off-by: Dmitry Sharshakov <d3dx12.xx@gmail.com>
Co-authored-by: Gokul Soumya <gokulps15@gmail.com>
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r-- | helix-term/src/ui/editor.rs | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index d5c907b8..ec5687bd 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -12,7 +12,7 @@ use helix_core::{ syntax::{self, HighlightEvent}, unicode::segmentation::UnicodeSegmentation, unicode::width::UnicodeWidthStr, - LineEnding, Position, Range, + LineEnding, Position, Range, Selection, }; use helix_view::{ document::Mode, @@ -24,7 +24,7 @@ use helix_view::{ }; use std::borrow::Cow; -use crossterm::event::Event; +use crossterm::event::{Event, MouseButton, MouseEvent, MouseEventKind}; use tui::buffer::Buffer as Surface; pub struct EditorView { @@ -805,6 +805,70 @@ impl Component for EditorView { EventResult::Consumed(callback) } + Event::Mouse(MouseEvent { + kind: MouseEventKind::Down(MouseButton::Left), + row, + column, + modifiers, + .. + }) => { + let editor = &mut cx.editor; + + let result = editor.tree.views().find_map(|(view, _focus)| { + view.pos_at_screen_coords( + &editor.documents[view.doc], + row as usize, + column as usize, + ) + .map(|pos| (pos, view.id)) + }); + + if let Some((pos, id)) = result { + let doc = &mut editor.documents[editor.tree.get(id).doc]; + let jump = (doc.id(), doc.selection(id).clone()); + editor.tree.get_mut(id).jumps.push(jump); + + if modifiers == crossterm::event::KeyModifiers::ALT { + let selection = doc.selection(id).clone(); + doc.set_selection(id, selection.push(Range::point(pos))); + } else { + doc.set_selection(id, Selection::point(pos)); + } + + editor.tree.focus = id; + + return EventResult::Consumed(None); + } + + EventResult::Ignored + } + + Event::Mouse(MouseEvent { + kind: MouseEventKind::Drag(MouseButton::Left), + row, + column, + .. + }) => { + let (view, doc) = current!(cx.editor); + + let pos = view.pos_at_screen_coords(doc, row as usize, column as usize); + + if pos == None { + return EventResult::Ignored; + } + + let selection = doc.selection(view.id).clone(); + let primary_anchor = selection.primary().anchor; + let new_selection = selection.transform(|range| -> Range { + if range.anchor == primary_anchor { + return Range::new(primary_anchor, pos.unwrap()); + } + range + }); + + doc.set_selection(view.id, new_selection); + EventResult::Consumed(None) + } Event::Mouse(_) => EventResult::Ignored, } } |