@@ -1,4 +1,10 @@
1−use crate::{align_view, editor::GutterType, graphics::Rect, Align, Document, DocumentId, ViewId};
1+use crate::{
2+ align_view,
3+ editor::{GutterConfig, GutterType},
4+ graphics::Rect,
5+ Align, Document, DocumentId, ViewId,
6+};
7+
28use helix_core::{
39 pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction,
410};
@@ -103,8 +109,8 @@ pub struct View {
103109 pub last_modified_docs: [Option<DocumentId>; 2],
104110 /// used to store previous selections of tree-sitter objects
105111 pub object_selections: Vec<Selection>,
106− /// GutterTypes used to fetch Gutter (constructor) and width for rendering
107− gutters: Vec<GutterType>,
112+ /// all gutter-related configuration settings, used primarily for gutter rendering
113+ pub gutters: GutterConfig,
108114 /// A mapping between documents and the last history revision the view was updated at.
109115 /// Changes between documents and views are synced lazily when switching windows. This
110116 /// mapping keeps track of the last applied history revision so that only new changes
@@ -123,7 +129,7 @@ impl fmt::Debug for View {
123129}
124130
125131impl View {
126− pub fn new(doc: DocumentId, gutter_types: Vec<crate::editor::GutterType>) -> Self {
132+ pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self {
127133 Self {
128134 id: ViewId::default(),
129135 doc,
@@ -133,7 +139,7 @@ impl View {
133139 docs_access_history: Vec::new(),
134140 last_modified_docs: [None, None],
135141 object_selections: Vec::new(),
136− gutters: gutter_types,
142+ gutters,
137143 doc_revisions: HashMap::new(),
138144 }
139145 }
@@ -154,11 +160,12 @@ impl View {
154160 }
155161
156162 pub fn gutters(&self) -> &[GutterType] {
157− &self.gutters
163+ &self.gutters.layout
158164 }
159165
160166 pub fn gutter_offset(&self, doc: &Document) -> u16 {
161167 self.gutters
168+ .layout
162169 .iter()
163170 .map(|gutter| gutter.width(self, doc) as u16)
164171 .sum()
@@ -414,18 +421,19 @@ impl View {
414421mod tests {
415422 use super::*;
416423 use helix_core::Rope;
417− const OFFSET: u16 = 3; // 1 diagnostic + 2 linenr (< 100 lines)
418− const OFFSET_WITHOUT_LINE_NUMBERS: u16 = 1; // 1 diagnostic
419− // const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum();
424+
425+ // 1 diagnostic + 1 spacer + 3 linenr (< 1000 lines) + 1 spacer + 1 diff
426+ const DEFAULT_GUTTER_OFFSET: u16 = 7;
427+
428+ // 1 diagnostics + 1 spacer + 1 gutter
429+ const DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS: u16 = 3;
430+
420431 use crate::document::Document;
421− use crate::editor::GutterType;
432+ use crate::editor::{GutterConfig, GutterLineNumbersConfig, GutterType};
422433
423434 #[test]
424435 fn test_text_pos_at_screen_coords() {
425− let mut view = View::new(
426− DocumentId::default(),
427− vec![GutterType::Diagnostics, GutterType::LineNumbers],
428− );
436+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
429437 view.area = Rect::new(40, 40, 40, 40);
430438 let rope = Rope::from_str("abc\n\tdef");
431439 let doc = Document::from(rope, None);
@@ -445,24 +453,24 @@ mod tests {
445453 assert_eq!(view.text_pos_at_screen_coords(&doc, 78, 41, 4), None);
446454
447455 assert_eq!(
448− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 3, 4),
456+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 3, 4),
449457 Some(3)
450458 );
451459
452460 assert_eq!(view.text_pos_at_screen_coords(&doc, 40, 80, 4), Some(3));
453461
454462 assert_eq!(
455− view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 1, 4),
463+ view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 1, 4),
456464 Some(4)
457465 );
458466
459467 assert_eq!(
460− view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 4, 4),
468+ view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 4, 4),
461469 Some(5)
462470 );
463471
464472 assert_eq!(
465− view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET + 7, 4),
473+ view.text_pos_at_screen_coords(&doc, 41, 40 + DEFAULT_GUTTER_OFFSET + 7, 4),
466474 Some(8)
467475 );
468476
@@ -471,19 +479,36 @@ mod tests {
471479
472480 #[test]
473481 fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
474− let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]);
482+ let mut view = View::new(
483+ DocumentId::default(),
484+ GutterConfig {
485+ layout: vec![GutterType::Diagnostics],
486+ line_numbers: GutterLineNumbersConfig::default(),
487+ },
488+ );
475489 view.area = Rect::new(40, 40, 40, 40);
476490 let rope = Rope::from_str("abc\n\tdef");
477491 let doc = Document::from(rope, None);
478492 assert_eq!(
479− view.text_pos_at_screen_coords(&doc, 41, 40 + OFFSET_WITHOUT_LINE_NUMBERS + 1, 4),
493+ view.text_pos_at_screen_coords(
494+ &doc,
495+ 41,
496+ 40 + DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS + 1,
497+ 4
498+ ),
480499 Some(4)
481500 );
482501 }
483502
484503 #[test]
485504 fn test_text_pos_at_screen_coords_without_any_gutters() {
486− let mut view = View::new(DocumentId::default(), vec![]);
505+ let mut view = View::new(
506+ DocumentId::default(),
507+ GutterConfig {
508+ layout: vec![],
509+ line_numbers: GutterLineNumbersConfig::default(),
510+ },
511+ );
487512 view.area = Rect::new(40, 40, 40, 40);
488513 let rope = Rope::from_str("abc\n\tdef");
489514 let doc = Document::from(rope, None);
@@ -492,76 +517,70 @@ mod tests {
492517
493518 #[test]
494519 fn test_text_pos_at_screen_coords_cjk() {
495− let mut view = View::new(
496− DocumentId::default(),
497− vec![GutterType::Diagnostics, GutterType::LineNumbers],
498− );
520+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
499521 view.area = Rect::new(40, 40, 40, 40);
500522 let rope = Rope::from_str("Hi! こんにちは皆さん");
501523 let doc = Document::from(rope, None);
502524
503525 assert_eq!(
504− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4),
526+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET, 4),
505527 Some(0)
506528 );
507529
508530 assert_eq!(
509− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 4, 4),
531+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 4, 4),
510532 Some(4)
511533 );
512534 assert_eq!(
513− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 5, 4),
535+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 5, 4),
514536 Some(4)
515537 );
516538
517539 assert_eq!(
518− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 6, 4),
540+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 6, 4),
519541 Some(5)
520542 );
521543
522544 assert_eq!(
523− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 7, 4),
545+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 7, 4),
524546 Some(5)
525547 );
526548
527549 assert_eq!(
528− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 8, 4),
550+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 8, 4),
529551 Some(6)
530552 );
531553 }
532554
533555 #[test]
534556 fn test_text_pos_at_screen_coords_graphemes() {
535− let mut view = View::new(
536− DocumentId::default(),
537− vec![GutterType::Diagnostics, GutterType::LineNumbers],
538− );
557+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
539558 view.area = Rect::new(40, 40, 40, 40);
540559 let rope = Rope::from_str("Hèl̀l̀ò world!");
541560 let doc = Document::from(rope, None);
542561
543562 assert_eq!(
544− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET, 4),
563+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET, 4),
545564 Some(0)
546565 );
547566
548567 assert_eq!(
549− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 1, 4),
568+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 1, 4),
550569 Some(1)
551570 );
552571
553572 assert_eq!(
554− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 2, 4),
573+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 2, 4),
555574 Some(3)
556575 );
557576
558577 assert_eq!(
559− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 3, 4),
578+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 3, 4),
560579 Some(5)
561580 );
562581
563582 assert_eq!(
564− view.text_pos_at_screen_coords(&doc, 40, 40 + OFFSET + 4, 4),
583+ view.text_pos_at_screen_coords(&doc, 40, 40 + DEFAULT_GUTTER_OFFSET + 4, 4),
565584 Some(7)
566585 );
567586 }