Skip to content

Fix coloring of wrapped delta lines - #5711

Merged
stefanhaller merged 7 commits into
masterfrom
fix-coloring-of-wrapped-delta-lines
Jun 18, 2026
Merged

Fix coloring of wrapped delta lines#5711
stefanhaller merged 7 commits into
masterfrom
fix-coloring-of-wrapped-delta-lines

Conversation

@stefanhaller

Copy link
Copy Markdown
Collaborator

When using delta as a custom pager, and the view is so narrow that delta needs to wrap long lines, only the last segment of such a wrapped line would have its background color extended to the right edge of the view, resulting in a block of lines with a frayed right edge, like this:

Screenshot 2026-06-18 at 17 25 36

Fix this by extending the wrapped line's background colors to the right edge as well, making it look like this:

Screenshot 2026-06-18 at 17 25 23

stefanhaller and others added 7 commits June 18, 2026 17:21
The next few commits restructure how the view's draw() decides the
fg/bg of cells past the end of a line's content. Pin down three
existing behaviors first so the restructuring stays a refactor:

- '\n' should reset attributes for the trailing area so a reversed
  final cell doesn't bleed into empty space.
- An unterminated line with AttrReverse on its last cell should
  propagate that to the right edge (otherwise the rendered bg
  abruptly stops at the last character).
- '\x1b[K' on a line that fits within InnerWidth should fill the
  remaining cells with the current bg color.

