@singapore-editor/diff 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +158 -0
  2. package/dist/diffGutter.d.ts +37 -0
  3. package/dist/diffGutter.d.ts.map +1 -0
  4. package/dist/diffGutter.js +189 -0
  5. package/dist/diffGutter.js.map +1 -0
  6. package/dist/diffRows.d.ts +5 -0
  7. package/dist/diffRows.d.ts.map +1 -0
  8. package/dist/diffRows.js +40 -0
  9. package/dist/diffRows.js.map +1 -0
  10. package/dist/diffSyntax.d.ts +124 -0
  11. package/dist/diffSyntax.d.ts.map +1 -0
  12. package/dist/diffSyntax.js +491 -0
  13. package/dist/diffSyntax.js.map +1 -0
  14. package/dist/editorDiffPlugin.d.ts +74 -0
  15. package/dist/editorDiffPlugin.d.ts.map +1 -0
  16. package/dist/editorDiffPlugin.js +546 -0
  17. package/dist/editorDiffPlugin.js.map +1 -0
  18. package/dist/editorOptions.d.ts +15 -0
  19. package/dist/editorOptions.d.ts.map +1 -0
  20. package/dist/editorOptions.js +33 -0
  21. package/dist/editorOptions.js.map +1 -0
  22. package/dist/gutters.d.ts +53 -0
  23. package/dist/gutters.d.ts.map +1 -0
  24. package/dist/gutters.js +122 -0
  25. package/dist/gutters.js.map +1 -0
  26. package/dist/index.d.ts +18 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +11 -0
  29. package/dist/inline.d.ts +3 -0
  30. package/dist/inline.d.ts.map +1 -0
  31. package/dist/inline.js +72 -0
  32. package/dist/inline.js.map +1 -0
  33. package/dist/lines.d.ts +8 -0
  34. package/dist/lines.d.ts.map +1 -0
  35. package/dist/lines.js +49 -0
  36. package/dist/lines.js.map +1 -0
  37. package/dist/liveProjection.d.ts +11 -0
  38. package/dist/liveProjection.d.ts.map +1 -0
  39. package/dist/liveProjection.js +152 -0
  40. package/dist/liveProjection.js.map +1 -0
  41. package/dist/model.d.ts +4 -0
  42. package/dist/model.d.ts.map +1 -0
  43. package/dist/model.js +247 -0
  44. package/dist/model.js.map +1 -0
  45. package/dist/projection.d.ts +18 -0
  46. package/dist/projection.d.ts.map +1 -0
  47. package/dist/projection.js +281 -0
  48. package/dist/projection.js.map +1 -0
  49. package/dist/regions.d.ts +28 -0
  50. package/dist/regions.d.ts.map +1 -0
  51. package/dist/regions.js +0 -0
  52. package/dist/regions.js.map +1 -0
  53. package/dist/style.css +145 -0
  54. package/dist/theme.d.ts +2 -0
  55. package/dist/theme.d.ts.map +1 -0
  56. package/dist/theme.js +43 -0
  57. package/dist/theme.js.map +1 -0
  58. package/dist/types.d.ts +78 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/package.json +44 -0
