From 45dbcb67832e31ca5eea936628f34f5dc26c4381 Mon Sep 17 00:00:00 2001
From: A-Walrus <58790821+A-Walrus@users.noreply.github.com>
Date: Thu, 1 Sep 2022 19:59:39 +0300
Subject: [PATCH] Fix closing buffer with custom keymap (#3633)

* Fix closing buffer with custom keymap

* Add comment explaining if
---
 helix-term/src/ui/editor.rs | 21 ++++++++++++---------
 helix-view/src/tree.rs      | 17 +++++++++++++++++
 2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 539e164c..fa437a7e 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -1263,17 +1263,20 @@ impl Component for EditorView {
                 if cx.editor.should_close() {
                     return EventResult::Ignored(None);
                 }
-                let config = cx.editor.config();
-                let mode = cx.editor.mode();
-                let view = cx.editor.tree.get_mut(focus);
-                let doc = cx.editor.documents.get_mut(&view.doc).unwrap();
+                // if the focused view still exists and wasn't closed
+                if cx.editor.tree.contains(focus) {
+                    let config = cx.editor.config();
+                    let mode = cx.editor.mode();
+                    let view = cx.editor.tree.get_mut(focus);
+                    let doc = cx.editor.documents.get_mut(&view.doc).unwrap();
 
-                view.ensure_cursor_in_view(doc, config.scrolloff);
+                    view.ensure_cursor_in_view(doc, config.scrolloff);
 
-                // Store a history state if not in insert mode. This also takes care of
-                // committing changes when leaving insert mode.
-                if mode != Mode::Insert {
-                    doc.append_changes_to_history(view.id);
+                    // Store a history state if not in insert mode. This also takes care of
+                    // committing changes when leaving insert mode.
+                    if mode != Mode::Insert {
+                        doc.append_changes_to_history(view.id);
+                    }
                 }
 
                 EventResult::Consumed(callback)
diff --git a/helix-view/src/tree.rs b/helix-view/src/tree.rs
index eaf1dbd2..72f6af57 100644
--- a/helix-view/src/tree.rs
+++ b/helix-view/src/tree.rs
@@ -270,10 +270,18 @@ impl Tree {
             })
     }
 
+    /// Get reference to a [`view`] by index.
+    /// # Panics
+    ///
+    /// Panics if `index` is not in self.nodes, or if the node's content is not [`Content::View`] . This can be checked with [`contains`]
     pub fn get(&self, index: ViewId) -> &View {
         self.try_get(index).unwrap()
     }
 
+    /// Try to get reference to a [`view`] by index. Returns `None` if node content is not a [`Content::View`]
+    /// # Panics
+    ///
+    /// Panics if `index` is not in self.nodes. This can be checked with [`Self::contains`]
     pub fn try_get(&self, index: ViewId) -> Option<&View> {
         match &self.nodes[index] {
             Node {
@@ -284,6 +292,10 @@ impl Tree {
         }
     }
 
+    /// Get a mutable reference to a [`view`] by index.
+    /// # Panics
+    ///
+    /// Panics if `index` is not in self.nodes, or if the node's content is not [`Content::View`] . This can be checked with [`Self::contains`]
     pub fn get_mut(&mut self, index: ViewId) -> &mut View {
         match &mut self.nodes[index] {
             Node {
@@ -294,6 +306,11 @@ impl Tree {
         }
     }
 
+    /// Check if tree contains a [`Node`] with a given index.
+    pub fn contains(&self, index: ViewId) -> bool {
+        self.nodes.contains_key(index)
+    }
+
     pub fn is_empty(&self) -> bool {
         match &self.nodes[self.root] {
             Node {