@@ -1,4 +1,10 @@
3+ editor::{GutterConfig, GutterType},
1−use crate::{align_view, editor::GutterType, graphics::Rect, Align, Document, DocumentId, ViewId};
5+ Align, Document, DocumentId, ViewId,
2use helix_core::{
8use helix_core::{
3 pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction,
9 pos_at_visual_coords, visual_coords_at_pos, Position, RopeSlice, Selection, Transaction,
@@ -103,8 +109,8 @@ pub struct View {
103 pub last_modified_docs: [Option<DocumentId>; 2],
109 pub last_modified_docs: [Option<DocumentId>; 2],
104 /// used to store previous selections of tree-sitter objects
110 /// used to store previous selections of tree-sitter objects
105 pub object_selections: Vec<Selection>,
111 pub object_selections: Vec<Selection>,
106− /// GutterTypes used to fetch Gutter (constructor) and width for rendering
112+ /// all gutter-related configuration settings, used primarily for gutter rendering
107− gutters: Vec<GutterType>,
113+ pub gutters: GutterConfig,
108 /// A mapping between documents and the last history revision the view was updated at.
114 /// A mapping between documents and the last history revision the view was updated at.
109 /// Changes between documents and views are synced lazily when switching windows. This
115 /// Changes between documents and views are synced lazily when switching windows. This
110 /// mapping keeps track of the last applied history revision so that only new changes
116 /// mapping keeps track of the last applied history revision so that only new changes
@@ -123,7 +129,7 @@ impl fmt::Debug for View {
125impl View {
131impl View {
126− pub fn new(doc: DocumentId, gutter_types: Vec<crate::editor::GutterType>) -> Self {
132+ pub fn new(doc: DocumentId, gutters: GutterConfig) -> Self {
128 id: ViewId::default(),
134 id: ViewId::default(),
@@ -133,7 +139,7 @@ impl View {
133 docs_access_history: Vec::new(),
139 docs_access_history: Vec::new(),
134 last_modified_docs: [None, None],
140 last_modified_docs: [None, None],
135 object_selections: Vec::new(),
141 object_selections: Vec::new(),
136− gutters: gutter_types,
142+ gutters,
137 doc_revisions: HashMap::new(),
143 doc_revisions: HashMap::new(),
@@ -154,11 +160,12 @@ impl View {
156 pub fn gutters(&self) -> &[GutterType] {
162 pub fn gutters(&self) -> &[GutterType] {
157− &self.gutters
163+ &self.gutters.layout
160 pub fn gutter_offset(&self, doc: &Document) -> u16 {
166 pub fn gutter_offset(&self, doc: &Document) -> u16 {
161 self.gutters
167 self.gutters
163 .map(|gutter| gutter.width(self, doc) as u16)
170 .map(|gutter| gutter.width(self, doc) as u16)
@@ -414,18 +421,19 @@ impl View {
414mod tests {
421mod tests {
415 use super::*;
422 use super::*;
416 use helix_core::Rope;
423 use helix_core::Rope;
417− const OFFSET: u16 = 3; // 1 diagnostic + 2 linenr (< 100 lines)
424+
418− const OFFSET_WITHOUT_LINE_NUMBERS: u16 = 1; // 1 diagnostic
425+ // 1 diagnostic + 1 spacer + 3 linenr (< 1000 lines) + 1 spacer + 1 diff
419− // const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum();
426+ const DEFAULT_GUTTER_OFFSET: u16 = 7;
428+ // 1 diagnostics + 1 spacer + 1 gutter
429+ const DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS: u16 = 3;
420 use crate::document::Document;
431 use crate::document::Document;
421− use crate::editor::GutterType;
432+ use crate::editor::{GutterConfig, GutterLineNumbersConfig, GutterType};
424 fn test_text_pos_at_screen_coords() {
435 fn test_text_pos_at_screen_coords() {
425− let mut view = View::new(
436+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
426− DocumentId::default(),
427− vec![GutterType::Diagnostics, GutterType::LineNumbers],
429 view.area = Rect::new(40, 40, 40, 40);
437 view.area = Rect::new(40, 40, 40, 40);
430 let rope = Rope::from_str("abc\n\tdef");
438 let rope = Rope::from_str("abc\n\tdef");
431 let doc = Document::from(rope, None);
439 let doc = Document::from(rope, None);
@@ -445,24 +453,24 @@ mod tests {
445 assert_eq!(view.text_pos_at_screen_coords(&doc, 78, 41, 4), None);
453 assert_eq!(view.text_pos_at_screen_coords(&doc, 78, 41, 4), None);
447 assert_eq!(
455 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),
452 assert_eq!(view.text_pos_at_screen_coords(&doc, 40, 80, 4), Some(3));
460 assert_eq!(view.text_pos_at_screen_coords(&doc, 40, 80, 4), Some(3));
454 assert_eq!(
462 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),
459 assert_eq!(
467 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),
464 assert_eq!(
472 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),
@@ -471,19 +479,36 @@ mod tests {
473 fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
481 fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
482+ let mut view = View::new(
483+ DocumentId::default(),
474− let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]);
485+ layout: vec![GutterType::Diagnostics],
486+ line_numbers: GutterLineNumbersConfig::default(),
475 view.area = Rect::new(40, 40, 40, 40);
489 view.area = Rect::new(40, 40, 40, 40);
476 let rope = Rope::from_str("abc\n\tdef");
490 let rope = Rope::from_str("abc\n\tdef");
477 let doc = Document::from(rope, None);
491 let doc = Document::from(rope, None);
478 assert_eq!(
492 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(
496+ 40 + DEFAULT_GUTTER_OFFSET_ONLY_DIAGNOSTICS + 1,
485 fn test_text_pos_at_screen_coords_without_any_gutters() {
504 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(),
509+ line_numbers: GutterLineNumbersConfig::default(),
487 view.area = Rect::new(40, 40, 40, 40);
512 view.area = Rect::new(40, 40, 40, 40);
488 let rope = Rope::from_str("abc\n\tdef");
513 let rope = Rope::from_str("abc\n\tdef");
489 let doc = Document::from(rope, None);
514 let doc = Document::from(rope, None);
@@ -492,76 +517,70 @@ mod tests {
494 fn test_text_pos_at_screen_coords_cjk() {
519 fn test_text_pos_at_screen_coords_cjk() {
495− let mut view = View::new(
520+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
496− DocumentId::default(),
497− vec![GutterType::Diagnostics, GutterType::LineNumbers],
499 view.area = Rect::new(40, 40, 40, 40);
521 view.area = Rect::new(40, 40, 40, 40);
500 let rope = Rope::from_str("Hi! こんにちは皆さん");
522 let rope = Rope::from_str("Hi! こんにちは皆さん");
501 let doc = Document::from(rope, None);
523 let doc = Document::from(rope, None);
503 assert_eq!(
525 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),
508 assert_eq!(
530 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),
512 assert_eq!(
534 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),
517 assert_eq!(
539 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),
522 assert_eq!(
544 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),
527 assert_eq!(
549 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),
534 fn test_text_pos_at_screen_coords_graphemes() {
556 fn test_text_pos_at_screen_coords_graphemes() {
535− let mut view = View::new(
557+ let mut view = View::new(DocumentId::default(), GutterConfig::default());
536− DocumentId::default(),
537− vec![GutterType::Diagnostics, GutterType::LineNumbers],
539 view.area = Rect::new(40, 40, 40, 40);
558 view.area = Rect::new(40, 40, 40, 40);
540 let rope = Rope::from_str("Hèl̀l̀ò world!");
559 let rope = Rope::from_str("Hèl̀l̀ò world!");
541 let doc = Document::from(rope, None);
560 let doc = Document::from(rope, None);
543 assert_eq!(
562 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),
548 assert_eq!(
567 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),
553 assert_eq!(
572 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),
558 assert_eq!(
577 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),
563 assert_eq!(
582 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),