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:
parent
f4f02d5536
commit
cd4cb8e10b
2 changed files with 14 additions and 19 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Reference in a new issue