refactor: improve chunk acceptance and rejection logic in CodeMirrorDiffUtils

- Simplified the acceptAllChunks and rejectAllChunks functions to handle document changes in a more robust manner.
- Updated logic to merge changes in a single operation, addressing potential RangeErrors with empty originals.
- Enhanced the CodeMirrorDiffView to conditionally apply themes based on the original document's content.
This commit is contained in:
iliya 2026-03-01 17:58:37 +02:00
parent f4f02d5536
commit cd4cb8e10b
2 changed files with 14 additions and 19 deletions

View file

@ -42,15 +42,13 @@ export function acceptAllChunks(view: EditorView): boolean {
if (!result || result.chunks.length === 0) return false;
const orig = getOriginalDoc(view.state);
const specs: ChangeSpec[] = [];
for (const chunk of result.chunks) {
specs.push({
from: chunk.fromA,
to: chunk.toA,
insert: view.state.doc.sliceString(chunk.fromB, chunk.toB),
});
}
const changes = ChangeSet.of(specs, orig.length);
// More robust than per-chunk: merge chunk ranges can be inconsistent for "empty" originals
// (e.g. whitespace-only or reconstruction edge cases), which can throw RangeError.
// Accept-all semantics are simply: make original equal to current modified doc.
const changes = ChangeSet.of(
[{ from: 0, to: orig.length, insert: view.state.doc.toString() }],
orig.length
);
view.dispatch({
effects: updateOriginalDoc.of({ doc: changes.apply(orig), changes }),
});
@ -63,15 +61,11 @@ export function rejectAllChunks(view: EditorView): boolean {
if (!result || result.chunks.length === 0) return false;
const orig = getOriginalDoc(view.state);
const specs: ChangeSpec[] = [];
for (const chunk of result.chunks) {
specs.push({
from: chunk.fromB,
to: chunk.toB,
insert: orig.sliceString(chunk.fromA, chunk.toA),
});
}
view.dispatch({ changes: specs });
// Same robustness principle as acceptAllChunks: reject-all semantics are simply
// "restore the current doc to the original baseline" in one edit.
view.dispatch({
changes: [{ from: 0, to: view.state.doc.length, insert: orig.toString() }],
});
return true;
}

View file

@ -381,10 +381,11 @@ export const CodeMirrorDiffView = ({
);
const buildExtensions = useCallback(() => {
const isEffectivelyEmptyOriginal = original.trim().length === 0;
const extensions: Extension[] = [
baseEditorTheme,
diffSpecificTheme,
...(original.length === 0 ? [emptyOriginalOverrideTheme] : []),
...(isEffectivelyEmptyOriginal ? [emptyOriginalOverrideTheme] : []),
lineNumbers(),
syntaxHighlighting(oneDarkHighlightStyle),
EditorView.editable.of(!readOnly),