Skip to content

feat: add diff gutter to picker preview - #14538

Open
forivall wants to merge 6 commits into
helix-editor:masterfrom
forivall:diff-gutter-preview
Open

feat: add diff gutter to picker preview#14538
forivall wants to merge 6 commits into
helix-editor:masterfrom
forivall:diff-gutter-preview

Conversation

@forivall

@forivall forivall commented Oct 5, 2025

Copy link
Copy Markdown
Contributor

This could probably be improved with some configuration options, if desired.

Screenshot taken from my branch with a few other modifications, notably this hack: forivall@c37b18d4 to select the first change in the git diff picker.

ScreenShot 2025-10-04 at 10 28 54 PM

Comment on lines +977 to +1012
let gutter_style = theme.get("ui.gutter");
let gutter_style_virtual = theme.get("ui.gutter.virtual");

let mut gutter = gutter::diff_style(doc, theme);
// equivalent to helix_view::editor::GutterType::Diff.width(_, doc);
let width = 1;
// avoid lots of small allocations by reusing a text buffer for each line
let mut text = String::with_capacity(width);
let gutter_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
// draw over the margin with width
let x = inner.x - 1;
let y = pos.visual_line;

let gutter_style = match pos.first_visual_line {
true => gutter_style,
false => gutter_style_virtual,
};

if let Some(style) =
gutter(pos.doc_line, false, pos.first_visual_line, &mut text)
{
renderer.set_stringn(x, y, &text, width, gutter_style.patch(style));
} else {
renderer.set_style(
Rect {
x,
y,
width: width as u16,
height: 1,
},
gutter_style,
);
}
text.clear();
};
decorations.add_decoration(gutter_decoration);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adapted from

let mut gutter = gutter_type.style(editor, doc, view, theme, is_focused);
let width = gutter_type.width(view, doc);
// avoid lots of small allocations by reusing a text buffer for each line
let mut text = String::with_capacity(width);
let cursors = cursors.clone();
let gutter_decoration = move |renderer: &mut TextRenderer, pos: LinePos| {
// TODO handle softwrap in gutters
let selected = cursors.contains(&pos.doc_line);
let x = viewport.x + offset;
let y = pos.visual_line;
let gutter_style = match (selected, pos.first_visual_line) {
(false, true) => gutter_style,
(true, true) => gutter_selected_style,
(false, false) => gutter_style_virtual,
(true, false) => gutter_selected_style_virtual,
};
if let Some(style) =
gutter(pos.doc_line, selected, pos.first_visual_line, &mut text)
{
renderer.set_stringn(x, y, &text, width, gutter_style.patch(style));
} else {
renderer.set_style(
Rect {
x,
y,
width: width as u16,
height: 1,
},
gutter_style,
);
}
text.clear();
};
decoration_manager.add_decoration(gutter_decoration);
, could be fine tuned for the preview use case, or deduplicated and shared.

@senekor

senekor commented Oct 10, 2025

Copy link
Copy Markdown
Contributor

I think this does need to be configurable, because the normal diff gutter can already be hidden. It would be weird if a normal buffer doesn't have the diff gutter while the picker has.

Maybe it could read the existing editor.gutters list and if it contains "diff", then it also activates it in the picker. That would make things consistent without introducing a new config option.

@forivall
forivall force-pushed the diff-gutter-preview branch from 52a8871 to de0e899 Compare August 12, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants