@@ -75,7 +75,11 @@ pub struct View {
75 pub last_modified_docs: [Option<DocumentId>; 2],
75 pub last_modified_docs: [Option<DocumentId>; 2],
76 /// used to store previous selections of tree-sitter objects
76 /// used to store previous selections of tree-sitter objects
77 pub object_selections: Vec<Selection>,
77 pub object_selections: Vec<Selection>,
78+ /// Gutter (constructor) and width of gutter, used to calculate
78− pub gutters: Vec<(Gutter, usize)>,
80+ gutters: Vec<(Gutter, usize)>,
81+ /// cached total width of gutter
81impl fmt::Debug for View {
85impl fmt::Debug for View {
@@ -91,12 +95,23 @@ impl fmt::Debug for View {
91impl View {
95impl View {
92 pub fn new(doc: DocumentId, gutter_types: Vec<crate::editor::GutterType>) -> Self {
96 pub fn new(doc: DocumentId, gutter_types: Vec<crate::editor::GutterType>) -> Self {
93 let mut gutters: Vec<(Gutter, usize)> = vec![];
97 let mut gutters: Vec<(Gutter, usize)> = vec![];
98+ let mut gutter_offset = 0;
94 use crate::editor::GutterType;
99 use crate::editor::GutterType;
95 for gutter_type in &gutter_types {
100 for gutter_type in &gutter_types {
96− match gutter_type {
101+ let width = match gutter_type {
102+ GutterType::Diagnostics => 1,
103+ GutterType::LineNumbers => 5,
104+ GutterType::Padding => 1,
106+ gutter_offset += width;
97− GutterType::Diagnostics => gutters.push((gutter::diagnostics_or_breakpoints, 1)),
109+ GutterType::Diagnostics => gutter::diagnostics_or_breakpoints,
98− GutterType::LineNumbers => gutters.push((gutter::line_numbers, 5)),
110+ GutterType::LineNumbers => gutter::line_numbers,
111+ GutterType::Padding => gutter::padding,
102 id: ViewId::default(),
117 id: ViewId::default(),
@@ -108,6 +123,7 @@ impl View {
108 last_modified_docs: [None, None],
123 last_modified_docs: [None, None],
109 object_selections: Vec::new(),
124 object_selections: Vec::new(),
@@ -119,14 +135,12 @@ impl View {
121 pub fn inner_area(&self) -> Rect {
137 pub fn inner_area(&self) -> Rect {
122− // TODO: cache this
138+ // TODO add abilty to not use cached offset for runtime configurable gutter
126− .map(|(_, width)| *width as u16)
128− + 1; // +1 for some space between gutters and line
129− self.area.clip_left(offset).clip_bottom(1) // -1 for statusline
139+ self.area.clip_left(self.gutter_offset).clip_bottom(1) // -1 for statusline
142+ pub fn gutters(&self) -> &[(Gutter, usize)] {
@@ -327,7 +341,11 @@ mod tests {
327 fn test_text_pos_at_screen_coords() {
341 fn test_text_pos_at_screen_coords() {
328 let mut view = View::new(
342 let mut view = View::new(
329 DocumentId::default(),
343 DocumentId::default(),
330− vec![GutterType::Diagnostics, GutterType::LineNumbers],
345+ GutterType::Diagnostics,
346+ GutterType::LineNumbers,
347+ GutterType::Padding,
332 view.area = Rect::new(40, 40, 40, 40);
350 view.area = Rect::new(40, 40, 40, 40);
333 let rope = Rope::from_str("abc\n\tdef");
351 let rope = Rope::from_str("abc\n\tdef");
@@ -374,7 +392,10 @@ mod tests {
376 fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
394 fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
395+ let mut view = View::new(
396+ DocumentId::default(),
377− let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]);
397+ vec![GutterType::Diagnostics, GutterType::Padding],
378 view.area = Rect::new(40, 40, 40, 40);
399 view.area = Rect::new(40, 40, 40, 40);
379 let rope = Rope::from_str("abc\n\tdef");
400 let rope = Rope::from_str("abc\n\tdef");
380 let text = rope.slice(..);
401 let text = rope.slice(..);
@@ -400,7 +421,11 @@ mod tests {
400 fn test_text_pos_at_screen_coords_cjk() {
421 fn test_text_pos_at_screen_coords_cjk() {
401 let mut view = View::new(
422 let mut view = View::new(
402 DocumentId::default(),
423 DocumentId::default(),
403− vec![GutterType::Diagnostics, GutterType::LineNumbers],
425+ GutterType::Diagnostics,
426+ GutterType::LineNumbers,
427+ GutterType::Padding,
405 view.area = Rect::new(40, 40, 40, 40);
430 view.area = Rect::new(40, 40, 40, 40);
406 let rope = Rope::from_str("Hi! こんにちは皆さん");
431 let rope = Rope::from_str("Hi! こんにちは皆さん");
@@ -440,7 +465,11 @@ mod tests {
440 fn test_text_pos_at_screen_coords_graphemes() {
465 fn test_text_pos_at_screen_coords_graphemes() {
441 let mut view = View::new(
466 let mut view = View::new(
442 DocumentId::default(),
467 DocumentId::default(),
443− vec![GutterType::Diagnostics, GutterType::LineNumbers],
469+ GutterType::Diagnostics,
470+ GutterType::LineNumbers,
471+ GutterType::Padding,
445 view.area = Rect::new(40, 40, 40, 40);
474 view.area = Rect::new(40, 40, 40, 40);
446 let rope = Rope::from_str("Hèl̀l̀ò world!");
475 let rope = Rope::from_str("Hèl̀l̀ò world!");