@tooee/marks 0.2.4 → 0.3.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.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mark-set-builder.d.ts.map +1 -1
- package/dist/mark-set-builder.js +2 -2
- package/dist/mark-set-builder.js.map +1 -1
- package/dist/mark-set.d.ts.map +1 -1
- package/dist/mark-set.js +19 -13
- package/dist/mark-set.js.map +1 -1
- package/dist/mark-state.d.ts +5 -5
- package/dist/mark-state.d.ts.map +1 -1
- package/dist/mark-state.js +19 -18
- package/dist/mark-state.js.map +1 -1
- package/dist/types.d.ts +4 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +6 -6
- package/src/mark-set-builder.ts +12 -12
- package/src/mark-set.ts +73 -64
- package/src/mark-state.ts +38 -39
- package/src/types.ts +21 -21
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-set-builder.d.ts","sourceRoot":"","sources":["../src/mark-set-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"mark-set-builder.d.ts","sourceRoot":"","sources":["../src/mark-set-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,qBAAa,cAAc;;IAGzB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAS7D,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAStF,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAKzB,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;CAGpD"}
|
package/dist/mark-set-builder.js
CHANGED
|
@@ -3,17 +3,17 @@ export class MarkSetBuilder {
|
|
|
3
3
|
#marks = [];
|
|
4
4
|
addLine(line, style, data) {
|
|
5
5
|
this.#marks.push({
|
|
6
|
+
data,
|
|
6
7
|
range: { from: { line }, to: { line } },
|
|
7
8
|
style,
|
|
8
|
-
data,
|
|
9
9
|
});
|
|
10
10
|
return this;
|
|
11
11
|
}
|
|
12
12
|
addRange(from, to, style, data) {
|
|
13
13
|
this.#marks.push({
|
|
14
|
+
data,
|
|
14
15
|
range: { from, to },
|
|
15
16
|
style,
|
|
16
|
-
data,
|
|
17
17
|
});
|
|
18
18
|
return this;
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-set-builder.js","sourceRoot":"","sources":["../src/mark-set-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"mark-set-builder.js","sourceRoot":"","sources":["../src/mark-set-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,MAAM,OAAO,cAAc;IAChB,MAAM,GAAW,EAAE,CAAC;IAE7B,OAAO,CAAC,IAAY,EAAE,KAAgB,EAAE,IAAc;QACpD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,IAAI;YACJ,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;YACvC,KAAK;SACN,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CAAC,IAAkB,EAAE,EAAgB,EAAE,KAAgB,EAAE,IAAc;QAC7E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,IAAI;YACJ,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YACnB,KAAK;SACN,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAU;QAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,SAAiB,EAAE,QAAgB;QACvC,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;CACF"}
|
package/dist/mark-set.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-set.d.ts","sourceRoot":"","sources":["../src/mark-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"mark-set.d.ts","sourceRoot":"","sources":["../src/mark-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWvC,qBAAa,OAAO;;IAClB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAKd,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE;IAe9D,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE;IAuCjC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE;IAc7C,cAAc,CACb,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,SAAS,CAAC;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACtC,CAAC;IA8BF,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC;CAGpC"}
|
package/dist/mark-set.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
function deepFreezeMark(mark) {
|
|
1
|
+
const deepFreezeMark = function deepFreezeMark(mark) {
|
|
2
2
|
Object.freeze(mark.range.from);
|
|
3
3
|
Object.freeze(mark.range.to);
|
|
4
4
|
Object.freeze(mark.range);
|
|
5
5
|
Object.freeze(mark.style);
|
|
6
6
|
Object.freeze(mark);
|
|
7
7
|
return mark;
|
|
8
|
-
}
|
|
8
|
+
};
|
|
9
9
|
export class MarkSet {
|
|
10
10
|
namespace;
|
|
11
11
|
priority;
|
|
@@ -16,11 +16,11 @@ export class MarkSet {
|
|
|
16
16
|
this.namespace = namespace;
|
|
17
17
|
this.priority = priority;
|
|
18
18
|
const sorted = [...marks]
|
|
19
|
-
.
|
|
19
|
+
.toSorted((a, b) => a.range.from.line - b.range.from.line)
|
|
20
20
|
.map(deepFreezeMark);
|
|
21
21
|
this.#marks = sorted;
|
|
22
22
|
const maxEnd = [];
|
|
23
|
-
for (let i = 0; i < sorted.length; i
|
|
23
|
+
for (let i = 0; i < sorted.length; i += 1) {
|
|
24
24
|
const end = sorted[i].range.to.line;
|
|
25
25
|
maxEnd[i] = i === 0 ? end : Math.max(maxEnd[i - 1], end);
|
|
26
26
|
}
|
|
@@ -35,6 +35,9 @@ export class MarkSet {
|
|
|
35
35
|
let lo = 0;
|
|
36
36
|
let hi = this.#marks.length;
|
|
37
37
|
while (lo < hi) {
|
|
38
|
+
// `no-bitwise` is a typo-avoidance rule (`&` vs `&&`). An unsigned shift is the
|
|
39
|
+
// canonical overflow-safe binary-search midpoint and is intentional here.
|
|
40
|
+
// oxlint-disable-next-line no-bitwise -- deliberate binary-search midpoint
|
|
38
41
|
const mid = (lo + hi) >>> 1;
|
|
39
42
|
if (this.#marks[mid].range.from.line < line) {
|
|
40
43
|
lo = mid + 1;
|
|
@@ -43,21 +46,23 @@ export class MarkSet {
|
|
|
43
46
|
hi = mid;
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
|
-
for (let i = lo - 1; i >= 0; i
|
|
49
|
+
for (let i = lo - 1; i >= 0; i -= 1) {
|
|
47
50
|
// If the max end line among marks[0..i] is before the target,
|
|
48
51
|
// no mark at or before index i can reach the target line.
|
|
49
|
-
if (this.#maxEnd[i] < line)
|
|
52
|
+
if (this.#maxEnd[i] < line) {
|
|
50
53
|
break;
|
|
54
|
+
}
|
|
51
55
|
const mark = this.#marks[i];
|
|
52
56
|
if (mark.range.to.line >= line) {
|
|
53
57
|
results.push(mark);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
// Marks starting at this line
|
|
57
|
-
for (let i = lo; i < this.#marks.length; i
|
|
61
|
+
for (let i = lo; i < this.#marks.length; i += 1) {
|
|
58
62
|
const mark = this.#marks[i];
|
|
59
|
-
if (mark.range.from.line > line)
|
|
63
|
+
if (mark.range.from.line > line) {
|
|
60
64
|
break;
|
|
65
|
+
}
|
|
61
66
|
// from.line === line
|
|
62
67
|
results.push(mark);
|
|
63
68
|
}
|
|
@@ -67,8 +72,9 @@ export class MarkSet {
|
|
|
67
72
|
const results = [];
|
|
68
73
|
for (const mark of this.#marks) {
|
|
69
74
|
// A mark overlaps [from, to] if mark.from.line <= to && mark.to.line >= from
|
|
70
|
-
if (mark.range.from.line > to)
|
|
75
|
+
if (mark.range.from.line > to) {
|
|
71
76
|
break;
|
|
77
|
+
}
|
|
72
78
|
if (mark.range.to.line >= from) {
|
|
73
79
|
results.push(mark);
|
|
74
80
|
}
|
|
@@ -80,17 +86,17 @@ export class MarkSet {
|
|
|
80
86
|
for (const mark of marks) {
|
|
81
87
|
const startLine = Math.max(from, mark.range.from.line);
|
|
82
88
|
const endLine = Math.min(to, mark.range.to.line);
|
|
83
|
-
for (let line = startLine; line <= endLine; line
|
|
89
|
+
for (let line = startLine; line <= endLine; line += 1) {
|
|
84
90
|
const decoration = { row: line };
|
|
85
|
-
if (mark.style.background) {
|
|
91
|
+
if ((mark.style.background?.length ?? 0) > 0) {
|
|
86
92
|
decoration.background = mark.style.background;
|
|
87
93
|
}
|
|
88
|
-
if (mark.style.gutterBackground) {
|
|
94
|
+
if ((mark.style.gutterBackground?.length ?? 0) > 0) {
|
|
89
95
|
decoration.gutterBackground = mark.style.gutterBackground;
|
|
90
96
|
}
|
|
91
97
|
const signText = (mark.style.signBefore ?? "") + (mark.style.signAfter ?? "");
|
|
92
98
|
if (signText) {
|
|
93
|
-
decoration.sign = {
|
|
99
|
+
decoration.sign = { fg: mark.style.foreground, text: signText };
|
|
94
100
|
}
|
|
95
101
|
yield decoration;
|
|
96
102
|
}
|
package/dist/mark-set.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-set.js","sourceRoot":"","sources":["../src/mark-set.ts"],"names":[],"mappings":"AAEA,SAAS,cAAc,CAAC,IAAU;
|
|
1
|
+
{"version":3,"file":"mark-set.js","sourceRoot":"","sources":["../src/mark-set.ts"],"names":[],"mappings":"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"}
|
package/dist/mark-state.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ import type { MarkSet } from "./mark-set.js";
|
|
|
3
3
|
export interface MarkState {
|
|
4
4
|
readonly sets: readonly MarkSet[];
|
|
5
5
|
readonly namespaces: readonly string[];
|
|
6
|
-
marksAtLine(line: number)
|
|
7
|
-
effectiveStyleAtLine(line: number)
|
|
8
|
-
getSet(namespace: string)
|
|
6
|
+
marksAtLine: (line: number) => Mark[];
|
|
7
|
+
effectiveStyleAtLine: (line: number) => MarkStyle | null;
|
|
8
|
+
getSet: (namespace: string) => MarkSet | undefined;
|
|
9
9
|
}
|
|
10
|
-
export declare
|
|
11
|
-
export declare
|
|
10
|
+
export declare const createMarkState: (sets: MarkSet[]) => MarkState;
|
|
11
|
+
export declare const updateMarkState: (state: MarkState, namespace: string, newSet: MarkSet | null) => MarkState;
|
|
12
12
|
//# sourceMappingURL=mark-state.d.ts.map
|
package/dist/mark-state.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-state.d.ts","sourceRoot":"","sources":["../src/mark-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"mark-state.d.ts","sourceRoot":"","sources":["../src/mark-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC;IACtC,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,IAAI,CAAC;IACzD,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,CAAC;CACpD;AAoCD,eAAO,MAAM,eAAe,GAA4B,MAAM,OAAO,EAAE,KAAG,SAEzE,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,OAAO,SAAS,EAChB,WAAW,MAAM,EACjB,QAAQ,OAAO,GAAG,IAAI,KACrB,SASF,CAAC"}
|
package/dist/mark-state.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
function makeMarkState(sets) {
|
|
2
|
-
const sortedSets = [...sets].
|
|
1
|
+
const makeMarkState = function makeMarkState(sets) {
|
|
2
|
+
const sortedSets = [...sets].toSorted((a, b) => a.priority - b.priority);
|
|
3
3
|
const namespaces = sortedSets.map((s) => s.namespace);
|
|
4
4
|
return {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
effectiveStyleAtLine(line) {
|
|
6
|
+
const marks = this.marksAtLine(line);
|
|
7
|
+
if (marks.length === 0) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return marks.at(-1)?.style ?? null;
|
|
11
|
+
},
|
|
12
|
+
getSet(namespace) {
|
|
13
|
+
return sortedSets.find((s) => s.namespace === namespace);
|
|
14
|
+
},
|
|
7
15
|
marksAtLine(line) {
|
|
8
16
|
const results = [];
|
|
9
17
|
for (const set of sortedSets) {
|
|
@@ -18,21 +26,14 @@ function makeMarkState(sets) {
|
|
|
18
26
|
results.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
19
27
|
return results;
|
|
20
28
|
},
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (marks.length === 0)
|
|
24
|
-
return null;
|
|
25
|
-
return marks[marks.length - 1].style;
|
|
26
|
-
},
|
|
27
|
-
getSet(namespace) {
|
|
28
|
-
return sortedSets.find((s) => s.namespace === namespace);
|
|
29
|
-
},
|
|
29
|
+
namespaces,
|
|
30
|
+
sets: sortedSets,
|
|
30
31
|
};
|
|
31
|
-
}
|
|
32
|
-
export function createMarkState(sets) {
|
|
32
|
+
};
|
|
33
|
+
export const createMarkState = function createMarkState(sets) {
|
|
33
34
|
return makeMarkState(sets);
|
|
34
|
-
}
|
|
35
|
-
export function updateMarkState(state, namespace, newSet) {
|
|
35
|
+
};
|
|
36
|
+
export const updateMarkState = function updateMarkState(state, namespace, newSet) {
|
|
36
37
|
if (newSet && newSet.namespace !== namespace) {
|
|
37
38
|
throw new Error(`Namespace mismatch: expected "${namespace}", got "${newSet.namespace}"`);
|
|
38
39
|
}
|
|
@@ -41,5 +42,5 @@ export function updateMarkState(state, namespace, newSet) {
|
|
|
41
42
|
filtered.push(newSet);
|
|
42
43
|
}
|
|
43
44
|
return makeMarkState(filtered);
|
|
44
|
-
}
|
|
45
|
+
};
|
|
45
46
|
//# sourceMappingURL=mark-state.js.map
|
package/dist/mark-state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark-state.js","sourceRoot":"","sources":["../src/mark-state.ts"],"names":[],"mappings":"AAWA,SAAS,aAAa,CAAC,IAAwB;
|
|
1
|
+
{"version":3,"file":"mark-state.js","sourceRoot":"","sources":["../src/mark-state.ts"],"names":[],"mappings":"AAWA,MAAM,aAAa,GAAG,SAAS,aAAa,CAAC,IAAwB;IACnE,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEtD,OAAO;QACL,oBAAoB,CAAC,IAAY;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;QACrC,CAAC;QACD,MAAM,CAAC,SAAiB;YACtB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAC3D,CAAC;QACD,WAAW,CAAC,IAAY;YACtB,MAAM,OAAO,GAAW,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;gBACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,OAAO,CAAC,IAAI,CAAC;wBACX,GAAG,IAAI;wBACP,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;qBACxC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9D,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,UAAU;QACV,IAAI,EAAE,UAAU;KACjB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,eAAe,CAAC,IAAe;IACrE,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,SAAS,eAAe,CACrD,KAAgB,EAChB,SAAiB,EACjB,MAAsB;IAEtB,IAAI,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,iCAAiC,SAAS,WAAW,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;IAC5F,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IACrE,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -22,13 +22,13 @@ export interface Mark<T = unknown> {
|
|
|
22
22
|
priority?: number;
|
|
23
23
|
}
|
|
24
24
|
export declare const MarkPriorities: {
|
|
25
|
-
readonly
|
|
25
|
+
readonly CURRENT_MATCH: 400;
|
|
26
|
+
readonly CURSOR: 500;
|
|
26
27
|
readonly DIAGNOSTIC: 150;
|
|
28
|
+
readonly SEARCH_MATCH: 100;
|
|
29
|
+
readonly SELECTION: 300;
|
|
27
30
|
readonly TOGGLED: 200;
|
|
28
31
|
readonly USER: 250;
|
|
29
|
-
readonly SELECTION: 300;
|
|
30
|
-
readonly CURRENT_MATCH: 400;
|
|
31
|
-
readonly CURSOR: 500;
|
|
32
32
|
};
|
|
33
33
|
export type MarkPriority = (typeof MarkPriorities)[keyof typeof MarkPriorities];
|
|
34
34
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,YAAY,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,IAAI,CAAC,CAAC,GAAG,OAAO;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC"}
|
package/dist/types.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export const MarkPriorities = {
|
|
2
|
-
|
|
2
|
+
CURRENT_MATCH: 400,
|
|
3
|
+
CURSOR: 500,
|
|
3
4
|
DIAGNOSTIC: 150,
|
|
5
|
+
SEARCH_MATCH: 100,
|
|
6
|
+
SELECTION: 300,
|
|
4
7
|
TOGGLED: 200,
|
|
5
8
|
USER: 250,
|
|
6
|
-
SELECTION: 300,
|
|
7
|
-
CURRENT_MATCH: 400,
|
|
8
|
-
CURSOR: 500,
|
|
9
9
|
};
|
|
10
10
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2BA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2BA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,aAAa,EAAE,GAAG;IAClB,MAAM,EAAE,GAAG;IACX,UAAU,EAAE,GAAG;IACf,YAAY,EAAE,GAAG;IACjB,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,GAAG;IACZ,IAAI,EAAE,GAAG;CACD,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export type { MarkPosition, MarkRange, MarkStyle, Mark, MarkPriority } from "./types.js"
|
|
2
|
-
export { MarkPriorities } from "./types.js"
|
|
1
|
+
export type { MarkPosition, MarkRange, MarkStyle, Mark, MarkPriority } from "./types.js";
|
|
2
|
+
export { MarkPriorities } from "./types.js";
|
|
3
3
|
|
|
4
|
-
export { MarkSet } from "./mark-set.js"
|
|
5
|
-
export { MarkSetBuilder } from "./mark-set-builder.js"
|
|
4
|
+
export { MarkSet } from "./mark-set.js";
|
|
5
|
+
export { MarkSetBuilder } from "./mark-set-builder.js";
|
|
6
6
|
|
|
7
|
-
export type { MarkState } from "./mark-state.js"
|
|
8
|
-
export { createMarkState, updateMarkState } from "./mark-state.js"
|
|
7
|
+
export type { MarkState } from "./mark-state.js";
|
|
8
|
+
export { createMarkState, updateMarkState } from "./mark-state.js";
|
package/src/mark-set-builder.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import type { Mark, MarkPosition, MarkStyle } from "./types.js"
|
|
2
|
-
import { MarkSet } from "./mark-set.js"
|
|
1
|
+
import type { Mark, MarkPosition, MarkStyle } from "./types.js";
|
|
2
|
+
import { MarkSet } from "./mark-set.js";
|
|
3
3
|
|
|
4
4
|
export class MarkSetBuilder {
|
|
5
|
-
readonly #marks: Mark[] = []
|
|
5
|
+
readonly #marks: Mark[] = [];
|
|
6
6
|
|
|
7
7
|
addLine(line: number, style: MarkStyle, data?: unknown): this {
|
|
8
8
|
this.#marks.push({
|
|
9
|
+
data,
|
|
9
10
|
range: { from: { line }, to: { line } },
|
|
10
11
|
style,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return this
|
|
12
|
+
});
|
|
13
|
+
return this;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
addRange(from: MarkPosition, to: MarkPosition, style: MarkStyle, data?: unknown): this {
|
|
17
17
|
this.#marks.push({
|
|
18
|
+
data,
|
|
18
19
|
range: { from, to },
|
|
19
20
|
style,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return this
|
|
21
|
+
});
|
|
22
|
+
return this;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
addMark(mark: Mark): this {
|
|
26
|
-
this.#marks.push(mark)
|
|
27
|
-
return this
|
|
26
|
+
this.#marks.push(mark);
|
|
27
|
+
return this;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
build(namespace: string, priority: number): MarkSet {
|
|
31
|
-
return new MarkSet(namespace, priority, this.#marks)
|
|
31
|
+
return new MarkSet(namespace, priority, this.#marks);
|
|
32
32
|
}
|
|
33
33
|
}
|
package/src/mark-set.ts
CHANGED
|
@@ -1,123 +1,132 @@
|
|
|
1
|
-
import type { Mark } from "./types.js"
|
|
1
|
+
import type { Mark } from "./types.js";
|
|
2
2
|
|
|
3
|
-
function deepFreezeMark(mark: Mark): Mark {
|
|
4
|
-
Object.freeze(mark.range.from)
|
|
5
|
-
Object.freeze(mark.range.to)
|
|
6
|
-
Object.freeze(mark.range)
|
|
7
|
-
Object.freeze(mark.style)
|
|
8
|
-
Object.freeze(mark)
|
|
9
|
-
return mark
|
|
10
|
-
}
|
|
3
|
+
const deepFreezeMark = function deepFreezeMark(mark: Mark): Mark {
|
|
4
|
+
Object.freeze(mark.range.from);
|
|
5
|
+
Object.freeze(mark.range.to);
|
|
6
|
+
Object.freeze(mark.range);
|
|
7
|
+
Object.freeze(mark.style);
|
|
8
|
+
Object.freeze(mark);
|
|
9
|
+
return mark;
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
export class MarkSet {
|
|
13
|
-
readonly namespace: string
|
|
14
|
-
readonly priority: number
|
|
15
|
-
readonly #marks: readonly Mark[]
|
|
13
|
+
readonly namespace: string;
|
|
14
|
+
readonly priority: number;
|
|
15
|
+
readonly #marks: readonly Mark[];
|
|
16
16
|
// #maxEnd[i] = max to.line among marks[0..i], enables O(1) early exit in backward scan
|
|
17
|
-
readonly #maxEnd: readonly number[]
|
|
17
|
+
readonly #maxEnd: readonly number[];
|
|
18
18
|
|
|
19
19
|
constructor(namespace: string, priority: number, marks: Mark[]) {
|
|
20
|
-
this.namespace = namespace
|
|
21
|
-
this.priority = priority
|
|
20
|
+
this.namespace = namespace;
|
|
21
|
+
this.priority = priority;
|
|
22
22
|
const sorted = [...marks]
|
|
23
|
-
.
|
|
24
|
-
.map(deepFreezeMark)
|
|
25
|
-
this.#marks = sorted
|
|
26
|
-
const maxEnd: number[] = []
|
|
27
|
-
for (let i = 0; i < sorted.length; i
|
|
28
|
-
const end = sorted[i].range.to.line
|
|
29
|
-
maxEnd[i] = i === 0 ? end : Math.max(maxEnd[i - 1], end)
|
|
23
|
+
.toSorted((a, b) => a.range.from.line - b.range.from.line)
|
|
24
|
+
.map(deepFreezeMark);
|
|
25
|
+
this.#marks = sorted;
|
|
26
|
+
const maxEnd: number[] = [];
|
|
27
|
+
for (let i = 0; i < sorted.length; i += 1) {
|
|
28
|
+
const end = sorted[i].range.to.line;
|
|
29
|
+
maxEnd[i] = i === 0 ? end : Math.max(maxEnd[i - 1], end);
|
|
30
30
|
}
|
|
31
|
-
this.#maxEnd = maxEnd
|
|
31
|
+
this.#maxEnd = maxEnd;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
get size(): number {
|
|
35
|
-
return this.#marks.length
|
|
35
|
+
return this.#marks.length;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
marksAtLine(line: number): Mark[] {
|
|
39
|
-
const results: Mark[] = []
|
|
39
|
+
const results: Mark[] = [];
|
|
40
40
|
// Binary search for the first mark whose from.line >= line
|
|
41
|
-
let lo = 0
|
|
42
|
-
let hi = this.#marks.length
|
|
41
|
+
let lo = 0;
|
|
42
|
+
let hi = this.#marks.length;
|
|
43
43
|
while (lo < hi) {
|
|
44
|
-
|
|
44
|
+
// `no-bitwise` is a typo-avoidance rule (`&` vs `&&`). An unsigned shift is the
|
|
45
|
+
// canonical overflow-safe binary-search midpoint and is intentional here.
|
|
46
|
+
// oxlint-disable-next-line no-bitwise -- deliberate binary-search midpoint
|
|
47
|
+
const mid = (lo + hi) >>> 1;
|
|
45
48
|
if (this.#marks[mid].range.from.line < line) {
|
|
46
|
-
lo = mid + 1
|
|
49
|
+
lo = mid + 1;
|
|
47
50
|
} else {
|
|
48
|
-
hi = mid
|
|
51
|
+
hi = mid;
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
|
-
for (let i = lo - 1; i >= 0; i
|
|
54
|
+
for (let i = lo - 1; i >= 0; i -= 1) {
|
|
52
55
|
// If the max end line among marks[0..i] is before the target,
|
|
53
56
|
// no mark at or before index i can reach the target line.
|
|
54
|
-
if (this.#maxEnd[i] < line)
|
|
55
|
-
|
|
57
|
+
if (this.#maxEnd[i] < line) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
const mark = this.#marks[i];
|
|
56
61
|
if (mark.range.to.line >= line) {
|
|
57
|
-
results.push(mark)
|
|
62
|
+
results.push(mark);
|
|
58
63
|
}
|
|
59
64
|
}
|
|
60
65
|
// Marks starting at this line
|
|
61
|
-
for (let i = lo; i < this.#marks.length; i
|
|
62
|
-
const mark = this.#marks[i]
|
|
63
|
-
if (mark.range.from.line > line)
|
|
66
|
+
for (let i = lo; i < this.#marks.length; i += 1) {
|
|
67
|
+
const mark = this.#marks[i];
|
|
68
|
+
if (mark.range.from.line > line) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
64
71
|
// from.line === line
|
|
65
|
-
results.push(mark)
|
|
72
|
+
results.push(mark);
|
|
66
73
|
}
|
|
67
|
-
return results
|
|
74
|
+
return results;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
marksInRange(from: number, to: number): Mark[] {
|
|
71
|
-
const results: Mark[] = []
|
|
78
|
+
const results: Mark[] = [];
|
|
72
79
|
for (const mark of this.#marks) {
|
|
73
80
|
// A mark overlaps [from, to] if mark.from.line <= to && mark.to.line >= from
|
|
74
|
-
if (mark.range.from.line > to)
|
|
81
|
+
if (mark.range.from.line > to) {
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
75
84
|
if (mark.range.to.line >= from) {
|
|
76
|
-
results.push(mark)
|
|
85
|
+
results.push(mark);
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
|
-
return results
|
|
88
|
+
return results;
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
*forVisibleRows(
|
|
83
92
|
from: number,
|
|
84
93
|
to: number,
|
|
85
94
|
): Generator<{
|
|
86
|
-
row: number
|
|
87
|
-
background?: string
|
|
88
|
-
gutterBackground?: string
|
|
89
|
-
sign?: { text: string; fg?: string }
|
|
95
|
+
row: number;
|
|
96
|
+
background?: string;
|
|
97
|
+
gutterBackground?: string;
|
|
98
|
+
sign?: { text: string; fg?: string };
|
|
90
99
|
}> {
|
|
91
|
-
const marks = this.marksInRange(from, to)
|
|
100
|
+
const marks = this.marksInRange(from, to);
|
|
92
101
|
for (const mark of marks) {
|
|
93
|
-
const startLine = Math.max(from, mark.range.from.line)
|
|
94
|
-
const endLine = Math.min(to, mark.range.to.line)
|
|
95
|
-
for (let line = startLine; line <= endLine; line
|
|
102
|
+
const startLine = Math.max(from, mark.range.from.line);
|
|
103
|
+
const endLine = Math.min(to, mark.range.to.line);
|
|
104
|
+
for (let line = startLine; line <= endLine; line += 1) {
|
|
96
105
|
const decoration: {
|
|
97
|
-
row: number
|
|
98
|
-
background?: string
|
|
99
|
-
gutterBackground?: string
|
|
100
|
-
sign?: { text: string; fg?: string }
|
|
101
|
-
} = { row: line }
|
|
106
|
+
row: number;
|
|
107
|
+
background?: string;
|
|
108
|
+
gutterBackground?: string;
|
|
109
|
+
sign?: { text: string; fg?: string };
|
|
110
|
+
} = { row: line };
|
|
102
111
|
|
|
103
|
-
if (mark.style.background) {
|
|
104
|
-
decoration.background = mark.style.background
|
|
112
|
+
if ((mark.style.background?.length ?? 0) > 0) {
|
|
113
|
+
decoration.background = mark.style.background;
|
|
105
114
|
}
|
|
106
|
-
if (mark.style.gutterBackground) {
|
|
107
|
-
decoration.gutterBackground = mark.style.gutterBackground
|
|
115
|
+
if ((mark.style.gutterBackground?.length ?? 0) > 0) {
|
|
116
|
+
decoration.gutterBackground = mark.style.gutterBackground;
|
|
108
117
|
}
|
|
109
118
|
|
|
110
|
-
const signText = (mark.style.signBefore ?? "") + (mark.style.signAfter ?? "")
|
|
119
|
+
const signText = (mark.style.signBefore ?? "") + (mark.style.signAfter ?? "");
|
|
111
120
|
if (signText) {
|
|
112
|
-
decoration.sign = {
|
|
121
|
+
decoration.sign = { fg: mark.style.foreground, text: signText };
|
|
113
122
|
}
|
|
114
123
|
|
|
115
|
-
yield decoration
|
|
124
|
+
yield decoration;
|
|
116
125
|
}
|
|
117
126
|
}
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
[Symbol.iterator](): Iterator<Mark> {
|
|
121
|
-
return this.#marks[Symbol.iterator]()
|
|
130
|
+
return this.#marks[Symbol.iterator]();
|
|
122
131
|
}
|
|
123
132
|
}
|
package/src/mark-state.ts
CHANGED
|
@@ -1,64 +1,63 @@
|
|
|
1
|
-
import type { Mark, MarkStyle } from "./types.js"
|
|
2
|
-
import type { MarkSet } from "./mark-set.js"
|
|
1
|
+
import type { Mark, MarkStyle } from "./types.js";
|
|
2
|
+
import type { MarkSet } from "./mark-set.js";
|
|
3
3
|
|
|
4
4
|
export interface MarkState {
|
|
5
|
-
readonly sets: readonly MarkSet[]
|
|
6
|
-
readonly namespaces: readonly string[]
|
|
7
|
-
marksAtLine(line: number)
|
|
8
|
-
effectiveStyleAtLine(line: number)
|
|
9
|
-
getSet(namespace: string)
|
|
5
|
+
readonly sets: readonly MarkSet[];
|
|
6
|
+
readonly namespaces: readonly string[];
|
|
7
|
+
marksAtLine: (line: number) => Mark[];
|
|
8
|
+
effectiveStyleAtLine: (line: number) => MarkStyle | null;
|
|
9
|
+
getSet: (namespace: string) => MarkSet | undefined;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
function makeMarkState(sets: readonly MarkSet[]): MarkState {
|
|
13
|
-
const sortedSets = [...sets].
|
|
14
|
-
const namespaces = sortedSets.map((s) => s.namespace)
|
|
12
|
+
const makeMarkState = function makeMarkState(sets: readonly MarkSet[]): MarkState {
|
|
13
|
+
const sortedSets = [...sets].toSorted((a, b) => a.priority - b.priority);
|
|
14
|
+
const namespaces = sortedSets.map((s) => s.namespace);
|
|
15
15
|
|
|
16
16
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
effectiveStyleAtLine(line: number): MarkStyle | null {
|
|
18
|
+
const marks = this.marksAtLine(line);
|
|
19
|
+
if (marks.length === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return marks.at(-1)?.style ?? null;
|
|
23
|
+
},
|
|
24
|
+
getSet(namespace: string): MarkSet | undefined {
|
|
25
|
+
return sortedSets.find((s) => s.namespace === namespace);
|
|
26
|
+
},
|
|
20
27
|
marksAtLine(line: number): Mark[] {
|
|
21
|
-
const results: Mark[] = []
|
|
28
|
+
const results: Mark[] = [];
|
|
22
29
|
for (const set of sortedSets) {
|
|
23
|
-
const marks = set.marksAtLine(line)
|
|
30
|
+
const marks = set.marksAtLine(line);
|
|
24
31
|
for (const mark of marks) {
|
|
25
32
|
results.push({
|
|
26
33
|
...mark,
|
|
27
34
|
priority: mark.priority ?? set.priority,
|
|
28
|
-
})
|
|
35
|
+
});
|
|
29
36
|
}
|
|
30
37
|
}
|
|
31
|
-
results.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0))
|
|
32
|
-
return results
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
effectiveStyleAtLine(line: number): MarkStyle | null {
|
|
36
|
-
const marks = this.marksAtLine(line)
|
|
37
|
-
if (marks.length === 0) return null
|
|
38
|
-
return marks[marks.length - 1].style
|
|
38
|
+
results.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
39
|
+
return results;
|
|
39
40
|
},
|
|
41
|
+
namespaces,
|
|
42
|
+
sets: sortedSets,
|
|
43
|
+
};
|
|
44
|
+
};
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function createMarkState(sets: MarkSet[]): MarkState {
|
|
48
|
-
return makeMarkState(sets)
|
|
49
|
-
}
|
|
46
|
+
export const createMarkState = function createMarkState(sets: MarkSet[]): MarkState {
|
|
47
|
+
return makeMarkState(sets);
|
|
48
|
+
};
|
|
50
49
|
|
|
51
|
-
export function updateMarkState(
|
|
50
|
+
export const updateMarkState = function updateMarkState(
|
|
52
51
|
state: MarkState,
|
|
53
52
|
namespace: string,
|
|
54
53
|
newSet: MarkSet | null,
|
|
55
54
|
): MarkState {
|
|
56
55
|
if (newSet && newSet.namespace !== namespace) {
|
|
57
|
-
throw new Error(`Namespace mismatch: expected "${namespace}", got "${newSet.namespace}"`)
|
|
56
|
+
throw new Error(`Namespace mismatch: expected "${namespace}", got "${newSet.namespace}"`);
|
|
58
57
|
}
|
|
59
|
-
const filtered = state.sets.filter((s) => s.namespace !== namespace)
|
|
58
|
+
const filtered = state.sets.filter((s) => s.namespace !== namespace);
|
|
60
59
|
if (newSet) {
|
|
61
|
-
filtered.push(newSet)
|
|
60
|
+
filtered.push(newSet);
|
|
62
61
|
}
|
|
63
|
-
return makeMarkState(filtered)
|
|
64
|
-
}
|
|
62
|
+
return makeMarkState(filtered);
|
|
63
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
export interface MarkPosition {
|
|
2
|
-
line: number
|
|
2
|
+
line: number;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
export interface MarkRange {
|
|
6
|
-
from: MarkPosition
|
|
7
|
-
to: MarkPosition
|
|
6
|
+
from: MarkPosition;
|
|
7
|
+
to: MarkPosition;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export interface MarkStyle {
|
|
11
|
-
background?: string
|
|
12
|
-
gutterBackground?: string
|
|
13
|
-
foreground?: string
|
|
14
|
-
signBefore?: string
|
|
15
|
-
signAfter?: string
|
|
16
|
-
themeColor?: string
|
|
17
|
-
className?: string
|
|
11
|
+
background?: string;
|
|
12
|
+
gutterBackground?: string;
|
|
13
|
+
foreground?: string;
|
|
14
|
+
signBefore?: string;
|
|
15
|
+
signAfter?: string;
|
|
16
|
+
themeColor?: string;
|
|
17
|
+
className?: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export interface Mark<T = unknown> {
|
|
21
|
-
id?: string
|
|
22
|
-
range: MarkRange
|
|
23
|
-
style: MarkStyle
|
|
24
|
-
data?: T
|
|
25
|
-
priority?: number
|
|
21
|
+
id?: string;
|
|
22
|
+
range: MarkRange;
|
|
23
|
+
style: MarkStyle;
|
|
24
|
+
data?: T;
|
|
25
|
+
priority?: number;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export const MarkPriorities = {
|
|
29
|
-
|
|
29
|
+
CURRENT_MATCH: 400,
|
|
30
|
+
CURSOR: 500,
|
|
30
31
|
DIAGNOSTIC: 150,
|
|
32
|
+
SEARCH_MATCH: 100,
|
|
33
|
+
SELECTION: 300,
|
|
31
34
|
TOGGLED: 200,
|
|
32
35
|
USER: 250,
|
|
33
|
-
|
|
34
|
-
CURRENT_MATCH: 400,
|
|
35
|
-
CURSOR: 500,
|
|
36
|
-
} as const
|
|
36
|
+
} as const;
|
|
37
37
|
|
|
38
|
-
export type MarkPriority = (typeof MarkPriorities)[keyof typeof MarkPriorities]
|
|
38
|
+
export type MarkPriority = (typeof MarkPriorities)[keyof typeof MarkPriorities];
|