@@ -9,6 +9,7 @@ use crate::{
99use helix_core::{
1010 coords_at_pos,
1111 graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary},
12+ movement::Direction,
1213 syntax::{self, HighlightEvent},
1314 unicode::segmentation::UnicodeSegmentation,
1415 unicode::width::UnicodeWidthStr,
@@ -694,8 +695,112 @@ impl EditorView {
694695 }
695696}
696697
698+impl EditorView {
699+ fn handle_mouse_event(
700+ &mut self,
701+ event: MouseEvent,
702+ cxt: &mut commands::Context,
703+ ) -> EventResult {
704+ match event {
705+ MouseEvent {
706+ kind: MouseEventKind::Down(MouseButton::Left),
707+ row,
708+ column,
709+ modifiers,
710+ ..
711+ } => {
712+ let editor = &mut cxt.editor;
713+
714+ let result = editor.tree.views().find_map(|(view, _focus)| {
715+ view.pos_at_screen_coords(&editor.documents[view.doc], row, column)
716+ .map(|pos| (pos, view.id))
717+ });
718+
719+ if let Some((pos, view_id)) = result {
720+ let doc = &mut editor.documents[editor.tree.get(view_id).doc];
721+
722+ if modifiers == crossterm::event::KeyModifiers::ALT {
723+ let selection = doc.selection(view_id).clone();
724+ doc.set_selection(view_id, selection.push(Range::point(pos)));
725+ } else {
726+ doc.set_selection(view_id, Selection::point(pos));
727+ }
728+
729+ editor.tree.focus = view_id;
730+
731+ return EventResult::Consumed(None);
732+ }
733+
734+ EventResult::Ignored
735+ }
736+
737+ MouseEvent {
738+ kind: MouseEventKind::Drag(MouseButton::Left),
739+ row,
740+ column,
741+ ..
742+ } => {
743+ let (view, doc) = current!(cxt.editor);
744+
745+ let pos = match view.pos_at_screen_coords(doc, row, column) {
746+ Some(pos) => pos,
747+ None => return EventResult::Ignored,
748+ };
749+
750+ let mut selection = doc.selection(view.id).clone();
751+ let primary = selection.primary_mut();
752+ *primary = Range::new(primary.anchor, pos);
753+ doc.set_selection(view.id, selection);
754+ EventResult::Consumed(None)
755+ }
756+
757+ MouseEvent {
758+ kind: MouseEventKind::ScrollUp | MouseEventKind::ScrollDown,
759+ row,
760+ column,
761+ ..
762+ } => {
763+ let current_view = cxt.editor.tree.focus;
764+
765+ let direction = match event.kind {
766+ MouseEventKind::ScrollUp => Direction::Backward,
767+ MouseEventKind::ScrollDown => Direction::Forward,
768+ _ => unreachable!(),
769+ };
770+
771+ let result = cxt.editor.tree.views().find_map(|(view, _focus)| {
772+ view.pos_at_screen_coords(&cxt.editor.documents[view.doc], row, column)
773+ .map(|_| view.id)
774+ });
775+
776+ match result {
777+ Some(view_id) => cxt.editor.tree.focus = view_id,
778+ None => return EventResult::Ignored,
779+ }
780+
781+ let offset = cxt.editor.config.scroll_lines.abs() as usize;
782+ commands::scroll(cxt, offset, direction);
783+
784+ cxt.editor.tree.focus = current_view;
785+
786+ EventResult::Consumed(None)
787+ }
788+ _ => EventResult::Ignored,
789+ }
790+ }
791+}
792+
697793impl Component for EditorView {
698794 fn handle_event(&mut self, event: Event, cx: &mut Context) -> EventResult {
795+ let mut cxt = commands::Context {
796+ selected_register: helix_view::RegisterSelection::default(),
797+ editor: &mut cx.editor,
798+ count: None,
799+ callback: None,
800+ on_next_key_callback: None,
801+ jobs: cx.jobs,
802+ };
803+
699804 match event {
700805 Event::Resize(_width, _height) => {
701806 // Ignore this event, we handle resizing just before rendering to screen.
@@ -706,20 +811,11 @@ impl Component for EditorView {
706811 let mut key = KeyEvent::from(key);
707812 canonicalize_key(&mut key);
708813 // clear status
709− cx.editor.status_msg = None;
814+ cxt.editor.status_msg = None;
710815
711− let (_, doc) = current!(cx.editor);
816+ let (_, doc) = current!(cxt.editor);
712817 let mode = doc.mode();
713818
714− let mut cxt = commands::Context {
715− selected_register: helix_view::RegisterSelection::default(),
716− editor: &mut cx.editor,
717− count: None,
718− callback: None,
719− on_next_key_callback: None,
720− jobs: cx.jobs,
721− };
722−
723819 if let Some(on_next_key) = self.on_next_key.take() {
724820 // if there's a command waiting input, do that first
725821 on_next_key(&mut cxt, key);
@@ -773,12 +869,12 @@ impl Component for EditorView {
773869
774870 // if the command consumed the last view, skip the render.
775871 // on the next loop cycle the Application will then terminate.
776− if cx.editor.should_close() {
872+ if cxt.editor.should_close() {
777873 return EventResult::Ignored;
778874 }
779875
780− let (view, doc) = current!(cx.editor);
781− view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
876+ let (view, doc) = current!(cxt.editor);
877+ view.ensure_cursor_in_view(doc, cxt.editor.config.scrolloff);
782878
783879 // mode transitions
784880 match (mode, doc.mode()) {
@@ -805,58 +901,8 @@ impl Component for EditorView {
805901
806902 EventResult::Consumed(callback)
807903 }
808− Event::Mouse(MouseEvent {
809− kind: MouseEventKind::Down(MouseButton::Left),
810− row,
811− column,
812− modifiers,
813− ..
814− }) => {
815− let editor = &mut cx.editor;
816−
817− let result = editor.tree.views().find_map(|(view, _focus)| {
818− view.pos_at_screen_coords(&editor.documents[view.doc], row, column)
819− .map(|pos| (pos, view.id))
820− });
821−
822− if let Some((pos, view_id)) = result {
823− let doc = &mut editor.documents[editor.tree.get(view_id).doc];
824−
825− if modifiers == crossterm::event::KeyModifiers::ALT {
826− let selection = doc.selection(view_id).clone();
827− doc.set_selection(view_id, selection.push(Range::point(pos)));
828− } else {
829− doc.set_selection(view_id, Selection::point(pos));
830− }
831−
832− editor.tree.focus = view_id;
833−
834− return EventResult::Consumed(None);
835− }
836−
837− EventResult::Ignored
838− }
839904
840− Event::Mouse(MouseEvent {
841− kind: MouseEventKind::Drag(MouseButton::Left),
842− row,
843− column,
844− ..
845− }) => {
846− let (view, doc) = current!(cx.editor);
847−
848− let pos = match view.pos_at_screen_coords(doc, row, column) {
849− Some(pos) => pos,
850− None => return EventResult::Ignored,
851− };
852−
853− let mut selection = doc.selection(view.id).clone();
854− let primary = selection.primary_mut();
855− *primary = Range::new(primary.anchor, pos);
856− doc.set_selection(view.id, selection);
857− EventResult::Consumed(None)
858− }
859− Event::Mouse(_) => EventResult::Ignored,
905+ Event::Mouse(event) => self.handle_mouse_event(event, &mut cxt),
860906 }
861907 }
862908