Introduce a small WithSimulationScreen helper that swaps in a tcell
mock terminal so tests can call view.draw() and inspect rendered
cells via Screen.Get().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tools like delta emit each diff line with the bg color set, then
\x1b[K to fill the rest of the row with that bg color. When the
content fits within the view's inner width, gocui's \x1b[K handling
appends explicit padding cells and rendering works. When the content
exceeds the inner width, \x1b[K adds no cells (negative repeat
count), the line is wrapped into multiple segments, and the partial
tail segment's trailing cells fall back to the view default bg
instead of continuing the fill color.

Add a test that drives draw() against a tcell mock terminal and
asserts the current (buggy) trailing background.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The four ReplaceAll(str, "\x00", "") calls (and the equivalent
rune-by-rune skip in linesToString) are leftover from when cell.chr
was a rune and \x00 was used as an internal sentinel. With chr now
being a string and no code path writing \x00, the filtering never
strips anything.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This is to free up the name lineType for something else in the next commit.
The cells of a source line will soon need to carry metadata about how
the line was terminated (newline vs filled to edge via \x1b[K). Move
to a struct so there's somewhere to put it; this commit only renames
[][]cell to []line{cells: ...} with no behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The sentinel was appended to every \n-terminated line solely so that
draw()'s prevFgColor tracking would reset to default for the trailing
area; without it, an AttrReverse-styled last cell would carry its
rendered bg past the end of the line.

The same prevFgColor mechanism propagated AttrReverse past content on
*unterminated* lines too — which doesn't match real terminal behavior
(try `print '\x1b[7m\x1b[31mfoo'` in a shell: the reverse stops at
the last character) and isn't relied on by anything in lazygit, since
all our writers terminate lines with \n.

Drop the sentinel cell, drop prevFgColor, and just have draw() paint
trailing cells with the view's default fg/bg. The
TestUnterminatedReverseLineExtendsToEdge regression test inverts to
document the new (terminal-matching) behavior, renamed accordingly.
TestWriteString expectations also drop the trailing "" that came
from the sentinel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tools like delta paint each diff line's background with '\x1b[K' so
the color reaches the right edge. Up to now the '\x1b[K' handler
appended (InnerWidth - cx) explicit padding cells with the fill bg
so rendering picked up the color. That worked for short lines but
silently degraded once content exceeded InnerWidth: the repeat
count went non-positive, no cells were added, and after wrapping
the partial tail segment was left without any cells carrying the
fill color, so draw() fell back to the view's default bg.

Record the fill colors on the source line as optional
trailingFillAttributes. In the '\x1b[K' handler set them (and drop
the padding-cell loop — the metadata covers both the wrap and the
non-wrap cases). In draw(), once per source line, pick the trailing
cell's fg/bg from the metadata if present and otherwise from the
view defaults; then the inner-loop fills past-content cells with
that.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@stefanhaller stefanhaller added the bug Something isn't working label Jun 18, 2026
@stefanhaller
stefanhaller enabled auto-merge June 18, 2026 15:29
@stefanhaller
stefanhaller merged commit c81c653 into master Jun 18, 2026
14 checks passed
@stefanhaller
stefanhaller deleted the fix-coloring-of-wrapped-delta-lines branch June 18, 2026 15:32
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Jul 9, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [jesseduffield/lazygit](https://github.com/jesseduffield/lazygit) | minor | `v0.62.2` → `v0.63.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>jesseduffield/lazygit (jesseduffield/lazygit)</summary>

### [`v0.63.0`](https://github.com/jesseduffield/lazygit/releases/tag/v0.63.0)

[Compare Source](jesseduffield/lazygit@v0.62.2...v0.63.0)

<!-- Release notes generated using configuration in .github/release.yml at v0.63.0 -->

#### What's Changed

##### Enhancements 🔥

- Add direnv support by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5660](jesseduffield/lazygit#5660)
- Improve cycling through multiple pagers by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5678](jesseduffield/lazygit#5678)
- Detect external repo changes via background polling by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5662](jesseduffield/lazygit#5662)
- Make the side panels configurable by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5702](jesseduffield/lazygit#5702)
- Add a global keybinding for editing the config file by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5728](jesseduffield/lazygit#5728)
- Improve resolving non-textual and submodule merge conflicts by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5735](jesseduffield/lazygit#5735)
- Auto-dismiss the continue-rebase prompt when it becomes stale by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5758](jesseduffield/lazygit#5758)
- Support custom pagers and passphrase prompts on Windows by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5740](jesseduffield/lazygit#5740)
- Make creating worktrees simpler and less error-prone by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5741](jesseduffield/lazygit#5741)
- Improve deleting worktrees and their branches by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5748](jesseduffield/lazygit#5748)
- Allow overriding the platform used for default keybindings by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5671](jesseduffield/lazygit#5671)
- Add `gui.shrinkSidePanelsToContent` option by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5754](jesseduffield/lazygit#5754)
- Show renamed files in the custom patch builder by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5759](jesseduffield/lazygit#5759)

##### Fixes 🔧

- Fix unstaging a submodule with dirty content by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5666](jesseduffield/lazygit#5666)
- Fix coloring of wrapped delta lines by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5711](jesseduffield/lazygit#5711)
- Fix Files Panel artefacts during rebase commands by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5661](jesseduffield/lazygit#5661)
- Keep selected commits stable across refreshes by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5717](jesseduffield/lazygit#5717)
- Fix quoting of shell commands on Windows by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5704](jesseduffield/lazygit#5704)
- Silently consume unrecognized or malformed escape sequences by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5738](jesseduffield/lazygit#5738)
- Don't include common ancestor when picking "both" for a conflict in diff3 style by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5747](jesseduffield/lazygit#5747)

##### Maintenance ⚙️

- Some fixes to our infrastructure by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5705](jesseduffield/lazygit#5705)
- Restructure the `just` recipes for running integration tests by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5720](jesseduffield/lazygit#5720)
- Fix flaky TestNewCmdTaskInstantStop test by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5743](jesseduffield/lazygit#5743)
- Bump golang.org/x/sync from 0.20.0 to 0.21.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5684](jesseduffield/lazygit#5684)
- Bump golang.org/x/sys from 0.45.0 to 0.46.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5685](jesseduffield/lazygit#5685)
- Bump github.com/sahilm/fuzzy from 0.1.2 to 0.1.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5706](jesseduffield/lazygit#5706)
- Bump actions/cache from 5 to 6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5722](jesseduffield/lazygit#5722)
- Bump actions/checkout from 6 to 7 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5723](jesseduffield/lazygit#5723)
- Bump goreleaser/goreleaser-action from 7.2.2 to 7.2.3 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5745](jesseduffield/lazygit#5745)
- Bump golangci/golangci-lint-action from 9.2.0 to 9.3.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5746](jesseduffield/lazygit#5746)
- Bump golang.org/x/net from 0.47.0 to 0.55.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;5752](jesseduffield/lazygit#5752)
- Pin gofumpt version to 0.9.2 by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5753](jesseduffield/lazygit#5753)
- Fix a few flaky tests by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5756](jesseduffield/lazygit#5756)

##### I18n 🌎

- Update translations from Crowdin by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5760](jesseduffield/lazygit#5760)

##### Performance Improvements 📊

- Prevent staging from becoming slower over time by [@&#8203;stefanhaller](https://github.com/stefanhaller) in [#&#8203;5712](jesseduffield/lazygit#5712)

**Full Changelog**: <jesseduffield/lazygit@v0.62.2...v0.63.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTYuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI1Ni4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant