Skip to content

feat: add intra line highlights#74

Closed
daulet wants to merge 1 commit intoumputun:masterfrom
daulet:daulet/word_highlight
Closed

feat: add intra line highlights#74
daulet wants to merge 1 commit intoumputun:masterfrom
daulet:daulet/word_highlight

Conversation

@daulet
Copy link
Copy Markdown
Contributor

@daulet daulet commented Apr 8, 2026

When left and right lines are similar enough, highlight what changed.

Before:
image

After:
image

@daulet daulet requested a review from umputun as a code owner April 8, 2026 22:55
Copy link
Copy Markdown
Owner

@umputun umputun left a comment

Choose a reason for hiding this comment

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

thx for the PR. heads up - #73 by @rashpile is also implementing intra-line highlights. some key differences between the two:

  • #73 (+3366/-169, 45 files) has opt-in toggle (W key + --word-diff flag), dedicated theme color keys (WordAddBg/WordRemoveBg), status bar icon, collapsed mode integration, ~94% test coverage, full docs update. uses sergi/go-diff as a new dependency
  • this PR (+374/-10, 6 files) is much smaller footprint, zero new deps (hand-rolled LCS + Levenshtein), cleaner separation in a single file. always-on by design

a few things to address in this approach:

  1. reuses SearchBg for emphasis - when search is active on a highlighted line, intra-line markers and search highlights become indistinguishable. needs separate colors
  2. naive mode threshold 1.0 - when remove/add counts are equal, lines are always paired regardless of similarity. two completely unrelated lines get noisy intra-line highlights
  3. CI failing - exhaustive switch lint error in intraline.go:48, missing ChangeContext/ChangeDivider cases

the small footprint and zero-dependency approach is a real advantage here. the hand-rolled LCS + Levenshtein keeps things self-contained, which I value.

would be great if you and @rashpile could sync up on this - two parallel implementations of the same feature. there might be synergy, e.g. combining the smaller footprint from here with some of the integration work from #73, or joining forces on one PR.

@umputun
Copy link
Copy Markdown
Owner

umputun commented Apr 10, 2026

thx for this. merged a combined version in #87 that takes the core algorithm from this PR:

  • regex tokenizer ([\pL\pN_]+|\s+|[^\pL\pN_\s]+) splitting into word/whitespace/punctuation tokens
  • LCS DP + backtrace for lcsKeptTokens
  • byte-offset based matchRange ranges, reusing the existing infrastructure
  • zero new dependencies

paired with @rashpile's production integration from #73 (pairing heuristic, 30% similarity gate, dedicated theme colors with HSL auto-derivation, collapsed mode refactor).

few changes on top of your implementation:

  • replaced the 0.60 / 1.00 Levenshtein pairing with prefix/suffix scoring (avoids forced pairing on same-count blocks with unrelated content)
  • added a 500-byte cap in changedTokenRanges to prevent O(m*n) LCS memory blowup on minified content
  • dedicated word-diff bg colors instead of reusing SearchBg (search + word-diff can now coexist without visual collision)

the final version is always-on matching your design. closing this one as its core algorithm shipped in #87.

@umputun umputun closed this Apr 10, 2026
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.

2 participants