@@ -0,0 +1,33 @@
1
+ import { editorKeymapLayersForCommandPacks } from "@singapore-editor/core/keymap";
2
+ //#region src/editorOptions.ts
3
+ var DIFF_COMMAND_PACKS = [
4
+ "navigation",
5
+ "selection",
6
+ "find"
7
+ ];
8
+ var diffKeymap;
9
+ /**
10
+ * The options an editor holding a `mode: 'document'` diff needs; an overlay diff keeps its host's
11
+ * editable options. Spread them and add the host's own, such as plugins, typography and theme.
12
+ */
13
+ function createDiffEditorOptions() {
14
+ return {
15
+ cursorLineHighlight: {
16
+ gutterBackground: false,
17
+ gutterNumber: false,
18
+ rowBackground: false
19
+ },
20
+ detectIndentation: false,
21
+ documentMode: "static",
22
+ editability: "readonly",
23
+ folding: false,
24
+ keymap: diffKeymap ??= Object.freeze({
25
+ defaultBindings: false,
26
+ layers: editorKeymapLayersForCommandPacks(DIFF_COMMAND_PACKS)
27
+ })
28
+ };
29
+ }
30
+ //#endregion
31
+ export { createDiffEditorOptions };
32
+
33
+ //# sourceMappingURL=editorOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editorOptions.js","names":[],"sources":["../src/editorOptions.ts"],"sourcesContent":["import type { EditorOptions } from '@singapore-editor/core/editor'\nimport {\n editorKeymapLayersForCommandPacks,\n type EditorCommandPack,\n type EditorKeymapOptions,\n} from '@singapore-editor/core/keymap'\nimport type { EditorCursorLineHighlightOptions } from '@singapore-editor/core/rendering'\n\n// Every nested field is present, so a host extends `keymap.layers` or one highlight part in place.\nexport type DiffEditorOptions = Required<\n Pick<EditorOptions, 'detectIndentation' | 'documentMode' | 'editability' | 'folding'>\n> & {\n readonly cursorLineHighlight: Required<EditorCursorLineHighlightOptions>\n readonly keymap: DiffKeymap\n}\n\ntype DiffKeymap = Readonly<Required<Pick<EditorKeymapOptions, 'defaultBindings' | 'layers'>>>\n\n// Read-only already refuses every editing key, and `folding: false` leaves fold keys nothing to do.\nconst DIFF_COMMAND_PACKS = [\n 'navigation',\n 'selection',\n 'find',\n] as const satisfies readonly EditorCommandPack[]\n\n// One object for every call: a React host compares `keymap` by identity and re-applies a new one.\nlet diffKeymap: DiffKeymap | undefined\n\n/**\n * The options an editor holding a `mode: 'document'` diff needs; an overlay diff keeps its host's\n * editable options. Spread them and add the host's own, such as plugins, typography and theme.\n */\nexport function createDiffEditorOptions(): DiffEditorOptions {\n return {\n cursorLineHighlight: { gutterBackground: false, gutterNumber: false, rowBackground: false },\n // The buffer interleaves both sides, so a guess would change the width per file and per toggle.\n detectIndentation: false,\n documentMode: 'static',\n editability: 'readonly',\n // A fold would hide a deletion and its addition, and misalign a split.\n folding: false,\n keymap: (diffKeymap ??= Object.freeze({\n defaultBindings: false,\n layers: editorKeymapLayersForCommandPacks(DIFF_COMMAND_PACKS),\n })),\n }\n}\n"],"mappings":";;AAmBA,IAAM,qBAAqB;CACzB;CACA;CACA;AACF;AAGA,IAAI;;;;;AAMJ,SAAgB,0BAA6C;CAC3D,OAAO;EACL,qBAAqB;GAAE,kBAAkB;GAAO,cAAc;GAAO,eAAe;EAAM;EAE1F,mBAAmB;EACnB,cAAc;EACd,aAAa;EAEb,SAAS;EACT,QAAS,eAAe,OAAO,OAAO;GACpC,iBAAiB;GACjB,QAAQ,kCAAkC,kBAAkB;EAC9D,CAAC;CACH;AACF"}
@@ -0,0 +1,53 @@
1
+ import type { DiffRenderRow } from './types';
2
+ export type DiffGutterSide = 'old' | 'new' | 'stacked';
3
+ export type DiffGutterNumberSide = Exclude<DiffGutterSide, 'stacked'>;
4
+ export type DiffGutterLaneKind = DiffGutterNumberSide | 'indicator';
5
+ /**
6
+ * What a lane is coloured *as*, rather than what colour it ends up. The DOM gutter resolves the
7
+ * colour in CSS so a theme can override it; keeping the branching here means the rule that an
8
+ * addition tints the new lane and not the old one lives in exactly one place.
9
+ */
10
+ export type DiffGutterLaneTone = 'added' | 'deleted' | 'hunk' | 'default';
11
+ type DiffGutterLaneLayout = {
12
+ readonly kind: DiffGutterLaneKind;
13
+ readonly left: number;
14
+ readonly width: number;
15
+ };
16
+ export type DiffGutterLayout = {
17
+ readonly lanes: readonly DiffGutterLaneLayout[];
18
+ readonly width: number;
19
+ };
20
+ /**
21
+ * The widest line number each lane has to fit, in digits.
22
+ *
23
+ * Computed once when a projection is built rather than inside `width()`. The gutter's width is
24
+ * invalidated far more often than the rows change, and the scan is over *every* projected row —
25
+ * which in overlay mode means every line of the file, since `createLiveDiffProjection` materializes
26
+ * a row per unchanged line. A 50,000-line file was re-scanning 50,000 rows and allocating a string
27
+ * per row, twice in stacked mode, on every gutter-width recompute.
28
+ */
29
+ export type DiffGutterDigits = {
30
+ readonly old: number;
31
+ readonly new: number;
32
+ };
33
+ export declare function diffGutterDigits(rows: readonly DiffRenderRow[]): DiffGutterDigits;
34
+ export declare function diffGutterWidth(side: DiffGutterSide, digits: DiffGutterDigits, lineCount: number, characterWidth: number): number;
35
+ export declare function diffGutterLayout(side: DiffGutterSide, digits: DiffGutterDigits, lineCount: number, characterWidth: number): DiffGutterLayout;
36
+ export declare function diffGutterNumberText(row: DiffRenderRow, side: DiffGutterNumberSide): string;
37
+ export declare function diffGutterIndicatorText(row: DiffRenderRow): string;
38
+ /**
39
+ * Side-awareness in this gutter is **per lane, not per pane** (plan §3.3). In stacked mode one
40
+ * gutter carries both number lanes, and for a single addition row the old lane stays foreground
41
+ * while the new lane goes green — so a row-level class cannot express it and each lane carries its
42
+ * own tone.
43
+ *
44
+ * The indicator lane is deliberately side-agnostic: it shows `+`/`-` for the row as a whole.
45
+ */
46
+ export declare function diffGutterLaneTone(row: DiffRenderRow, kind: DiffGutterLaneKind): DiffGutterLaneTone;
47
+ /**
48
+ * Whether the gutter band behind a row is tinted. Unlike the lane tone this *is* per pane: a split
49
+ * old pane shows no tint behind an addition, because that row is a placeholder there.
50
+ */
51
+ export declare function diffGutterRowTone(row: DiffRenderRow, side: DiffGutterSide): DiffGutterLaneTone;
52
+ export {};
53
+ //# sourceMappingURL=gutters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gutters.d.ts","sourceRoot":"","sources":["../src/gutters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;AACtD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;AACrE,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,WAAW,CAAA;AAEnE;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;AAEzE,KAAK,oBAAoB,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAA;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB,CAAA;AAQD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,GAAG,gBAAgB,CAUjF;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,gBAAgB,EACxB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,gBAAgB,CAwBlB;AAuBD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAE3F;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAKlE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,kBAAkB,GACvB,kBAAkB,CAWpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,GAAG,kBAAkB,CAK9F"}
@@ -0,0 +1,122 @@
1
+ //#region src/gutters.ts
2
+ var MIN_LINE_NUMBER_DIGITS = 3;
3
+ var GUTTER_NUMBER_RESERVED_WIDTH = 8;
4
+ var GUTTER_INDICATOR_WIDTH = 12;
5
+ function diffGutterDigits(rows) {
6
+ let oldDigits = 0;
7
+ let newDigits = 0;
8
+ for (const row of rows) {
9
+ if (row.type === "hunk" || row.type === "empty") continue;
10
+ oldDigits = Math.max(oldDigits, digitCount(row.oldLineNumber));
11
+ newDigits = Math.max(newDigits, digitCount(row.newLineNumber));
12
+ }
13
+ return {
14
+ old: oldDigits,
15
+ new: newDigits
16
+ };
17
+ }
18
+ function diffGutterLayout(side, digits, lineCount, characterWidth) {
19
+ if (side !== "stacked") {
20
+ const numberWidth = gutterNumberLaneWidth(side, digits, lineCount, characterWidth);
21
+ const width = numberWidth + GUTTER_INDICATOR_WIDTH;
22
+ return {
23
+ lanes: [{
24
+ kind: side,
25
+ left: 0,
26
+ width: numberWidth
27
+ }, {
28
+ kind: "indicator",
29
+ left: numberWidth,
30
+ width: GUTTER_INDICATOR_WIDTH
31
+ }],
32
+ width
33
+ };
34
+ }
35
+ const oldWidth = gutterNumberLaneWidth("old", digits, lineCount, characterWidth);
36
+ const newWidth = gutterNumberLaneWidth("new", digits, lineCount, characterWidth);
37
+ const indicatorLeft = oldWidth + newWidth;
38
+ return {
39
+ lanes: [
40
+ {
41
+ kind: "old",
42
+ left: 0,
43
+ width: oldWidth
44
+ },
45
+ {
46
+ kind: "new",
47
+ left: oldWidth,
48
+ width: newWidth
49
+ },
50
+ {
51
+ kind: "indicator",
52
+ left: indicatorLeft,
53
+ width: GUTTER_INDICATOR_WIDTH
54
+ }
55
+ ],
56
+ width: indicatorLeft + GUTTER_INDICATOR_WIDTH
57
+ };
58
+ }
59
+ function diffGutterWidthCharacters(side, digits, lineCount) {
60
+ if (side === "stacked") return diffGutterWidthCharacters("old", digits, lineCount) + diffGutterWidthCharacters("new", digits, lineCount);
61
+ const maxCharacters = Math.max(String(Math.max(1, lineCount)).length, digits[side]);
62
+ return Math.max(MIN_LINE_NUMBER_DIGITS, maxCharacters);
63
+ }
64
+ function digitCount(value) {
65
+ if (value === void 0) return 0;
66
+ return String(value).length;
67
+ }
68
+ function diffGutterNumberText(row, side) {
69
+ return lineNumberForRow(row, side);
70
+ }
71
+ function diffGutterIndicatorText(row) {
72
+ if (row.type === "addition") return "+";
73
+ if (row.type === "deletion") return "-";
74
+ if (row.type === "hunk" && row.expandable) return row.expanded ? "−" : "+";
75
+ return "";
76
+ }
77
+ /**
78
+ * Side-awareness in this gutter is **per lane, not per pane** (plan §3.3). In stacked mode one
79
+ * gutter carries both number lanes, and for a single addition row the old lane stays foreground
80
+ * while the new lane goes green — so a row-level class cannot express it and each lane carries its
81
+ * own tone.
82
+ *
83
+ * The indicator lane is deliberately side-agnostic: it shows `+`/`-` for the row as a whole.
84
+ */
85
+ function diffGutterLaneTone(row, kind) {
86
+ if (row.type === "hunk") return "hunk";
87
+ if (kind === "indicator") {
88
+ if (row.type === "addition") return "added";
89
+ if (row.type === "deletion") return "deleted";
90
+ return "default";
91
+ }
92
+ if (row.type === "addition" && kind !== "old") return "added";
93
+ if (row.type === "deletion" && kind !== "new") return "deleted";
94
+ return "default";
95
+ }
96
+ /**
97
+ * Whether the gutter band behind a row is tinted. Unlike the lane tone this *is* per pane: a split
98
+ * old pane shows no tint behind an addition, because that row is a placeholder there.
99
+ */
100
+ function diffGutterRowTone(row, side) {
101
+ if (row.type === "addition" && side !== "old") return "added";
102
+ if (row.type === "deletion" && side !== "new") return "deleted";
103
+ if (row.type === "hunk") return "hunk";
104
+ return "default";
105
+ }
106
+ function gutterNumberLaneWidth(side, digits, lineCount, characterWidth) {
107
+ const characters = diffGutterWidthCharacters(side, digits, lineCount);
108
+ return Math.ceil(characters * characterWidth + GUTTER_NUMBER_RESERVED_WIDTH);
109
+ }
110
+ function lineNumberForRow(row, side) {
111
+ if (row.type === "hunk" || row.type === "empty") return "";
112
+ if (side === "old") return formatLineNumber(row.oldLineNumber);
113
+ return formatLineNumber(row.newLineNumber);
114
+ }
115
+ function formatLineNumber(value) {
116
+ if (value === void 0) return "";
117
+ return String(value);
118
+ }
119
+ //#endregion
120
+ export { diffGutterDigits, diffGutterIndicatorText, diffGutterLaneTone, diffGutterLayout, diffGutterNumberText, diffGutterRowTone };
121
+
122
+ //# sourceMappingURL=gutters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gutters.js","names":[],"sources":["../src/gutters.ts"],"sourcesContent":["import type { DiffRenderRow } from './types'\n\nexport type DiffGutterSide = 'old' | 'new' | 'stacked'\nexport type DiffGutterNumberSide = Exclude<DiffGutterSide, 'stacked'>\nexport type DiffGutterLaneKind = DiffGutterNumberSide | 'indicator'\n\n/**\n * What a lane is coloured *as*, rather than what colour it ends up. The DOM gutter resolves the\n * colour in CSS so a theme can override it; keeping the branching here means the rule that an\n * addition tints the new lane and not the old one lives in exactly one place.\n */\nexport type DiffGutterLaneTone = 'added' | 'deleted' | 'hunk' | 'default'\n\ntype DiffGutterLaneLayout = {\n readonly kind: DiffGutterLaneKind\n readonly left: number\n readonly width: number\n}\n\nexport type DiffGutterLayout = {\n readonly lanes: readonly DiffGutterLaneLayout[]\n readonly width: number\n}\n\n/* Both match the plain line gutter (`DEFAULT_LINE_GUTTER_MIN_COLUMNS`, `LINE_GUTTER_PADDING_PX`),\n so a diff number sits at the same inset from the pane edge as an editor number. */\nconst MIN_LINE_NUMBER_DIGITS = 3\nconst GUTTER_NUMBER_RESERVED_WIDTH = 8\nconst GUTTER_INDICATOR_WIDTH = 12\n\n/**\n * The widest line number each lane has to fit, in digits.\n *\n * Computed once when a projection is built rather than inside `width()`. The gutter's width is\n * invalidated far more often than the rows change, and the scan is over *every* projected row —\n * which in overlay mode means every line of the file, since `createLiveDiffProjection` materializes\n * a row per unchanged line. A 50,000-line file was re-scanning 50,000 rows and allocating a string\n * per row, twice in stacked mode, on every gutter-width recompute.\n */\nexport type DiffGutterDigits = {\n readonly old: number\n readonly new: number\n}\n\nexport function diffGutterDigits(rows: readonly DiffRenderRow[]): DiffGutterDigits {\n let oldDigits = 0\n let newDigits = 0\n for (const row of rows) {\n if (row.type === 'hunk' || row.type === 'empty') continue\n oldDigits = Math.max(oldDigits, digitCount(row.oldLineNumber))\n newDigits = Math.max(newDigits, digitCount(row.newLineNumber))\n }\n\n return { old: oldDigits, new: newDigits }\n}\n\nexport function diffGutterWidth(\n side: DiffGutterSide,\n digits: DiffGutterDigits,\n lineCount: number,\n characterWidth: number,\n): number {\n return diffGutterLayout(side, digits, lineCount, characterWidth).width\n}\n\nexport function diffGutterLayout(\n side: DiffGutterSide,\n digits: DiffGutterDigits,\n lineCount: number,\n characterWidth: number,\n): DiffGutterLayout {\n if (side !== 'stacked') {\n const numberWidth = gutterNumberLaneWidth(side, digits, lineCount, characterWidth)\n const width = numberWidth + GUTTER_INDICATOR_WIDTH\n return {\n lanes: [\n { kind: side, left: 0, width: numberWidth },\n { kind: 'indicator', left: numberWidth, width: GUTTER_INDICATOR_WIDTH },\n ],\n width,\n }\n }\n\n const oldWidth = gutterNumberLaneWidth('old', digits, lineCount, characterWidth)\n const newWidth = gutterNumberLaneWidth('new', digits, lineCount, characterWidth)\n const indicatorLeft = oldWidth + newWidth\n return {\n lanes: [\n { kind: 'old', left: 0, width: oldWidth },\n { kind: 'new', left: oldWidth, width: newWidth },\n { kind: 'indicator', left: indicatorLeft, width: GUTTER_INDICATOR_WIDTH },\n ],\n width: indicatorLeft + GUTTER_INDICATOR_WIDTH,\n }\n}\n\nfunction diffGutterWidthCharacters(\n side: DiffGutterSide,\n digits: DiffGutterDigits,\n lineCount: number,\n): number {\n if (side === 'stacked') {\n return (\n diffGutterWidthCharacters('old', digits, lineCount) +\n diffGutterWidthCharacters('new', digits, lineCount)\n )\n }\n\n const maxCharacters = Math.max(String(Math.max(1, lineCount)).length, digits[side])\n return Math.max(MIN_LINE_NUMBER_DIGITS, maxCharacters)\n}\n\nfunction digitCount(value: number | undefined): number {\n if (value === undefined) return 0\n return String(value).length\n}\n\nexport function diffGutterNumberText(row: DiffRenderRow, side: DiffGutterNumberSide): string {\n return lineNumberForRow(row, side)\n}\n\nexport function diffGutterIndicatorText(row: DiffRenderRow): string {\n if (row.type === 'addition') return '+'\n if (row.type === 'deletion') return '-'\n if (row.type === 'hunk' && row.expandable) return row.expanded ? '−' : '+'\n return ''\n}\n\n/**\n * Side-awareness in this gutter is **per lane, not per pane** (plan §3.3). In stacked mode one\n * gutter carries both number lanes, and for a single addition row the old lane stays foreground\n * while the new lane goes green — so a row-level class cannot express it and each lane carries its\n * own tone.\n *\n * The indicator lane is deliberately side-agnostic: it shows `+`/`-` for the row as a whole.\n */\nexport function diffGutterLaneTone(\n row: DiffRenderRow,\n kind: DiffGutterLaneKind,\n): DiffGutterLaneTone {\n if (row.type === 'hunk') return 'hunk'\n if (kind === 'indicator') {\n if (row.type === 'addition') return 'added'\n if (row.type === 'deletion') return 'deleted'\n return 'default'\n }\n\n if (row.type === 'addition' && kind !== 'old') return 'added'\n if (row.type === 'deletion' && kind !== 'new') return 'deleted'\n return 'default'\n}\n\n/**\n * Whether the gutter band behind a row is tinted. Unlike the lane tone this *is* per pane: a split\n * old pane shows no tint behind an addition, because that row is a placeholder there.\n */\nexport function diffGutterRowTone(row: DiffRenderRow, side: DiffGutterSide): DiffGutterLaneTone {\n if (row.type === 'addition' && side !== 'old') return 'added'\n if (row.type === 'deletion' && side !== 'new') return 'deleted'\n if (row.type === 'hunk') return 'hunk'\n return 'default'\n}\n\nfunction gutterNumberLaneWidth(\n side: DiffGutterNumberSide,\n digits: DiffGutterDigits,\n lineCount: number,\n characterWidth: number,\n): number {\n const characters = diffGutterWidthCharacters(side, digits, lineCount)\n return Math.ceil(characters * characterWidth + GUTTER_NUMBER_RESERVED_WIDTH)\n}\n\nfunction lineNumberForRow(row: DiffRenderRow, side: DiffGutterNumberSide): string {\n if (row.type === 'hunk' || row.type === 'empty') return ''\n if (side === 'old') return formatLineNumber(row.oldLineNumber)\n return formatLineNumber(row.newLineNumber)\n}\n\nfunction formatLineNumber(value: number | undefined): string {\n if (value === undefined) return ''\n return String(value)\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import './style.css';
2
+ export { createDiffPlugin, diffRowAtEvent } from './editorDiffPlugin';
3
+ export { createDiffEditorOptions } from './editorOptions';
4
+ export { createDiffRegionStore } from './regions';
5
+ export { annotateInlineChanges } from './inline';
6
+ export { joinRenderLines } from './lines';
7
+ export { createLiveDiffProjection } from './liveProjection';
8
+ export { createTextDiff, parseGitPatch } from './model';
9
+ export { createSplitProjection, createStackedProjection } from './projection';
10
+ export { diffSyntaxBackend, prepareDiffSyntax, PreparedDiffSyntaxSource, projectDiffSyntaxTokens, } from './diffSyntax';
11
+ export type { PrepareDiffSyntaxOptions, PreparedDiffSyntaxInput } from './diffSyntax';
12
+ export type { DiffPlugin, DiffPluginMode, DiffPluginOptions, DiffRowHit } from './editorDiffPlugin';
13
+ export type { DiffEditorOptions } from './editorOptions';
14
+ export type { DiffGutterSide } from './gutters';
15
+ export type { DiffRegionStore } from './regions';
16
+ export type { LiveDiffProjection } from './liveProjection';
17
+ export type { CreateTextDiffOptions, DiffFile, DiffFileChangeType, DiffHunk, DiffHunkLine, DiffInlineRange, DiffLineType, DiffRenderRow, DiffRenderRowType, DiffSyntaxBackend, DiffTextFile, ParseGitPatchOptions, } from './types';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAC7E,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AACrF,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACnG,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,YAAY,EACV,qBAAqB,EACrB,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,GACrB,MAAM,SAAS,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ import { joinRenderLines } from "./lines.js";
2
+ import { PreparedDiffSyntaxSource, diffSyntaxBackend, prepareDiffSyntax, projectDiffSyntaxTokens } from "./diffSyntax.js";
3
+ import { createLiveDiffProjection } from "./liveProjection.js";
4
+ import { annotateInlineChanges } from "./inline.js";
5
+ import { createTextDiff, parseGitPatch } from "./model.js";
6
+ import { createSplitProjection, createStackedProjection } from "./projection.js";
7
+ import { createDiffRegionStore } from "./regions.js";
8
+ import { createDiffPlugin, diffRowAtEvent } from "./editorDiffPlugin.js";
9
+ import { createDiffEditorOptions } from "./editorOptions.js";
10
+ import "./style.css";
11
+ export { PreparedDiffSyntaxSource, annotateInlineChanges, createDiffEditorOptions, createDiffPlugin, createDiffRegionStore, createLiveDiffProjection, createSplitProjection, createStackedProjection, createTextDiff, diffRowAtEvent, diffSyntaxBackend, joinRenderLines, parseGitPatch, prepareDiffSyntax, projectDiffSyntaxTokens };
@@ -0,0 +1,3 @@
1
+ import type { DiffHunkLine } from './types';
2
+ export declare function annotateInlineChanges(lines: readonly DiffHunkLine[]): readonly DiffHunkLine[];
3
+ //# sourceMappingURL=inline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,SAAS,CAAA;AAa5D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,YAAY,EAAE,CAU7F"}
package/dist/inline.js ADDED
@@ -0,0 +1,72 @@
1
+ import { diffWordsWithSpace } from "diff";
2
+ //#region src/inline.ts
3
+ function annotateInlineChanges(lines) {
4
+ const result = lines.map((line) => ({ ...line }));
5
+ let index = 0;
6
+ while (index < result.length) {
7
+ const nextIndex = annotateChangeBlock(result, index);
8
+ index = Math.max(index + 1, nextIndex);
9
+ }
10
+ return result;
11
+ }
12
+ function annotateChangeBlock(lines, start) {
13
+ const line = lines[start];
14
+ if (!line || line.type === "context") return start + 1;
15
+ const end = firstContextIndex(lines, start);
16
+ annotateReplacementLines(lines, start, end);
17
+ return end;
18
+ }
19
+ function firstContextIndex(lines, start) {
20
+ let index = start;
21
+ while (index < lines.length && lines[index]?.type !== "context") index += 1;
22
+ return index;
23
+ }
24
+ function annotateReplacementLines(lines, start, end) {
25
+ const deletions = lineIndexesByType(lines, start, end, "deletion");
26
+ const additions = lineIndexesByType(lines, start, end, "addition");
27
+ const pairCount = Math.min(deletions.length, additions.length);
28
+ for (let index = 0; index < pairCount; index += 1) annotateLinePair(lines[deletions[index]], lines[additions[index]]);
29
+ }
30
+ function lineIndexesByType(lines, start, end, type) {
31
+ const indexes = [];
32
+ for (let index = start; index < end; index += 1) {
33
+ if (lines[index]?.type !== type) continue;
34
+ indexes.push(index);
35
+ }
36
+ return indexes;
37
+ }
38
+ function annotateLinePair(oldLine, newLine) {
39
+ const ranges = inlineRangesForPair(oldLine.text, newLine.text);
40
+ oldLine.oldInlineRanges = ranges.oldRanges;
41
+ newLine.newInlineRanges = ranges.newRanges;
42
+ }
43
+ function inlineRangesForPair(oldText, newText) {
44
+ const parts = diffWordsWithSpace(oldText, newText);
45
+ const oldRanges = [];
46
+ const newRanges = [];
47
+ let oldOffset = 0;
48
+ let newOffset = 0;
49
+ for (const part of parts) {
50
+ appendPartRanges(part, oldRanges, newRanges, oldOffset, newOffset);
51
+ if (!part.added) oldOffset += part.value.length;
52
+ if (!part.removed) newOffset += part.value.length;
53
+ }
54
+ return {
55
+ oldRanges,
56
+ newRanges
57
+ };
58
+ }
59
+ function appendPartRanges(part, oldRanges, newRanges, oldOffset, newOffset) {
60
+ if (part.removed) oldRanges.push({
61
+ start: oldOffset,
62
+ end: oldOffset + part.value.length
63
+ });
64
+ if (part.added) newRanges.push({
65
+ start: newOffset,
66
+ end: newOffset + part.value.length
67
+ });
68
+ }
69
+ //#endregion
70
+ export { annotateInlineChanges };
71
+
72
+ //# sourceMappingURL=inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.js","names":[],"sources":["../src/inline.ts"],"sourcesContent":["import { diffWordsWithSpace } from 'diff'\nimport type { DiffHunkLine, DiffInlineRange } from './types'\n\ntype MutableDiffHunkLine = DiffHunkLine & {\n oldInlineRanges?: readonly DiffInlineRange[]\n newInlineRanges?: readonly DiffInlineRange[]\n}\n\ntype WordPart = {\n readonly value: string\n readonly added?: boolean\n readonly removed?: boolean\n}\n\nexport function annotateInlineChanges(lines: readonly DiffHunkLine[]): readonly DiffHunkLine[] {\n const result = lines.map((line) => ({ ...line }))\n let index = 0\n\n while (index < result.length) {\n const nextIndex = annotateChangeBlock(result, index)\n index = Math.max(index + 1, nextIndex)\n }\n\n return result\n}\n\nfunction annotateChangeBlock(lines: MutableDiffHunkLine[], start: number): number {\n const line = lines[start]\n if (!line || line.type === 'context') return start + 1\n\n const end = firstContextIndex(lines, start)\n annotateReplacementLines(lines, start, end)\n return end\n}\n\nfunction firstContextIndex(lines: readonly DiffHunkLine[], start: number): number {\n let index = start\n while (index < lines.length && lines[index]?.type !== 'context') index += 1\n return index\n}\n\nfunction annotateReplacementLines(lines: MutableDiffHunkLine[], start: number, end: number): void {\n const deletions = lineIndexesByType(lines, start, end, 'deletion')\n const additions = lineIndexesByType(lines, start, end, 'addition')\n const pairCount = Math.min(deletions.length, additions.length)\n\n // An unpaired line gets no ranges: its row background already says it is all new or all gone,\n // and a whole-line tint on top turns a multi-line addition into one opaque slab.\n for (let index = 0; index < pairCount; index += 1) {\n annotateLinePair(lines[deletions[index]!]!, lines[additions[index]!]!)\n }\n}\n\nfunction lineIndexesByType(\n lines: readonly DiffHunkLine[],\n start: number,\n end: number,\n type: 'addition' | 'deletion',\n): number[] {\n const indexes: number[] = []\n for (let index = start; index < end; index += 1) {\n if (lines[index]?.type !== type) continue\n indexes.push(index)\n }\n\n return indexes\n}\n\nfunction annotateLinePair(oldLine: MutableDiffHunkLine, newLine: MutableDiffHunkLine): void {\n const ranges = inlineRangesForPair(oldLine.text, newLine.text)\n oldLine.oldInlineRanges = ranges.oldRanges\n newLine.newInlineRanges = ranges.newRanges\n}\n\nfunction inlineRangesForPair(\n oldText: string,\n newText: string,\n): {\n readonly oldRanges: readonly DiffInlineRange[]\n readonly newRanges: readonly DiffInlineRange[]\n} {\n const parts = diffWordsWithSpace(oldText, newText) as readonly WordPart[]\n const oldRanges: DiffInlineRange[] = []\n const newRanges: DiffInlineRange[] = []\n let oldOffset = 0\n let newOffset = 0\n\n for (const part of parts) {\n appendPartRanges(part, oldRanges, newRanges, oldOffset, newOffset)\n if (!part.added) oldOffset += part.value.length\n if (!part.removed) newOffset += part.value.length\n }\n\n return { oldRanges, newRanges }\n}\n\nfunction appendPartRanges(\n part: WordPart,\n oldRanges: DiffInlineRange[],\n newRanges: DiffInlineRange[],\n oldOffset: number,\n newOffset: number,\n): void {\n if (part.removed) oldRanges.push({ start: oldOffset, end: oldOffset + part.value.length })\n if (part.added) newRanges.push({ start: newOffset, end: newOffset + part.value.length })\n}\n"],"mappings":";;AAcA,SAAgB,sBAAsB,OAAyD;CAC7F,MAAM,SAAS,MAAM,KAAK,UAAU,EAAE,GAAG,KAAK,EAAE;CAChD,IAAI,QAAQ;CAEZ,OAAO,QAAQ,OAAO,QAAQ;EAC5B,MAAM,YAAY,oBAAoB,QAAQ,KAAK;EACnD,QAAQ,KAAK,IAAI,QAAQ,GAAG,SAAS;CACvC;CAEA,OAAO;AACT;AAEA,SAAS,oBAAoB,OAA8B,OAAuB;CAChF,MAAM,OAAO,MAAM;CACnB,IAAI,CAAC,QAAQ,KAAK,SAAS,WAAW,OAAO,QAAQ;CAErD,MAAM,MAAM,kBAAkB,OAAO,KAAK;CAC1C,yBAAyB,OAAO,OAAO,GAAG;CAC1C,OAAO;AACT;AAEA,SAAS,kBAAkB,OAAgC,OAAuB;CAChF,IAAI,QAAQ;CACZ,OAAO,QAAQ,MAAM,UAAU,MAAM,MAAM,EAAE,SAAS,WAAW,SAAS;CAC1E,OAAO;AACT;AAEA,SAAS,yBAAyB,OAA8B,OAAe,KAAmB;CAChG,MAAM,YAAY,kBAAkB,OAAO,OAAO,KAAK,UAAU;CACjE,MAAM,YAAY,kBAAkB,OAAO,OAAO,KAAK,UAAU;CACjE,MAAM,YAAY,KAAK,IAAI,UAAU,QAAQ,UAAU,MAAM;CAI7D,KAAK,IAAI,QAAQ,GAAG,QAAQ,WAAW,SAAS,GAC9C,iBAAiB,MAAM,UAAU,SAAW,MAAM,UAAU,OAAS;AAEzE;AAEA,SAAS,kBACP,OACA,OACA,KACA,MACU;CACV,MAAM,UAAoB,CAAC;CAC3B,KAAK,IAAI,QAAQ,OAAO,QAAQ,KAAK,SAAS,GAAG;EAC/C,IAAI,MAAM,MAAM,EAAE,SAAS,MAAM;EACjC,QAAQ,KAAK,KAAK;CACpB;CAEA,OAAO;AACT;AAEA,SAAS,iBAAiB,SAA8B,SAAoC;CAC1F,MAAM,SAAS,oBAAoB,QAAQ,MAAM,QAAQ,IAAI;CAC7D,QAAQ,kBAAkB,OAAO;CACjC,QAAQ,kBAAkB,OAAO;AACnC;AAEA,SAAS,oBACP,SACA,SAIA;CACA,MAAM,QAAQ,mBAAmB,SAAS,OAAO;CACjD,MAAM,YAA+B,CAAC;CACtC,MAAM,YAA+B,CAAC;CACtC,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,OAAO;EACxB,iBAAiB,MAAM,WAAW,WAAW,WAAW,SAAS;EACjE,IAAI,CAAC,KAAK,OAAO,aAAa,KAAK,MAAM;EACzC,IAAI,CAAC,KAAK,SAAS,aAAa,KAAK,MAAM;CAC7C;CAEA,OAAO;EAAE;EAAW;CAAU;AAChC;AAEA,SAAS,iBACP,MACA,WACA,WACA,WACA,WACM;CACN,IAAI,KAAK,SAAS,UAAU,KAAK;EAAE,OAAO;EAAW,KAAK,YAAY,KAAK,MAAM;CAAO,CAAC;CACzF,IAAI,KAAK,OAAO,UAAU,KAAK;EAAE,OAAO;EAAW,KAAK,YAAY,KAAK,MAAM;CAAO,CAAC;AACzF"}
@@ -0,0 +1,8 @@
1
+ export declare function splitTextLines(text: string): readonly string[];
2
+ export declare function joinRenderLines(rows: readonly {
3
+ readonly text: string;
4
+ }[]): string;
5
+ export declare function normalizeContextLines(value: number | undefined): number;
6
+ export declare function stripDiffPathPrefix(path: string | undefined): string;
7
+ export declare function languageIdForPath(path: string): string | null;
8
+ //# sourceMappingURL=lines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../src/lines.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAG9D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAElF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIvE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKpE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK7D"}
package/dist/lines.js ADDED
@@ -0,0 +1,49 @@
1
+ //#region src/lines.ts
2
+ function splitTextLines(text) {
3
+ if (text.length === 0) return [];
4
+ return text.split("\n");
5
+ }
6
+ function joinRenderLines(rows) {
7
+ return rows.map((row) => row.text).join("\n");
8
+ }
9
+ function normalizeContextLines(value) {
10
+ if (value === void 0) return 3;
11
+ if (!Number.isFinite(value)) return 3;
12
+ return Math.max(0, Math.floor(value));
13
+ }
14
+ function stripDiffPathPrefix(path) {
15
+ if (!path) return "";
16
+ if (path === "/dev/null") return path;
17
+ if (path.startsWith("a/") || path.startsWith("b/")) return path.slice(2);
18
+ return path;
19
+ }
20
+ function languageIdForPath(path) {
21
+ const extension = pathExtension(path);
22
+ if (!extension) return null;
23
+ return LANGUAGE_BY_EXTENSION[extension] ?? null;
24
+ }
25
+ function pathExtension(path) {
26
+ const fileName = path.slice(path.lastIndexOf("/") + 1);
27
+ const dotIndex = fileName.lastIndexOf(".");
28
+ if (dotIndex === -1) return "";
29
+ return fileName.slice(dotIndex).toLowerCase();
30
+ }
31
+ var LANGUAGE_BY_EXTENSION = {
32
+ ".cjs": "javascript",
33
+ ".css": "css",
34
+ ".cts": "typescript",
35
+ ".htm": "html",
36
+ ".html": "html",
37
+ ".js": "javascript",
38
+ ".json": "json",
39
+ ".jsx": "javascript",
40
+ ".md": "markdown",
41
+ ".mjs": "javascript",
42
+ ".mts": "typescript",
43
+ ".ts": "typescript",
44
+ ".tsx": "typescript"
45
+ };
46
+ //#endregion
47
+ export { joinRenderLines, languageIdForPath, normalizeContextLines, splitTextLines, stripDiffPathPrefix };
48
+
49
+ //# sourceMappingURL=lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lines.js","names":[],"sources":["../src/lines.ts"],"sourcesContent":["export function splitTextLines(text: string): readonly string[] {\n if (text.length === 0) return []\n return text.split('\\n')\n}\n\nexport function joinRenderLines(rows: readonly { readonly text: string }[]): string {\n return rows.map((row) => row.text).join('\\n')\n}\n\nexport function normalizeContextLines(value: number | undefined): number {\n if (value === undefined) return 3\n if (!Number.isFinite(value)) return 3\n return Math.max(0, Math.floor(value))\n}\n\nexport function stripDiffPathPrefix(path: string | undefined): string {\n if (!path) return ''\n if (path === '/dev/null') return path\n if (path.startsWith('a/') || path.startsWith('b/')) return path.slice(2)\n return path\n}\n\nexport function languageIdForPath(path: string): string | null {\n const extension = pathExtension(path)\n if (!extension) return null\n\n return LANGUAGE_BY_EXTENSION[extension] ?? null\n}\n\nfunction pathExtension(path: string): string {\n const fileName = path.slice(path.lastIndexOf('/') + 1)\n const dotIndex = fileName.lastIndexOf('.')\n if (dotIndex === -1) return ''\n return fileName.slice(dotIndex).toLowerCase()\n}\n\nconst LANGUAGE_BY_EXTENSION: Record<string, string> = {\n '.cjs': 'javascript',\n '.css': 'css',\n '.cts': 'typescript',\n '.htm': 'html',\n '.html': 'html',\n '.js': 'javascript',\n '.json': 'json',\n '.jsx': 'javascript',\n '.md': 'markdown',\n '.mjs': 'javascript',\n '.mts': 'typescript',\n '.ts': 'typescript',\n '.tsx': 'typescript',\n}\n"],"mappings":";AAAA,SAAgB,eAAe,MAAiC;CAC9D,IAAI,KAAK,WAAW,GAAG,OAAO,CAAC;CAC/B,OAAO,KAAK,MAAM,IAAI;AACxB;AAEA,SAAgB,gBAAgB,MAAoD;CAClF,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI;AAC9C;AAEA,SAAgB,sBAAsB,OAAmC;CACvE,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACpC,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC;AACtC;AAEA,SAAgB,oBAAoB,MAAkC;CACpE,IAAI,CAAC,MAAM,OAAO;CAClB,IAAI,SAAS,aAAa,OAAO;CACjC,IAAI,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW,IAAI,GAAG,OAAO,KAAK,MAAM,CAAC;CACvE,OAAO;AACT;AAEA,SAAgB,kBAAkB,MAA6B;CAC7D,MAAM,YAAY,cAAc,IAAI;CACpC,IAAI,CAAC,WAAW,OAAO;CAEvB,OAAO,sBAAsB,cAAc;AAC7C;AAEA,SAAS,cAAc,MAAsB;CAC3C,MAAM,WAAW,KAAK,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;CACrD,MAAM,WAAW,SAAS,YAAY,GAAG;CACzC,IAAI,aAAa,IAAI,OAAO;CAC5B,OAAO,SAAS,MAAM,QAAQ,CAAC,CAAC,YAAY;AAC9C;AAEA,IAAM,wBAAgD;CACpD,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,OAAO;CACP,SAAS;CACT,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,QAAQ;AACV"}
@@ -0,0 +1,11 @@
1
+ import type { VirtualizedTextRowDecoration } from '@singapore-editor/core/rendering';
2
+ import type { EditorInjectedTextRow } from '@singapore-editor/core/extensions';
3
+ import type { DiffFile, DiffRenderRow } from './types';
4
+ export type LiveDiffProjection = {
5
+ readonly injectedRows: readonly EditorInjectedTextRow[];
6
+ readonly rowDecorations: ReadonlyMap<number, VirtualizedTextRowDecoration>;
7
+ readonly rows: readonly DiffRenderRow[];
8
+ readonly rowsByBufferRow: ReadonlyMap<number, DiffRenderRow>;
9
+ };
10
+ export declare function createLiveDiffProjection(file: DiffFile): LiveDiffProjection;
11
+ //# sourceMappingURL=liveProjection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveProjection.d.ts","sourceRoot":"","sources":["../src/liveProjection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,kCAAkC,CAAA;AACpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAA;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAA0B,aAAa,EAAE,MAAM,SAAS,CAAA;AAE9E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,YAAY,EAAE,SAAS,qBAAqB,EAAE,CAAA;IACvD,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAA;IAC1E,QAAQ,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,CAAA;IACvC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAC7D,CAAA;AAKD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,GAAG,kBAAkB,CAG3E"}
@@ -0,0 +1,152 @@
1
+ //#region src/liveProjection.ts
2
+ var DIFF_ROW_CLASS = "editor-diff-row";
3
+ var DIFF_GUTTER_ROW_CLASS = "editor-diff-gutter-row";
4
+ function createLiveDiffProjection(file) {
5
+ return new LiveDiffProjectionBuilder(file).create();
6
+ }
7
+ var LiveDiffProjectionBuilder = class {
8
+ file;
9
+ injectedRows = [];
10
+ rowDecorations = /* @__PURE__ */ new Map();
11
+ rows = [];
12
+ rowsByBufferRow = /* @__PURE__ */ new Map();
13
+ order = 0;
14
+ constructor(file) {
15
+ this.file = file;
16
+ }
17
+ create() {
18
+ let previousOldEnd = 0;
19
+ let previousNewEnd = 0;
20
+ for (const [hunkIndex, hunk] of this.file.hunks.entries()) {
21
+ this.appendUnchangedRows(previousOldEnd + 1, hunk.oldStart - 1, previousNewEnd + 1);
22
+ this.appendHunkRows(hunk, hunkIndex);
23
+ previousOldEnd = hunkEndLine(hunk.oldStart, hunk.oldLines);
24
+ previousNewEnd = hunkEndLine(hunk.newStart, hunk.newLines);
25
+ }
26
+ const nextNewLineNumber = this.appendUnchangedRows(previousOldEnd + 1, this.file.oldLines.length, previousNewEnd + 1);
27
+ this.appendTrailingAdditionRows(nextNewLineNumber);
28
+ return {
29
+ injectedRows: this.injectedRows,
30
+ rowDecorations: this.rowDecorations,
31
+ rows: this.rows,
32
+ rowsByBufferRow: this.rowsByBufferRow
33
+ };
34
+ }
35
+ appendUnchangedRows(oldStart, oldEnd, newStart) {
36
+ let oldLineNumber = oldStart;
37
+ let newLineNumber = newStart;
38
+ while (oldLineNumber <= oldEnd && newLineNumber <= this.file.newLines.length) {
39
+ this.appendDocumentRow({
40
+ type: "context",
41
+ text: this.file.newLines[newLineNumber - 1] ?? "",
42
+ oldLineNumber,
43
+ newLineNumber
44
+ });
45
+ oldLineNumber += 1;
46
+ newLineNumber += 1;
47
+ }
48
+ return newLineNumber;
49
+ }
50
+ appendHunkRows(hunk, hunkIndex) {
51
+ let lastNewLineNumber = hunk.newStart - 1;
52
+ for (const [lineIndex, line] of hunk.lines.entries()) {
53
+ if (line.type === "deletion") {
54
+ this.appendInjectedDeletion(line, hunkIndex, lineIndex, lastNewLineNumber, hunk);
55
+ continue;
56
+ }
57
+ this.appendDocumentRow(renderRowFromHunkLine(line, hunkIndex));
58
+ if (line.type === "addition") this.decorateDocumentRow(line.newLineNumber, "addition");
59
+ lastNewLineNumber = line.newLineNumber ?? lastNewLineNumber;
60
+ }
61
+ }
62
+ appendInjectedDeletion(line, hunkIndex, lineIndex, lastNewLineNumber, hunk) {
63
+ const row = renderRowFromHunkLine(line, hunkIndex);
64
+ const anchor = deletionAnchor(this.file, hunk, lineIndex, lastNewLineNumber);
65
+ this.rows.push(row);
66
+ this.injectedRows.push({
67
+ id: deletionRowId(row, hunkIndex, lineIndex),
68
+ anchorBufferRow: anchor.bufferRow,
69
+ placement: anchor.placement,
70
+ text: line.text,
71
+ order: this.order,
72
+ className: rowClassName("deletion"),
73
+ gutterClassName: gutterRowClassName("deletion"),
74
+ metadata: row
75
+ });
76
+ this.order += 1;
77
+ }
78
+ appendDocumentRow(row) {
79
+ this.rows.push(row);
80
+ if (row.newLineNumber === void 0) return;
81
+ this.rowsByBufferRow.set(row.newLineNumber - 1, row);
82
+ }
83
+ appendTrailingAdditionRows(newStart) {
84
+ for (let newLineNumber = newStart; newLineNumber <= this.file.newLines.length; newLineNumber += 1) {
85
+ const row = {
86
+ type: "addition",
87
+ text: this.file.newLines[newLineNumber - 1] ?? "",
88
+ newLineNumber
89
+ };
90
+ this.appendDocumentRow(row);
91
+ this.decorateDocumentRow(newLineNumber, "addition");
92
+ }
93
+ }
94
+ decorateDocumentRow(lineNumber, type) {
95
+ if (lineNumber === void 0) return;
96
+ this.rowDecorations.set(lineNumber - 1, {
97
+ className: rowClassName(type),
98
+ gutterClassName: gutterRowClassName(type)
99
+ });
100
+ }
101
+ };
102
+ function renderRowFromHunkLine(line, hunkIndex) {
103
+ return {
104
+ type: line.type,
105
+ text: line.text,
106
+ oldLineNumber: line.oldLineNumber,
107
+ newLineNumber: line.newLineNumber,
108
+ hunkIndex
109
+ };
110
+ }
111
+ function deletionAnchor(file, hunk, lineIndex, lastNewLineNumber) {
112
+ const nextNewLineNumber = nextHunkNewLineNumber(hunk.lines, lineIndex + 1);
113
+ if (nextNewLineNumber !== void 0) return {
114
+ bufferRow: clampBufferRow(file, nextNewLineNumber - 1),
115
+ placement: "before"
116
+ };
117
+ if (file.newLines.length === 0) return {
118
+ bufferRow: 0,
119
+ placement: "before"
120
+ };
121
+ return {
122
+ bufferRow: clampBufferRow(file, lastNewLineNumber - 1),
123
+ placement: "after"
124
+ };
125
+ }
126
+ function nextHunkNewLineNumber(lines, startIndex) {
127
+ for (let index = startIndex; index < lines.length; index += 1) {
128
+ const newLineNumber = lines[index]?.newLineNumber;
129
+ if (newLineNumber !== void 0) return newLineNumber;
130
+ }
131
+ }
132
+ function clampBufferRow(file, row) {
133
+ return Math.max(0, Math.min(row, Math.max(0, file.newLines.length - 1)));
134
+ }
135
+ function hunkEndLine(start, count) {
136
+ if (count <= 0) return Math.max(0, start);
137
+ return start + count - 1;
138
+ }
139
+ function rowClassName(type) {
140
+ return `${DIFF_ROW_CLASS} ${DIFF_ROW_CLASS}-${type}`;
141
+ }
142
+ function gutterRowClassName(type) {
143
+ return `${DIFF_GUTTER_ROW_CLASS} ${DIFF_GUTTER_ROW_CLASS}-${type}`;
144
+ }
145
+ function deletionRowId(row, hunkIndex, lineIndex) {
146
+ if (row.oldLineNumber !== void 0) return `diff-delete-old-${row.oldLineNumber}`;
147
+ return `diff-delete-${hunkIndex}-${lineIndex}`;
148
+ }
149
+ //#endregion
150
+ export { createLiveDiffProjection };
151
+
152
+ //# sourceMappingURL=liveProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveProjection.js","names":[],"sources":["../src/liveProjection.ts"],"sourcesContent":["import type { VirtualizedTextRowDecoration } from '@singapore-editor/core/rendering'\nimport type { EditorInjectedTextRow } from '@singapore-editor/core/extensions'\nimport type { DiffFile, DiffHunk, DiffHunkLine, DiffRenderRow } from './types'\n\nexport type LiveDiffProjection = {\n readonly injectedRows: readonly EditorInjectedTextRow[]\n readonly rowDecorations: ReadonlyMap<number, VirtualizedTextRowDecoration>\n readonly rows: readonly DiffRenderRow[]\n readonly rowsByBufferRow: ReadonlyMap<number, DiffRenderRow>\n}\n\nconst DIFF_ROW_CLASS = 'editor-diff-row'\nconst DIFF_GUTTER_ROW_CLASS = 'editor-diff-gutter-row'\n\nexport function createLiveDiffProjection(file: DiffFile): LiveDiffProjection {\n const builder = new LiveDiffProjectionBuilder(file)\n return builder.create()\n}\n\nclass LiveDiffProjectionBuilder {\n private readonly injectedRows: EditorInjectedTextRow[] = []\n private readonly rowDecorations = new Map<number, VirtualizedTextRowDecoration>()\n private readonly rows: DiffRenderRow[] = []\n private readonly rowsByBufferRow = new Map<number, DiffRenderRow>()\n private order = 0\n\n constructor(private readonly file: DiffFile) {}\n\n create(): LiveDiffProjection {\n let previousOldEnd = 0\n let previousNewEnd = 0\n\n for (const [hunkIndex, hunk] of this.file.hunks.entries()) {\n this.appendUnchangedRows(previousOldEnd + 1, hunk.oldStart - 1, previousNewEnd + 1)\n this.appendHunkRows(hunk, hunkIndex)\n previousOldEnd = hunkEndLine(hunk.oldStart, hunk.oldLines)\n previousNewEnd = hunkEndLine(hunk.newStart, hunk.newLines)\n }\n\n const nextNewLineNumber = this.appendUnchangedRows(\n previousOldEnd + 1,\n this.file.oldLines.length,\n previousNewEnd + 1,\n )\n this.appendTrailingAdditionRows(nextNewLineNumber)\n return {\n injectedRows: this.injectedRows,\n rowDecorations: this.rowDecorations,\n rows: this.rows,\n rowsByBufferRow: this.rowsByBufferRow,\n }\n }\n\n private appendUnchangedRows(oldStart: number, oldEnd: number, newStart: number): number {\n let oldLineNumber = oldStart\n let newLineNumber = newStart\n while (oldLineNumber <= oldEnd && newLineNumber <= this.file.newLines.length) {\n this.appendDocumentRow({\n type: 'context',\n text: this.file.newLines[newLineNumber - 1] ?? '',\n oldLineNumber,\n newLineNumber,\n })\n oldLineNumber += 1\n newLineNumber += 1\n }\n\n return newLineNumber\n }\n\n private appendHunkRows(hunk: DiffHunk, hunkIndex: number): void {\n let lastNewLineNumber = hunk.newStart - 1\n for (const [lineIndex, line] of hunk.lines.entries()) {\n if (line.type === 'deletion') {\n this.appendInjectedDeletion(line, hunkIndex, lineIndex, lastNewLineNumber, hunk)\n continue\n }\n\n this.appendDocumentRow(renderRowFromHunkLine(line, hunkIndex))\n if (line.type === 'addition') this.decorateDocumentRow(line.newLineNumber, 'addition')\n lastNewLineNumber = line.newLineNumber ?? lastNewLineNumber\n }\n }\n\n private appendInjectedDeletion(\n line: DiffHunkLine,\n hunkIndex: number,\n lineIndex: number,\n lastNewLineNumber: number,\n hunk: DiffHunk,\n ): void {\n const row = renderRowFromHunkLine(line, hunkIndex)\n const anchor = deletionAnchor(this.file, hunk, lineIndex, lastNewLineNumber)\n this.rows.push(row)\n this.injectedRows.push({\n id: deletionRowId(row, hunkIndex, lineIndex),\n anchorBufferRow: anchor.bufferRow,\n placement: anchor.placement,\n text: line.text,\n order: this.order,\n className: rowClassName('deletion'),\n gutterClassName: gutterRowClassName('deletion'),\n metadata: row,\n })\n this.order += 1\n }\n\n private appendDocumentRow(row: DiffRenderRow): void {\n this.rows.push(row)\n if (row.newLineNumber === undefined) return\n\n this.rowsByBufferRow.set(row.newLineNumber - 1, row)\n }\n\n private appendTrailingAdditionRows(newStart: number): void {\n for (\n let newLineNumber = newStart;\n newLineNumber <= this.file.newLines.length;\n newLineNumber += 1\n ) {\n const row: DiffRenderRow = {\n type: 'addition',\n text: this.file.newLines[newLineNumber - 1] ?? '',\n newLineNumber,\n }\n this.appendDocumentRow(row)\n this.decorateDocumentRow(newLineNumber, 'addition')\n }\n }\n\n private decorateDocumentRow(lineNumber: number | undefined, type: 'addition' | 'deletion'): void {\n if (lineNumber === undefined) return\n\n this.rowDecorations.set(lineNumber - 1, {\n className: rowClassName(type),\n gutterClassName: gutterRowClassName(type),\n })\n }\n}\n\nfunction renderRowFromHunkLine(line: DiffHunkLine, hunkIndex: number): DiffRenderRow {\n return {\n type: line.type,\n text: line.text,\n oldLineNumber: line.oldLineNumber,\n newLineNumber: line.newLineNumber,\n hunkIndex,\n }\n}\n\nfunction deletionAnchor(\n file: DiffFile,\n hunk: DiffHunk,\n lineIndex: number,\n lastNewLineNumber: number,\n): { readonly bufferRow: number; readonly placement: 'before' | 'after' } {\n const nextNewLineNumber = nextHunkNewLineNumber(hunk.lines, lineIndex + 1)\n if (nextNewLineNumber !== undefined) {\n return { bufferRow: clampBufferRow(file, nextNewLineNumber - 1), placement: 'before' }\n }\n\n if (file.newLines.length === 0) return { bufferRow: 0, placement: 'before' }\n return { bufferRow: clampBufferRow(file, lastNewLineNumber - 1), placement: 'after' }\n}\n\nfunction nextHunkNewLineNumber(\n lines: readonly DiffHunkLine[],\n startIndex: number,\n): number | undefined {\n for (let index = startIndex; index < lines.length; index += 1) {\n const newLineNumber = lines[index]?.newLineNumber\n if (newLineNumber !== undefined) return newLineNumber\n }\n\n return undefined\n}\n\nfunction clampBufferRow(file: DiffFile, row: number): number {\n return Math.max(0, Math.min(row, Math.max(0, file.newLines.length - 1)))\n}\n\nfunction hunkEndLine(start: number, count: number): number {\n if (count <= 0) return Math.max(0, start)\n return start + count - 1\n}\n\nfunction rowClassName(type: 'addition' | 'deletion'): string {\n return `${DIFF_ROW_CLASS} ${DIFF_ROW_CLASS}-${type}`\n}\n\nfunction gutterRowClassName(type: 'addition' | 'deletion'): string {\n return `${DIFF_GUTTER_ROW_CLASS} ${DIFF_GUTTER_ROW_CLASS}-${type}`\n}\n\nfunction deletionRowId(row: DiffRenderRow, hunkIndex: number, lineIndex: number): string {\n if (row.oldLineNumber !== undefined) return `diff-delete-old-${row.oldLineNumber}`\n return `diff-delete-${hunkIndex}-${lineIndex}`\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { CreateTextDiffOptions, DiffFile, ParseGitPatchOptions } from './types';
2
+ export declare function createTextDiff(options: CreateTextDiffOptions): DiffFile;
3
+ export declare function parseGitPatch(patchText: string, options?: ParseGitPatchOptions): readonly DiffFile[];
4
+ //# sourceMappingURL=model.d.ts.map