@@ -11,6 +11,8 @@ use helix_core::{
11 visual_coords_at_pos, Position, RopeSlice, Selection,
11 visual_coords_at_pos, Position, RopeSlice, Selection,
14type Jump = (DocumentId, Selection);
16type Jump = (DocumentId, Selection);
16#[derive(Debug, Clone)]
18#[derive(Debug, Clone)]
@@ -64,17 +66,11 @@ impl JumpList {
67−const GUTTERS: &[(Gutter, usize)] = &[
68− (gutter::diagnostics_or_breakpoints, 1),
69− (gutter::line_number, 5),
73pub struct View {
69pub struct View {
74 pub id: ViewId,
70 pub id: ViewId,
76 pub offset: Position,
71 pub offset: Position,
77 pub area: Rect,
72 pub area: Rect,
78 pub jumps: JumpList,
74 pub jumps: JumpList,
79 /// the last accessed file before the current one
75 /// the last accessed file before the current one
80 pub last_accessed_doc: Option<DocumentId>,
76 pub last_accessed_doc: Option<DocumentId>,
@@ -85,10 +81,29 @@ pub struct View {
85 pub last_modified_docs: [Option<DocumentId>; 2],
81 pub last_modified_docs: [Option<DocumentId>; 2],
86 /// used to store previous selections of tree-sitter objecs
82 /// used to store previous selections of tree-sitter objecs
87 pub object_selections: Vec<Selection>,
83 pub object_selections: Vec<Selection>,
84+ pub gutters: Vec<(Gutter, usize)>,
87+impl fmt::Debug for View {
88+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89+ f.debug_struct("View")
90+ .field("id", &self.id)
91+ .field("area", &self.area)
92+ .field("doc", &self.doc)
90impl View {
97impl View {
91− pub fn new(doc: DocumentId) -> Self {
98+ pub fn new(doc: DocumentId, gutter_types: Vec<crate::editor::GutterType>) -> Self {
99+ let mut gutters: Vec<(Gutter, usize)> = vec![];
100+ use crate::editor::GutterType;
101+ for gutter_type in &gutter_types {
103+ GutterType::Diagnostics => gutters.push((gutter::diagnostics_or_breakpoints, 1)),
104+ GutterType::LineNumbers => gutters.push((gutter::line_numbers, 5)),
93 id: ViewId::default(),
108 id: ViewId::default(),
@@ -98,17 +113,14 @@ impl View {
98 last_accessed_doc: None,
113 last_accessed_doc: None,
99 last_modified_docs: [None, None],
114 last_modified_docs: [None, None],
100 object_selections: Vec::new(),
115 object_selections: Vec::new(),
104− pub fn gutters(&self) -> &[(Gutter, usize)] {
108 pub fn inner_area(&self) -> Rect {
120 pub fn inner_area(&self) -> Rect {
109 // TODO: cache this
121 // TODO: cache this
110 let offset = self
122 let offset = self
111− .gutters()
123+ .gutters
113 .map(|(_, width)| *width as u16)
125 .map(|(_, width)| *width as u16)
114 .sum::<u16>()
126 .sum::<u16>()
@@ -324,11 +336,16 @@ mod tests {
324 use super::*;
336 use super::*;
325 use helix_core::Rope;
337 use helix_core::Rope;
326 const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
338 const OFFSET: u16 = 7; // 1 diagnostic + 5 linenr + 1 gutter
339+ const OFFSET_WITHOUT_LINE_NUMBERS: u16 = 2; // 1 diagnostic + 1 gutter
327− // const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum();
340+ // const OFFSET: u16 = GUTTERS.iter().map(|(_, width)| *width as u16).sum();
341+ use crate::editor::GutterType;
330 fn test_text_pos_at_screen_coords() {
344 fn test_text_pos_at_screen_coords() {
331− let mut view = View::new(DocumentId::default());
345+ let mut view = View::new(
346+ DocumentId::default(),
347+ vec![GutterType::Diagnostics, GutterType::LineNumbers],
332 view.area = Rect::new(40, 40, 40, 40);
349 view.area = Rect::new(40, 40, 40, 40);
333 let rope = Rope::from_str("abc\n\tdef");
350 let rope = Rope::from_str("abc\n\tdef");
334 let text = rope.slice(..);
351 let text = rope.slice(..);
@@ -372,9 +389,36 @@ mod tests {
372 assert_eq!(view.text_pos_at_screen_coords(&text, 41, 80, 4), Some(8));
389 assert_eq!(view.text_pos_at_screen_coords(&text, 41, 80, 4), Some(8));
393+ fn test_text_pos_at_screen_coords_without_line_numbers_gutter() {
394+ let mut view = View::new(DocumentId::default(), vec![GutterType::Diagnostics]);
395+ view.area = Rect::new(40, 40, 40, 40);
396+ let rope = Rope::from_str("abc\n\tdef");
397+ let text = rope.slice(..);
399+ view.text_pos_at_screen_coords(&text, 41, 40 + OFFSET_WITHOUT_LINE_NUMBERS + 1, 4),
405+ fn test_text_pos_at_screen_coords_without_any_gutters() {
406+ let mut view = View::new(DocumentId::default(), vec![]);
407+ view.area = Rect::new(40, 40, 40, 40);
408+ let rope = Rope::from_str("abc\n\tdef");
409+ let text = rope.slice(..);
411+ view.text_pos_at_screen_coords(&text, 41, 40 + 1, 4),
376 fn test_text_pos_at_screen_coords_cjk() {
417 fn test_text_pos_at_screen_coords_cjk() {
377− let mut view = View::new(DocumentId::default());
418+ let mut view = View::new(
419+ DocumentId::default(),
420+ vec![GutterType::Diagnostics, GutterType::LineNumbers],
378 view.area = Rect::new(40, 40, 40, 40);
422 view.area = Rect::new(40, 40, 40, 40);
379 let rope = Rope::from_str("Hi! こんにちは皆さん");
423 let rope = Rope::from_str("Hi! こんにちは皆さん");
380 let text = rope.slice(..);
424 let text = rope.slice(..);
@@ -411,7 +455,10 @@ mod tests {
413 fn test_text_pos_at_screen_coords_graphemes() {
457 fn test_text_pos_at_screen_coords_graphemes() {
414− let mut view = View::new(DocumentId::default());
458+ let mut view = View::new(
459+ DocumentId::default(),
460+ vec![GutterType::Diagnostics, GutterType::LineNumbers],
415 view.area = Rect::new(40, 40, 40, 40);
462 view.area = Rect::new(40, 40, 40, 40);
416 let rope = Rope::from_str("Hèl̀l̀ò world!");
463 let rope = Rope::from_str("Hèl̀l̀ò world!");
417 let text = rope.slice(..);
464 let text = rope.slice(..);