Make the gutter render the correct sticky note line number

pull/6118/merge^2
SoraTenshi 1 year ago
parent f1d26a6a66
commit 987a8dbd0d

@ -198,7 +198,15 @@ impl EditorView {
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(
surface,
@ -595,6 +603,7 @@ impl EditorView {
pub fn render_gutter<'d>(
editor: &'d Editor,
doc: &'d Document,
context: &'d Option<Vec<StickyNode>>,
view: &View,
theme: &Theme,
is_focused: bool,
@ -634,9 +643,20 @@ impl EditorView {
(true, false) => gutter_selected_style_virtual,
};
if let Some(style) =
gutter(pos.doc_line, selected, pos.first_visual_line, &mut text)
let mut doc_line = Some(pos.doc_line);
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
.surface
.set_stringn(x, y, &text, width, gutter_style.patch(style));
@ -863,12 +883,12 @@ impl EditorView {
context = context
.into_iter()
.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()
.take_while(|(i, _)| *i + 1 != visual_cursor_pos as usize)
.map(|(index, node)| {
.take_while(|(i, _)| *i + 1 != visual_cursor_pos as usize) // also only nodes that don't overlap with the visual cursor position
.map(|(i, node)| {
let mut new_node = node;
new_node.visual_line = index as u16;
new_node.visual_line = i as u16;
new_node
})
.collect();

@ -11,7 +11,8 @@ fn count_digits(n: usize) -> usize {
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 =
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();
Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line {
move |line: Option<usize>, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line || line.is_none() {
return None;
}
let line = line.expect("line exists");
use helix_core::diagnostic::Severity;
if let Ok(index) = diagnostics.binary_search_by_key(&line, |d| d.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 = hunks.nth_hunk(hunk_i);
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
// for files with more lines than i32::MAX anyways
// we need to special case removals here
// 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
if line.is_none() {
return None;
}
let line = line.expect("line exists");
while hunk.after.end < line as u32
|| !hunk.is_pure_removal() && line as u32 == hunk.after.end
{
@ -168,7 +178,12 @@ pub fn line_numbers<'doc>(
let mode = editor.mode;
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 {
write!(out, "{:>1$}", '~', width).unwrap();
Some(linenr)
@ -226,7 +241,9 @@ pub fn padding<'doc>(
_theme: &Theme,
_is_focused: bool,
) -> 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)]
@ -257,10 +274,11 @@ pub fn breakpoints<'doc>(
};
Box::new(
move |line: usize, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line {
move |line: Option<usize>, _selected: bool, first_visual_line: bool, out: &mut String| {
if !first_visual_line || line.is_none() {
return None;
}
let line = line.expect("line exists");
let breakpoint = breakpoints
.iter()
.find(|breakpoint| breakpoint.line == line)?;

Loading…
Cancel
Save