From a2ccfffda1171bde5118c1a1120af49dc87aecca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= <blaz@mxxn.io>
Date: Sun, 8 Aug 2021 14:07:14 +0900
Subject: [PATCH] config: Rename [terminal] to [editor] and pass it into Editor

---
 helix-term/src/application.rs |  9 +++++++--
 helix-term/src/commands.rs    | 27 +++++++++++++++------------
 helix-term/src/config.rs      | 14 +-------------
 helix-term/src/ui/editor.rs   | 14 +++++++-------
 helix-term/src/ui/mod.rs      |  4 ++--
 helix-view/src/editor.rs      | 28 ++++++++++++++++++++++++++--
 helix-view/src/view.rs        |  6 ++----
 7 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index 01ea617f..9cd9ee7e 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -80,7 +80,12 @@ impl Application {
         let syn_loader_conf = toml::from_slice(lang_conf).expect("Could not parse languages.toml");
         let syn_loader = std::sync::Arc::new(syntax::Loader::new(syn_loader_conf));
 
-        let mut editor = Editor::new(size, theme_loader.clone(), syn_loader.clone());
+        let mut editor = Editor::new(
+            size,
+            theme_loader.clone(),
+            syn_loader.clone(),
+            config.editor.clone(),
+        );
 
         let editor_view = Box::new(ui::EditorView::new(std::mem::take(&mut config.keys)));
         compositor.push(editor_view);
@@ -489,7 +494,7 @@ impl Application {
         terminal::enable_raw_mode()?;
         let mut stdout = stdout();
         execute!(stdout, terminal::EnterAlternateScreen)?;
-        if self.config.terminal.mouse {
+        if self.config.editor.mouse {
             execute!(stdout, EnableMouseCapture)?;
         }
         Ok(())
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 612a89ab..29be5ccd 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -12,12 +12,8 @@ use helix_core::{
 };
 
 use helix_view::{
-    document::Mode,
-    editor::Action,
-    input::KeyEvent,
-    keyboard::KeyCode,
-    view::{View, PADDING},
-    Document, DocumentId, Editor, ViewId,
+    document::Mode, editor::Action, input::KeyEvent, keyboard::KeyCode, view::View, Document,
+    DocumentId, Editor, ViewId,
 };
 
 use anyhow::{anyhow, bail, Context as _};
@@ -452,7 +448,11 @@ fn goto_first_nonwhitespace(cx: &mut Context) {
 fn goto_window(cx: &mut Context, align: Align) {
     let (view, doc) = current!(cx.editor);
 
-    let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
+    let scrolloff = cx
+        .editor
+        .config
+        .scrolloff
+        .min(view.area.height as usize / 2); // TODO: user pref
 
     let last_line = view.last_line(doc);
 
@@ -890,7 +890,11 @@ fn scroll(cx: &mut Context, offset: usize, direction: Direction) {
         return;
     }
 
-    let scrolloff = PADDING.min(view.area.height as usize / 2); // TODO: user pref
+    let scrolloff = cx
+        .editor
+        .config
+        .scrolloff
+        .min(view.area.height as usize / 2); // TODO: user pref
 
     view.first_line = match direction {
         Forward => view.first_line + offset,
@@ -3927,10 +3931,9 @@ fn align_view_middle(cx: &mut Context) {
         .cursor(doc.text().slice(..));
     let pos = coords_at_pos(doc.text().slice(..), pos);
 
-    const OFFSET: usize = 7; // gutters
-    view.first_col = pos
-        .col
-        .saturating_sub(((view.area.width as usize).saturating_sub(OFFSET)) / 2);
+    view.first_col = pos.col.saturating_sub(
+        ((view.area.width as usize).saturating_sub(crate::ui::editor::GUTTER_OFFSET as usize)) / 2,
+    );
 }
 
 fn scroll_up(cx: &mut Context) {
diff --git a/helix-term/src/config.rs b/helix-term/src/config.rs
index 38cd3bfb..13917656 100644
--- a/helix-term/src/config.rs
+++ b/helix-term/src/config.rs
@@ -10,7 +10,7 @@ pub struct Config {
     #[serde(default)]
     pub keys: Keymaps,
     #[serde(default)]
-    pub terminal: TerminalConfig,
+    pub editor: helix_view::editor::Config,
 }
 
 #[derive(Debug, Default, Clone, PartialEq, Deserialize)]
@@ -19,18 +19,6 @@ pub struct LspConfig {
     pub display_messages: bool,
 }
 
-#[derive(Debug, Clone, PartialEq, Deserialize)]
-#[serde(rename_all = "kebab-case")]
-pub struct TerminalConfig {
-    pub mouse: bool,
-}
-
-impl Default for TerminalConfig {
-    fn default() -> Self {
-        Self { mouse: true }
-    }
-}
-
 #[test]
 fn parsing_keymaps_config_file() {
     use crate::keymap;
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index a2b169ed..496edf42 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -36,7 +36,7 @@ pub struct EditorView {
     pub autoinfo: Option<Info>,
 }
 
-const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
+pub const GUTTER_OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
 
 impl Default for EditorView {
     fn default() -> Self {
@@ -72,9 +72,9 @@ impl EditorView {
         loader: &syntax::Loader,
     ) {
         let area = Rect::new(
-            view.area.x + OFFSET,
+            view.area.x + GUTTER_OFFSET,
             view.area.y,
-            view.area.width - OFFSET,
+            view.area.width - GUTTER_OFFSET,
             view.area.height.saturating_sub(1),
         ); // - 1 for statusline
 
@@ -339,7 +339,7 @@ impl EditorView {
             use helix_core::diagnostic::Severity;
             if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
                 surface.set_stringn(
-                    viewport.x - OFFSET,
+                    viewport.x - GUTTER_OFFSET,
                     viewport.y + i as u16,
                     "●",
                     1,
@@ -360,7 +360,7 @@ impl EditorView {
                 format!("{:>5}", line + 1)
             };
             surface.set_stringn(
-                viewport.x + 1 - OFFSET,
+                viewport.x + 1 - GUTTER_OFFSET,
                 viewport.y + i as u16,
                 line_number_text,
                 5,
@@ -401,7 +401,7 @@ impl EditorView {
                         format!("{:>5}", line_number + 1)
                     };
                     surface.set_stringn(
-                        viewport.x + 1 - OFFSET,
+                        viewport.x + 1 - GUTTER_OFFSET,
                         viewport.y + head.row as u16,
                         line_number_text,
                         5,
@@ -778,7 +778,7 @@ impl Component for EditorView {
                 }
 
                 let (view, doc) = current!(cx.editor);
-                view.ensure_cursor_in_view(doc);
+                view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
 
                 // mode transitions
                 match (mode, doc.mode()) {
diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 9e71cfe7..f68ad0a7 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -1,5 +1,5 @@
 mod completion;
-mod editor;
+pub(crate) mod editor;
 mod info;
 mod markdown;
 mod menu;
@@ -63,7 +63,7 @@ pub fn regex_prompt(
 
                             fun(view, doc, registers, regex);
 
-                            view.ensure_cursor_in_view(doc);
+                            view.ensure_cursor_in_view(doc, cx.editor.config.scrolloff);
                         }
                         Err(_err) => (), // TODO: mark command line as error
                     }
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index 7e8548e7..e5ba0d51 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -18,6 +18,26 @@ pub use helix_core::register::Registers;
 use helix_core::syntax;
 use helix_core::Position;
 
+use serde::Deserialize;
+
+#[derive(Debug, Clone, PartialEq, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub struct Config {
+    /// Padding to keep between the edge of the screen and the cursor when scrolling. Defaults to 5.
+    pub scrolloff: usize,
+    /// Mouse support. Defaults to true.
+    pub mouse: bool,
+}
+
+impl Default for Config {
+    fn default() -> Self {
+        Self {
+            scrolloff: 5,
+            mouse: true,
+        }
+    }
+}
+
 #[derive(Debug)]
 pub struct Editor {
     pub tree: Tree,
@@ -33,6 +53,8 @@ pub struct Editor {
     pub theme_loader: Arc<theme::Loader>,
 
     pub status_msg: Option<(String, Severity)>,
+
+    pub config: Config,
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -48,6 +70,7 @@ impl Editor {
         mut area: Rect,
         themes: Arc<theme::Loader>,
         config_loader: Arc<syntax::Loader>,
+        config: Config,
     ) -> Self {
         let language_servers = helix_lsp::Registry::new();
 
@@ -66,6 +89,7 @@ impl Editor {
             registers: Registers::default(),
             clipboard_provider: get_clipboard_provider(),
             status_msg: None,
+            config,
         }
     }
 
@@ -108,7 +132,7 @@ impl Editor {
     fn _refresh(&mut self) {
         for (view, _) in self.tree.views_mut() {
             let doc = &self.documents[view.doc];
-            view.ensure_cursor_in_view(doc)
+            view.ensure_cursor_in_view(doc, self.config.scrolloff)
         }
     }
 
@@ -267,7 +291,7 @@ impl Editor {
     pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
         let view = self.tree.get_mut(id);
         let doc = &self.documents[view.doc];
-        view.ensure_cursor_in_view(doc)
+        view.ensure_cursor_in_view(doc, self.config.scrolloff)
     }
 
     pub fn document(&self, id: DocumentId) -> Option<&Document> {
diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs
index 62ab2642..25efbde5 100644
--- a/helix-view/src/view.rs
+++ b/helix-view/src/view.rs
@@ -8,8 +8,6 @@ use helix_core::{
     Position, RopeSlice, Selection,
 };
 
-pub const PADDING: usize = 5;
-
 type Jump = (DocumentId, Selection);
 
 #[derive(Debug)]
@@ -84,7 +82,7 @@ impl View {
         }
     }
 
-    pub fn ensure_cursor_in_view(&mut self, doc: &Document) {
+    pub fn ensure_cursor_in_view(&mut self, doc: &Document, scrolloff: usize) {
         let cursor = doc
             .selection(self.id)
             .primary()
@@ -95,7 +93,7 @@ impl View {
         let height = self.area.height.saturating_sub(1); // - 1 for statusline
         let last_line = (self.first_line + height as usize).saturating_sub(1);
 
-        let scrolloff = PADDING.min(self.area.height as usize / 2); // TODO: user pref
+        let scrolloff = scrolloff.min(self.area.height as usize / 2);
 
         // TODO: not ideal
         const OFFSET: usize = 7; // 1 diagnostic + 5 linenr + 1 gutter