From 2b58ff4d7cc09bc48bcdd79096110eeb578b509f Mon Sep 17 00:00:00 2001 From: Doug Kelkhoff Date: Sat, 21 Jan 2023 15:20:59 -0500 Subject: Add configuration for min width of line-numbers gutter (#4724) --- helix-view/src/view.rs | 99 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'helix-view/src/view.rs') diff --git a/helix-view/src/view.rs b/helix-view/src/view.rs index 23fb85c9..abcf9a16 100644 --- a/helix-view/src/view.rs +++ b/helix-view/src/view.rs @@ -1,4 +1,10 @@ -use crate::{align_view, editor::GutterType, graphics::Rect, Align, Document, DocumentId, ViewId}; +use crate::{ + align_view, + editor::{GutterConfig, GutterType}, + graphics::Rect, + Align, Document, DocumentId, ViewId, +}; + use helix_core::{ pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction, }; @@ -103,8 +109,8 @@ pub struct View { pub last_modified_docs: [Option; 2], /// used to store previous selections of tree-sitter objects pub object_selections: Vec, - /// GutterTypes used to fetch Gutter (constructor) and width for rendering - gutters: Vec, + /// all gutter-related configuration settings, used primarily for gutter rendering + pub gutters: GutterConfig, /// A mapping between documents and the last history revision the view was updated at. /// Changes between documents and views are synced lazily when switching windows. This /// mapping keeps track of the last applied history revision so that only new changes @@ -123,7 +129,7 @@ impl fmt::Debug for View { } impl View { - pub fn new(doc: DocumentId, gutter_types: Vec) -> Self { + pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self { Self { id: ViewId::default(), doc, @@ -133,7 +139,7 @@ impl View { docs_access_history: Vec::new(), last_modified_docs: [None, None], object_selections: Vec::new(), - gutters: gutter_types, + gutters, doc_revisions: HashMap::new(), } } @@ -154,11 +160,12 @@ impl View { } pub fn gutters(&self) -> &[GutterType] { - &self.gutters + &self.gutters.layout } pub fn gutter_offset(&self, doc: &Document) -> u16 { self.gutters + .layout .iter() .map(|gutter| gutter.width(self, doc) as u16) .sum() @@ -414,18 +421,19 @@ impl View { mod tests { use super::*; use helix_core::Rope; - const OFFSET: u16 = 3; // 1 diagnostic + 2 linenr (< 100 lines) - const OFFSET_WITHOUT_LINE_NUMBERS: u16 = 1; // 1 diagnostic - // const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum(); + + // 1 diagnostic + 1 spacer + 3 linenr (< 1000 lines) + 1 spacer + 1 diff + const DEFAULT_GUTTER_OFFSET: u16 = 7; + + // 1 diagnostics + 1 spacer + 1 gutter + const DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS: u16 = 3; + use crate::document::Document; - use crate::editor::GutterType; + use crate::editor::{GutterConfig, GutterLineNumbersConfig, GutterType}; #[test] fn test_text_pos_at_screen_coords() { - let mut view = View::new( - DocumentId::default(), - vec![GutterType::Diagnostics, GutterType::LineNumbers], - ); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); let doc = Document::from(rope, None); @@ -445,24 +453,24 @@ mod tests { assert_eq!(view.text_pos_at_screen_coords(&doc, 78, 41, 4), None); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 3, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 3, 4), Some(3) ); assert_eq!(view.text_pos_at_screen_coords(&doc, 40, 80, 4), Some(3)); assert_eq!( - view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 1, 4), + view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 1, 4), Some(4) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 4, 4), + view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 4, 4), Some(5) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 7, 4), + view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 7, 4), Some(8) ); @@ -471,19 +479,36 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_without_line_numbers_gutter() { - let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]); + let mut view = View::new( + DocumentId::default(), + GutterConfig { + layout: vec![GutterType::Diagnostics], + line_numbers: GutterLineNumbersConfig::default(), + }, + ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); let doc = Document::from(rope, None); assert_eq!( - view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET_WITHOUT_LINE_NUMBERS + 1, 4), + view.text_pos_at_screen_coords( + &doc, + 41, + 40 + DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS + 1, + 4 + ), Some(4) ); } #[test] fn test_text_pos_at_screen_coords_without_any_gutters() { - let mut view = View::new(DocumentId::default(), vec![]); + let mut view = View::new( + DocumentId::default(), + GutterConfig { + layout: vec![], + line_numbers: GutterLineNumbersConfig::default(), + }, + ); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("abc\n\tdef"); let doc = Document::from(rope, None); @@ -492,76 +517,70 @@ mod tests { #[test] fn test_text_pos_at_screen_coords_cjk() { - let mut view = View::new( - DocumentId::default(), - vec![GutterType::Diagnostics, GutterType::LineNumbers], - ); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hi! こんにちは皆さん"); let doc = Document::from(rope, None); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET, 4), Some(0) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 4, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 4, 4), Some(4) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 5, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 5, 4), Some(4) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 6, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 6, 4), Some(5) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 7, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 7, 4), Some(5) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 8, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 8, 4), Some(6) ); } #[test] fn test_text_pos_at_screen_coords_graphemes() { - let mut view = View::new( - DocumentId::default(), - vec![GutterType::Diagnostics, GutterType::LineNumbers], - ); + let mut view = View::new(DocumentId::default(), GutterConfig::default()); view.area = Rect::new(40, 40, 40, 40); let rope = Rope::from_str("Hèl̀l̀ò world!"); let doc = Document::from(rope, None); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET, 4), Some(0) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 1, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 1, 4), Some(1) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 2, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 2, 4), Some(3) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 3, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 3, 4), Some(5) ); assert_eq!( - view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 4, 4), + view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 4, 4), Some(7) ); } -- cgit v1.2.3-70-g09d2