Draw the diff selection as a narrow bar rather than across the line

Now that a diff view always carries a selection, the highlight fights the
diff itself for the line's colours. Painting the selection across the whole
line takes over the background, and a selected hunk becomes one solid block
with no boundary between what was removed and what replaced it — the more
lines you select, the less you can read.

This isn't specific to renderers like delta that say which side of the diff
a line is on by colouring its background, though they suffer most: git's own
output puts red and green text on that background, which reads badly too.
Since there is no rendering of a diff that a full-width highlight doesn't
degrade, there is nothing here worth configuring — the bar is simply what
diff views use.

Left edge only, and two columns wide: every convention for marking a row of
coloured content — change bars, diff gutters, selection gutters — puts the
marker on the left, and bracketing both edges reads as framing instead.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-10-01 17:07:52 +02:00
co-authored by Claude Opus 5
parent cfde175e8a
commit 8c51a920b2
2 changed files with 17 additions and 1 deletions
+8 -1
View File
@@ -164,6 +164,12 @@ type View struct {
// instead of Sel{Bg,Fg}Colors for highlighting selected lines.
HighlightInactive bool
// If SelectedLineColorWidth is greater than zero, a highlighted line is painted
// in the selection colors on that many columns at its left edge only, rather
// than across its whole width, leaving the line's own colors to show through.
// For content that conveys meaning by color of its own.
SelectedLineColorWidth int
// If Frame is true, a border will be drawn around the view.
Frame bool
@@ -869,7 +875,8 @@ func (v *View) setCharacter(x, y int, ch string, fgColor, bgColor Attribute, isW
rangeSelectEnd = max(relativeRangeSelectStart, v.cy)
}
if y >= rangeSelectStart && y <= rangeSelectEnd {
colorWidth := v.SelectedLineColorWidth
if y >= rangeSelectStart && y <= rangeSelectEnd && (colorWidth == 0 || x < colorWidth) {
fgColor = applySelTextColor(fgColor, v.SelTextColor)
if v.HighlightInactive || !isWindowFocused {
bgColor = (bgColor & AttrStyleBits) | v.InactiveViewSelBgColor
+9
View File
@@ -168,6 +168,15 @@ func (gui *Gui) createAllViews() error {
gui.Views.Snake.FgColor = gocui.ColorGreen
// The main views show diffs, whose own colors say what each line is: which side of
// the diff it's on, and often its syntax highlighting too. A selection painted
// across the whole line takes those colors over, which for a whole selected hunk
// leaves one unreadable block; so mark the selection with a narrow bar at the left
// edge instead, and leave the rest of the line to the diff. Two columns, enough to
// read as a marker rather than as an artefact.
gui.Views.Main.SelectedLineColorWidth = 2
gui.Views.Secondary.SelectedLineColorWidth = 2
return nil
}