diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 1a47d50ef..1500c67a7 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -35,11 +35,12 @@ use tui::buffer::Buffer as Surface; use super::{document::render_text, statusline}; use super::{document::LineDecoration, lsp::SignatureHelp}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct StickyNode { visual_line: u16, line_nr: usize, indicator: Option, + top_first_byte: usize, } pub struct EditorView { @@ -748,7 +749,7 @@ impl EditorView { return; } - let context = context.as_ref().expect("context has value"); + let context = context.as_deref().expect("context has value"); let text = doc.text().slice(..); let viewport = view.inner_area(doc); @@ -763,14 +764,8 @@ impl EditorView { for node in context { surface.clear_with(context_area, context_style); - if node.indicator.is_some() { - surface.set_string( - context_area.x, - context_area.y, - node.indicator.as_ref().expect("indicator exists"), - indicator_style, - ); - + if let Some(indicator) = node.indicator.as_deref() { + surface.set_string(context_area.x, context_area.y, indicator, indicator_style); continue; } @@ -786,7 +781,6 @@ impl EditorView { view.offset.horizontal_offset, context_area, ); - let mut new_offset = view.offset; new_offset.anchor = line_num_anchor; @@ -820,9 +814,24 @@ impl EditorView { let tree = syntax.tree(); let text = doc.text().slice(..); let viewport = view.inner_area(doc); + let cursor_line = doc.selection(view.id).primary().cursor(text); + + // Use the cached nodes to determine the current topmost viewport + let anchor_line = text.char_to_line(view.offset.anchor); + let top_first_byte = + text.line_to_byte(anchor_line + nodes.as_deref().map_or(0, |v| v.len())); + + if let Some(nodes) = nodes { + if nodes + .iter() + .any(|node| node.top_first_byte == top_first_byte) + { + return Some(nodes.to_vec()); + } + } let visual_cursor_pos = view - .screen_coords_at_pos(doc, text, doc.selection(view.id).primary().cursor(text)) + .screen_coords_at_pos(doc, text, cursor_line) .unwrap_or_default() .row as u16; @@ -830,11 +839,6 @@ impl EditorView { return None; } - // Use the cached nodes to determine the current topmost viewport - let anchor_line = text.char_to_line(view.offset.anchor); - let top_first_byte = - text.line_to_byte(anchor_line + nodes.as_ref().unwrap_or(&Vec::new()).len()); - let context_nodes = doc .language_config() .and_then(|lc| lc.sticky_context_nodes.as_ref()); @@ -846,6 +850,7 @@ impl EditorView { // context is list of numbers of lines that should be rendered in the LSP context let mut context: Vec = Vec::new(); + while let Some(node) = parent { // if the node is smaller than half the viewport height, skip if (node.end_position().row - node.start_position().row) < viewport.height as usize / 2 @@ -868,6 +873,7 @@ impl EditorView { visual_line: 0, // with sorting it will be done line_nr: line, indicator: None, + top_first_byte, }); } @@ -912,6 +918,7 @@ impl EditorView { visual_line: context.len() as u16, line_nr: 0, indicator: Some(str), + top_first_byte, }) }