@adecore/merge 0.47.0 → 0.48.1

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.
@@ -0,0 +1,7 @@
1
+ import type { DiffLineRow } from './diff-document.ts';
2
+ import type { Hunk } from './patch-parser.ts';
3
+ export interface DiffSourceLine {
4
+ readonly line: number;
5
+ readonly column: number;
6
+ }
7
+ export declare function sourceLineOf(rows: readonly DiffLineRow[], hunks: readonly Pick<Hunk, 'newStart'>[], line: number, character: number, side: 'old' | 'new'): DiffSourceLine | null;
@@ -0,0 +1,52 @@
1
+ function newNumberIn(rows, from, step, hunk) {
2
+ for (let index = from + step; index >= 0 && index < rows.length; index += step) {
3
+ const row = rows[index];
4
+ if (row.hunk !== hunk) {
5
+ return null;
6
+ }
7
+ if (row.new !== undefined) {
8
+ return row.new.number;
9
+ }
10
+ }
11
+ return null;
12
+ }
13
+ /*
14
+ * The line of the new file that took the place of a removed line, from its own hunk only. Past the last line
15
+ * of the last hunk there may be no line at all, so there it is the line before, or none in a file left empty.
16
+ */
17
+ function removedLineOf(rows, line, hunks) {
18
+ const row = rows[line];
19
+ const next = newNumberIn(rows, line, 1, row.hunk);
20
+ if (next !== null) {
21
+ return next;
22
+ }
23
+ const previous = newNumberIn(rows, line, -1, row.hunk);
24
+ const hunk = row.hunk === undefined ? undefined : hunks[row.hunk];
25
+ // The lines of the new file before the removed one.
26
+ const before = previous ?? hunk?.newStart;
27
+ if (before === undefined) {
28
+ return null;
29
+ }
30
+ if (row.hunk !== undefined && row.hunk < hunks.length - 1) {
31
+ return before + 1;
32
+ }
33
+ return before > 0 ? before : null;
34
+ }
35
+ /*
36
+ * The place in the new file that a caret on a line of a diff stands for. `rows` are the rows of one pane with
37
+ * both of their sides, `hunks` the document's, `line` and `character` count from 0 the way the editor's caret
38
+ * does, and `side` is the text the pane shows for a changed line. A removed line stands for the line that took
39
+ * its place; the column carries over only where the pane shows the new text. Null where the new file has no
40
+ * line at all, such as a diff that deletes the file.
41
+ */
42
+ export function sourceLineOf(rows, hunks, line, character, side) {
43
+ const row = rows[line];
44
+ if (row === undefined) {
45
+ return null;
46
+ }
47
+ if (row.new !== undefined) {
48
+ return { line: row.new.number, column: row.change === 'context' || side === 'new' ? character + 1 : 1 };
49
+ }
50
+ const found = removedLineOf(rows, line, hunks);
51
+ return found === null ? null : { line: found, column: 1 };
52
+ }
package/dist/index.d.ts CHANGED
@@ -9,3 +9,4 @@ export { patchOf } from './patch-of.ts';
9
9
  export { wordChanges, type DiffWordRange } from './word-changes.ts';
10
10
  export { diffDisplay, type DiffDisplay, type DiffDisplayGap } from './diff-display.ts';
11
11
  export { diffSplit, type DiffSplit, type DiffSplitRow } from './diff-split.ts';
12
+ export { sourceLineOf, type DiffSourceLine } from './diff-source.ts';
package/dist/index.js CHANGED
@@ -9,3 +9,4 @@ export { patchOf } from './patch-of.js';
9
9
  export { wordChanges } from './word-changes.js';
10
10
  export { diffDisplay } from './diff-display.js';
11
11
  export { diffSplit } from './diff-split.js';
12
+ export { sourceLineOf } from './diff-source.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/merge",
3
- "version": "0.47.0",
3
+ "version": "0.48.1",
4
4
  "description": "Pure line diffs, three-way merge blocks and conflict resolution.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "author": "Bas Milius",
@@ -0,0 +1,81 @@
1
+ import type { DiffLineRow } from './diff-document.ts';
2
+ import type { Hunk } from './patch-parser.ts';
3
+
4
+ export interface DiffSourceLine {
5
+ /* Both count from 1, in the new file. */
6
+ readonly line: number;
7
+ readonly column: number;
8
+ }
9
+
10
+ function newNumberIn(rows: readonly DiffLineRow[], from: number, step: 1 | -1, hunk: number | undefined): number | null {
11
+ for (let index = from + step; index >= 0 && index < rows.length; index += step) {
12
+ const row = rows[index]!;
13
+
14
+ if (row.hunk !== hunk) {
15
+ return null;
16
+ }
17
+
18
+ if (row.new !== undefined) {
19
+ return row.new.number;
20
+ }
21
+ }
22
+
23
+ return null;
24
+ }
25
+
26
+ /*
27
+ * The line of the new file that took the place of a removed line, from its own hunk only. Past the last line
28
+ * of the last hunk there may be no line at all, so there it is the line before, or none in a file left empty.
29
+ */
30
+ function removedLineOf(rows: readonly DiffLineRow[], line: number, hunks: readonly Pick<Hunk, 'newStart'>[]): number | null {
31
+ const row = rows[line]!;
32
+ const next = newNumberIn(rows, line, 1, row.hunk);
33
+
34
+ if (next !== null) {
35
+ return next;
36
+ }
37
+
38
+ const previous = newNumberIn(rows, line, -1, row.hunk);
39
+ const hunk = row.hunk === undefined ? undefined : hunks[row.hunk];
40
+ // The lines of the new file before the removed one.
41
+ const before = previous ?? hunk?.newStart;
42
+
43
+ if (before === undefined) {
44
+ return null;
45
+ }
46
+
47
+ if (row.hunk !== undefined && row.hunk < hunks.length - 1) {
48
+ return before + 1;
49
+ }
50
+
51
+ return before > 0 ? before : null;
52
+ }
53
+
54
+ /*
55
+ * The place in the new file that a caret on a line of a diff stands for. `rows` are the rows of one pane with
56
+ * both of their sides, `hunks` the document's, `line` and `character` count from 0 the way the editor's caret
57
+ * does, and `side` is the text the pane shows for a changed line. A removed line stands for the line that took
58
+ * its place; the column carries over only where the pane shows the new text. Null where the new file has no
59
+ * line at all, such as a diff that deletes the file.
60
+ */
61
+ export function sourceLineOf(
62
+ rows: readonly DiffLineRow[],
63
+ hunks: readonly Pick<Hunk, 'newStart'>[],
64
+ line: number,
65
+ character: number,
66
+ side: 'old' | 'new'
67
+ ): DiffSourceLine | null {
68
+ const row = rows[line];
69
+
70
+ if (row === undefined) {
71
+ return null;
72
+ }
73
+
74
+ if (row.new !== undefined) {
75
+ return { line: row.new.number, column: row.change === 'context' || side === 'new' ? character + 1 : 1 };
76
+ }
77
+
78
+ const found = removedLineOf(rows, line, hunks);
79
+
80
+ return found === null ? null : { line: found, column: 1 };
81
+ }
package/src/index.ts CHANGED
@@ -9,3 +9,4 @@ export { patchOf } from './patch-of.ts';
9
9
  export { wordChanges, type DiffWordRange } from './word-changes.ts';
10
10
  export { diffDisplay, type DiffDisplay, type DiffDisplayGap } from './diff-display.ts';
11
11
  export { diffSplit, type DiffSplit, type DiffSplitRow } from './diff-split.ts';
12
+ export { sourceLineOf, type DiffSourceLine } from './diff-source.ts';