@@ -44,124 +44,6 @@ impl Default for EditorView {
49− spans: Box<dyn Iterator<Item = (usize, std::ops::Range<usize>)>>,
51− next_event: Option<HighlightEvent>,
52− next_span: Option<(usize, std::ops::Range<usize>)>,
54− queue: Vec<HighlightEvent>,
57−fn merge<I: Iterator<Item = HighlightEvent>>(
59− spans: Vec<(usize, std::ops::Range<usize>)>,
60−) -> impl Iterator<Item = HighlightEvent> {
61− let spans = Box::new(spans.into_iter());
62− let mut merge = Merge {
69− merge.next_event = merge.iter.next();
70− merge.next_span = merge.spans.next();
74−impl<I: Iterator<Item = HighlightEvent>> Iterator for Merge<I> {
75− type Item = HighlightEvent;
76− fn next(&mut self) -> Option<Self::Item> {
77− use HighlightEvent::*;
78− if let Some(event) = self.queue.pop() {
83− match (self.next_event, &self.next_span) {
84− // this happens when range is partially or fully offscreen
85− (Some(Source { start, end }), Some((span, range))) if start > range.start => {
86− if start > range.end {
87− self.next_span = self.spans.next();
89− self.next_span = Some((*span, start..range.end));
96− match (self.next_event, &self.next_span) {
97− (Some(HighlightStart(i)), _) => {
98− self.next_event = self.iter.next();
99− Some(HighlightStart(i))
101− (Some(HighlightEnd), _) => {
102− self.next_event = self.iter.next();
105− (Some(Source { start, end }), Some((span, range))) if start < range.start => {
106− let intersect = range.start.min(end);
107− let event = Source {
112− if end == intersect {
113− // the event is complete
114− self.next_event = self.iter.next();
116− // subslice the event
117− self.next_event = Some(Source {
125− (Some(Source { start, end }), Some((span, range))) if start == range.start => {
126− let intersect = range.end.min(end);
127− let event = HighlightStart(Highlight(*span));
129− // enqueue in reverse order
130− self.queue.push(HighlightEnd);
131− self.queue.push(Source {
136− if end == intersect {
137− // the event is complete
138− self.next_event = self.iter.next();
140− // subslice the event
141− self.next_event = Some(Source {
147− if intersect == range.end {
148− self.next_span = self.spans.next();
150− self.next_span = Some((*span, intersect..range.end));
155− (Some(event), None) => {
156− self.next_event = self.iter.next();
159− (None, None) => None,
160− e => unreachable!("{:?}", e),
165impl EditorView {
47impl EditorView {
166 pub fn new(keymaps: Keymaps) -> Self {
48 pub fn new(keymaps: Keymaps) -> Self {
@@ -290,27 +172,16 @@ impl EditorView {
290 .find_scope_index("ui.selection.primary")
172 .find_scope_index("ui.selection.primary")
291 .unwrap_or(selection_scope);
173 .unwrap_or(selection_scope);
293− // TODO: primary + insert mode patching
294− // let primary_cursor_style = theme
295− // .try_get("ui.cursor.primary")
297− // if mode != Mode::Normal {
298− // // we want to make sure that the insert and select highlights
299− // // also affect the primary cursor if set
300− // style.patch(cursor_style)
305− // .unwrap_or(cursor_style);
307− let primary_cursor_scope = theme
308− .find_scope_index("ui.cursor.primary")
309− .unwrap_or(cursor_scope);
311 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
175 let highlights: Box<dyn Iterator<Item = HighlightEvent>> = if is_focused {
312 // inject selections as highlight scopes
176 // inject selections as highlight scopes
313− let mut spans_: Vec<(usize, std::ops::Range<usize>)> = Vec::new();
177+ let mut spans: Vec<(usize, std::ops::Range<usize>)> = Vec::new();
179+ // TODO: primary + insert mode patching:
180+ // (ui.cursor.primary).patch(mode).unwrap_or(cursor)
182+ let primary_cursor_scope = theme
183+ .find_scope_index("ui.cursor.primary")
184+ .unwrap_or(cursor_scope);
315 for (i, range) in selections.iter().enumerate() {
186 for (i, range) in selections.iter().enumerate() {
316 let (cursor_scope, selection_scope) = if i == primary_idx {
187 let (cursor_scope, selection_scope) = if i == primary_idx {
@@ -320,39 +191,40 @@ impl EditorView {
322 if range.head == range.anchor {
193 if range.head == range.anchor {
323− spans_.push((cursor_scope, range.head..range.head + 1));
194+ spans.push((cursor_scope, range.head..range.head + 1));
324 continue;
195 continue;
327 let reverse = range.head < range.anchor;
198 let reverse = range.head < range.anchor;
329 if reverse {
200 if reverse {
330− spans_.push((cursor_scope, range.head..range.head + 1));
201+ spans.push((cursor_scope, range.head..range.head + 1));
331− spans_.push((selection_scope, range.head + 1..range.anchor + 1));
202+ spans.push((selection_scope, range.head + 1..range.anchor + 1));
333− spans_.push((selection_scope, range.anchor..range.head));
204+ spans.push((selection_scope, range.anchor..range.head));
334− spans_.push((cursor_scope, range.head..range.head + 1));
205+ spans.push((cursor_scope, range.head..range.head + 1));
338− Box::new(merge(highlights, spans_))
209+ Box::new(syntax::merge(highlights, spans))
340 Box::new(highlights)
211 Box::new(highlights)
343 // diagnostic injection
214 // diagnostic injection
344 let diagnostic_scope = theme.find_scope_index("diagnostic").unwrap_or(cursor_scope);
215 let diagnostic_scope = theme.find_scope_index("diagnostic").unwrap_or(cursor_scope);
345− let spans_ = doc
216+ let highlights = Box::new(syntax::merge(
346− .diagnostics()
218+ doc.diagnostics()
348− .map(|diagnostic| {
220+ .map(|diagnostic| {
350− diagnostic_scope,
222+ diagnostic_scope,
351− diagnostic.range.start..diagnostic.range.end,
223+ diagnostic.range.start..diagnostic.range.end,
354− .collect();
226+ .collect(),
355− let highlights = Box::new(merge(highlights, spans_));
227+ ));
357 'outer: for event in highlights {
229 'outer: for event in highlights {
358 match event {
230 match event {
@@ -403,16 +275,20 @@ impl EditorView {
403 break 'outer;
275 break 'outer;
405 } else if grapheme == "\t" {
277 } else if grapheme == "\t" {
406− if !out_of_bounds {
278+ if out_of_bounds {
407− // we still want to render an empty cell with the style
279+ // if we're offscreen just keep going until we hit a new line
408− surface.set_string(
280+ visual_x = visual_x.saturating_add(tab_width as u16);
409− viewport.x + visual_x - view.first_col as u16,
281+ continue;
411− " ".repeat(tab_width),
284+ // we still want to render an empty cell with the style
286+ viewport.x + visual_x - view.first_col as u16,
288+ " ".repeat(tab_width),
416 visual_x = visual_x.saturating_add(tab_width as u16);
292 visual_x = visual_x.saturating_add(tab_width as u16);
418 // Cow will prevent allocations if span contained in a single slice
294 // Cow will prevent allocations if span contained in a single slice