Make the gutter render the correct sticky note line number

SoraTenshi 1 year ago
parent f1d26a6a66
commit 987a8dbd0d

@ -198,7 +198,15 @@ impl EditorView {
translated_positions.push((cursor, Box::new(update_cursor_cache))); translated_positions.push((cursor, Box::new(update_cursor_cache)));
} }
Self::render_gutter(editor, doc, view, theme, is_focused, &mut line_decorations); Self::render_gutter(
editor,
doc,
&self.sticky_nodes,
view,
theme,
is_focused,
&mut line_decorations,
);
render_document( render_document(
surface, surface,
@ -595,6 +603,7 @@ impl EditorView {
pub fn render_gutter<'d>( pub fn render_gutter<'d>(
editor: &'d Editor, editor: &'d Editor,
doc: &'d Document, doc: &'d Document,
context: &'d Option<Vec<StickyNode>>,
view: &View, view: &View,
theme: &Theme, theme: &Theme,
is_focused: bool, is_focused: bool,
@ -634,9 +643,20 @@ impl EditorView {
(true, false) => gutter_selected_style_virtual, (true, false) => gutter_selected_style_virtual,
}; };
if let Some(style) = let mut doc_line = Some(pos.doc_line);
gutter(pos.doc_line, selected, pos.first_visual_line, &mut text)
if let Some(current_context) = context
.as_ref()
.and_then(|c| c.iter().find(|n| n.visual_line == pos.visual_line))
{ {
doc_line = if current_context.indicator.is_some() {
None
} else {
Some(current_context.line_nr)
};
}
if let Some(style) = gutter(doc_line, selected, pos.first_visual_line, &mut text) {
renderer renderer
.surface .surface
.set_stringn(x, y, &text, width, gutter_style.patch(style)); .set_stringn(x, y, &text, width, gutter_style.patch(style));
@ -863,12 +883,12 @@ impl EditorView {
context = context context = context
.into_iter() .into_iter()
.rev() .rev()
.take(viewport.height as usize / 3) .take(viewport.height as usize / 3) // only take the nodes until 1 / 3 of the viewport is reached
.enumerate() .enumerate()
.take_while(|(i, _)| *i + 1 != visual_cursor_pos as usize) .take_while(|(i, _)| *i + 1 != visual_cursor_pos as usize) // also only nodes that don't overlap with the visual cursor position
.map(|(index, node)| { .map(|(i, node)| {
let mut new_node = node; let mut new_node = node;
new_node.visual_line = index as u16; new_node.visual_line = i as u16;
new_node new_node
}) })
.collect(); .collect();

@ -11,7 +11,8 @@ fn count_digits(n: usize) -> usize {
std::iter::successors(Some(n), |&n| (n >= 10).then_some(n / 10)).count() std::iter::successors(Some(n), |&n| (n >= 10).then_some(n / 10)).count()
} }
pub type GutterFn<'doc> = Box<dyn FnMut(usize, bool, bool, &mut String) -> Option<Style> + 'doc>; pub type GutterFn<'doc> =
Box<dyn FnMut(Option<usize>, bool, bool, &mut String) -> Option<Style> + 'doc>;
pub type Gutter = pub type Gutter =
for<'doc> fn(&'doc Editor, &'doc Document, &View, &Theme, bool, usize) -> GutterFn<'doc>; for<'doc> fn(&'doc Editor, &'doc Document, &View, &Theme, bool, usize) -> GutterFn<'doc>;
@ -58,10 +59,11 @@ pub fn diagnostic<'doc>(
let diagnostics = doc.diagnostics(); let diagnostics = doc.diagnostics();
Box::new( Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| { move |line: Option<usize>, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line { if !first_visual_line || line.is_none() {
return None; return None;
} }
let line = line.expect("line exists");
use helix_core::diagnostic::Severity; use helix_core::diagnostic::Severity;
if let Ok(index) = diagnostics.binary_search_by_key(&line, |d| d.line) { if let Ok(index) = diagnostics.binary_search_by_key(&line, |d| d.line) {
let after = diagnostics[index..].iter().take_while(|d| d.line == line); let after = diagnostics[index..].iter().take_while(|d| d.line == line);
@ -104,12 +106,20 @@ pub fn diff<'doc>(
let mut hunk_i = 0; let mut hunk_i = 0;
let mut hunk = hunks.nth_hunk(hunk_i); let mut hunk = hunks.nth_hunk(hunk_i);
Box::new( Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| { move |line: Option<usize>,
_selected: bool,
first_visual_line: bool,
out: &mut String| {
// truncating the line is fine here because we don't compute diffs // truncating the line is fine here because we don't compute diffs
// for files with more lines than i32::MAX anyways // for files with more lines than i32::MAX anyways
// we need to special case removals here // we need to special case removals here
// these technically do not have a range of lines to highlight (`hunk.after.start == hunk.after.end`). // these technically do not have a range of lines to highlight (`hunk.after.start == hunk.after.end`).
// However we still want to display these hunks correctly we must not yet skip to the next hunk here // However we still want to display these hunks correctly we must not yet skip to the next hunk here
if line.is_none() {
return None;
}
let line = line.expect("line exists");
while hunk.after.end < line as u32 while hunk.after.end < line as u32
|| !hunk.is_pure_removal() && line as u32 == hunk.after.end || !hunk.is_pure_removal() && line as u32 == hunk.after.end
{ {
@ -168,7 +178,12 @@ pub fn line_numbers<'doc>(
let mode = editor.mode; let mode = editor.mode;
Box::new( Box::new(
move |line: usize, selected: bool, first_visual_line: bool, out: &mut String| { move |line: Option<usize>, selected: bool, first_visual_line: bool, out: &mut String| {
if line.is_none() {
return None;
}
let line = line.expect("line exists");
if line == last_line_in_view && !draw_last { if line == last_line_in_view && !draw_last {
write!(out, "{:>1$}", '~', width).unwrap(); write!(out, "{:>1$}", '~', width).unwrap();
Some(linenr) Some(linenr)
@ -226,7 +241,9 @@ pub fn padding<'doc>(
_theme: &Theme, _theme: &Theme,
_is_focused: bool, _is_focused: bool,
) -> GutterFn<'doc> { ) -> GutterFn<'doc> {
Box::new(|_line: usize, _selected: bool, _first_visual_line: bool, _out: &mut String| None) Box::new(
|_line: Option<usize>, _selected: bool, _first_visual_line: bool, _out: &mut String| None,
)
} }
#[inline(always)] #[inline(always)]
@ -257,10 +274,11 @@ pub fn breakpoints<'doc>(
}; };
Box::new( Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| { move |line: Option<usize>, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line { if !first_visual_line || line.is_none() {
return None; return None;
} }
let line = line.expect("line exists");
let breakpoint = breakpoints let breakpoint = breakpoints
.iter() .iter()
.find(|breakpoint| breakpoint.line == line)?; .find(|breakpoint| breakpoint.line == line)?;

Loading…
Cancel
Save