From e4c9d4082a139aac3aea4506918171b96e81f5b9 Mon Sep 17 00:00:00 2001
From: Blaž Hrastnik
Date: Tue, 23 Aug 2022 14:07:50 +0900
Subject: fix: Reset document mode when losing focus

Fixes #3090
---
 helix-term/src/ui/editor.rs | 14 ++++++--------
 helix-view/src/editor.rs    | 23 ++++++++++++++++++++++-
 helix-view/src/tree.rs      |  6 ------
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 46218e0d..60cab905 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -976,16 +976,15 @@ impl EditorView {
                         doc.set_selection(view_id, Selection::point(pos));
                     }
 
-                    editor.tree.focus = view_id;
+                    editor.focus(view_id);
 
                     return EventResult::Consumed(None);
                 }
 
                 if let Some((coords, view_id)) = gutter_coords_and_view(editor, row, column) {
-                    editor.tree.focus = view_id;
+                    editor.focus(view_id);
 
-                    let view = editor.tree.get(view_id);
-                    let doc = editor.documents.get_mut(&view.doc).unwrap();
+                    let (view, doc) = current!(cxt.editor);
 
                     let path = match doc.path() {
                         Some(path) => path.clone(),
@@ -1064,10 +1063,9 @@ impl EditorView {
 
             MouseEventKind::Up(MouseButton::Right) => {
                 if let Some((coords, view_id)) = gutter_coords_and_view(cxt.editor, row, column) {
-                    cxt.editor.tree.focus = view_id;
+                    cxt.editor.focus(view_id);
 
-                    let view = cxt.editor.tree.get(view_id);
-                    let doc = cxt.editor.documents.get_mut(&view.doc).unwrap();
+                    let (view, doc) = current!(cxt.editor);
                     let line = coords.row + view.offset.row;
                     if let Ok(pos) = doc.text().try_line_to_char(line) {
                         doc.set_selection(view_id, Selection::point(pos));
@@ -1100,7 +1098,7 @@ impl EditorView {
                 if let Some((pos, view_id)) = pos_and_view(editor, row, column) {
                     let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
                     doc.set_selection(view_id, Selection::point(pos));
-                    editor.tree.focus = view_id;
+                    cxt.editor.focus(view_id);
                     commands::MappableCommand::paste_primary_clipboard_before.execute(cxt);
 
                     return EventResult::Consumed(None);
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index d6c89693..520a425c 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -1091,12 +1091,33 @@ impl Editor {
         };
     }
 
+    pub fn focus(&mut self, view_id: ViewId) {
+        let prev_id = std::mem::replace(&mut self.tree.focus, view_id);
+
+        // if leaving the view: mode should reset
+        if prev_id != view_id {
+            let doc_id = self.tree.get(prev_id).doc;
+            self.documents.get_mut(&doc_id).unwrap().mode = Mode::Normal;
+        }
+    }
+
     pub fn focus_next(&mut self) {
+        let prev_id = self.tree.focus;
         self.tree.focus_next();
+        let id = self.tree.focus;
+
+        // if leaving the view: mode should reset
+        if prev_id != id {
+            let doc_id = self.tree.get(prev_id).doc;
+            self.documents.get_mut(&doc_id).unwrap().mode = Mode::Normal;
+        }
     }
 
     pub fn focus_direction(&mut self, direction: tree::Direction) {
-        self.tree.focus_direction(direction);
+        let current_view = self.tree.focus;
+        if let Some(id) = self.tree.find_split_in_direction(current_view, direction) {
+            self.focus(id)
+        }
     }
 
     pub fn swap_split_in_direction(&mut self, direction: tree::Direction) {
diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs
index c4474c33..eaf1dbd2 100644
--- a/helix-view/src/tree.rs
+++ b/helix-view/src/tree.rs
@@ -504,12 +504,6 @@ impl Tree {
         Some(child_id)
     }
 
-    pub fn focus_direction(&mut self, direction: Direction) {
-        if let Some(id) = self.find_split_in_direction(self.focus, direction) {
-            self.focus = id;
-        }
-    }
-
     pub fn focus_next(&mut self) {
         // This function is very dumb, but that's because we don't store any parent links.
         // (we'd be able to go parent.next_sibling() recursively until we find something)
-- 
cgit v1.2.3-70-g09d2