Conversation
Not sure if we should allow this to be configurable, but the word-based diffing will probably be a better user experience in general and we'll probably want to utilize `jsdiff` for other things in the future... Also swapped over to use more of a word based diffing algo
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| _wrapper: HTMLPreElement, | ||
| _decorations?: DiffDecorationItem[] | ||
| ) { | ||
| async render(_diff: FileMetadata, _wrapper: HTMLPreElement) { |
There was a problem hiding this comment.
The changes within the render function` here are mostly just to remove the decorations API
| codeUnified, | ||
| }: RenderHunkProps) { | ||
| if (hunk.hunkContent == null) return; | ||
| const { additions, deletions, unified } = this.processLines(hunk); |
There was a problem hiding this comment.
I kinda refactored the layout of renderHunks to some sub-functions, but the core logic of rendering into the code elements is largely unchanged.
| if (deletionLine.length > 1000 || additionLine.length > 1000) { | ||
| continue; | ||
| } | ||
| const lineDiff = diffWordsWithSpace(deletionLine, additionLine); |
There was a problem hiding this comment.
This is where most of the magic happens -- diffGroups is essentially a data structure where we figure out arrays of additions and deletions without the context lines and figure out the line index relative to each group that can then be passed through to the decorations API
| start: { line, character: spanStart }, | ||
| end: { line, character: spanStart + spanLength }, | ||
| properties: { 'data-diff-span': '' }, | ||
| alwaysWrap: true, |
There was a problem hiding this comment.
This property is important to make sure we never highlight the whole line and instead JUST the text even if all the content of the line changed (the decorations need to feel like specific text wrappers, not full line wrappers
| patch: 'diff', | ||
| }; | ||
|
|
||
| export const DIFF_DECORATIONS: Record<string, DiffDecorationItem[]> = { |
There was a problem hiding this comment.
This API is now kill... we can't really support it and highlighting diffs at the same time... which I think is ok in practice
|
alas, the review never came |
Large-tree render hot-path optimizations Reduce first visible-row readiness for large virtualized trees by removing redundant tree-building/traversal work and tightening hot path data structures. Experiments: #2, #3, #6, #7, #9, #10, #12, #13, #14, #19, #20, #21, #22 Metric: visible_rows_ready_median_ms 826.7ms -> 409.9ms (-50.4%)
Reduce whole-tree startup work across the path-store tree controller and store setup. This combines the kept changes that removed duplicate controller metadata passes, made projection data lazy/partial, deferred child lookup maps, optimized initial expansion handling, and added file-only builder fast paths for the profile workload. Experiments: #2, #3, #4, #5, #7, #8, #9, #10, #11, #12, #13, #14, #21, #23, #28, #29 Metric: visible_rows_ready_ms 1002.3 → 197.5 (-80.3%)
Overhaul path-store startup hot path Reduce whole-tree startup work across the path-store tree controller and store setup. This combines the kept changes that removed duplicate controller metadata passes, made projection data lazy/partial, deferred child lookup maps, optimized initial expansion handling, and added file-only builder fast paths for the profile workload. Experiments: #2, #3, #4, #5, #7, #8, #9, #10, #11, #12, #13, #14, #21, #23, #28, #29 Metric: visible_rows_ready_ms 1002.3 → 197.5 (-80.3%)
This PR adds shiki decorations on deletion/addition lines to highlight specific word-based changes:
Because of the way I do this, I've decided to disable the custom shiki decoration API because technically it won't be compatible given that shiki doesn't allow overlapping decorations.
Anyways, at a high level this PR adds
jsdiffas a dependency and when we iterate over to render we figure out the word-based spans to add highlights for specific changes within a line. I initially usedfast-diffto do this but it only could diff based on characters which I found a bit more annoying in practice. I think word based is much easier.I also applied some additional logic to look for cases where there would be single white-space characters between spans and use that to join the spans together to avoid a sort of gap-tooth'd aesthetic.
I think we still need to iterate on what the spans look like and what colors they should adopt, but this is definitely a good foundation for us to build on.