@termaxjs/editor-core 0.1.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.
Files changed (91) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +274 -0
  3. package/dist/buffer/PieceTable.d.ts +31 -0
  4. package/dist/buffer/PieceTable.d.ts.map +1 -0
  5. package/dist/buffer/PieceTable.js +365 -0
  6. package/dist/buffer/PieceTable.js.map +1 -0
  7. package/dist/buffer/TerminalBuffer.d.ts +45 -0
  8. package/dist/buffer/TerminalBuffer.d.ts.map +1 -0
  9. package/dist/buffer/TerminalBuffer.js +166 -0
  10. package/dist/buffer/TerminalBuffer.js.map +1 -0
  11. package/dist/collab/AwarenessState.d.ts +30 -0
  12. package/dist/collab/AwarenessState.d.ts.map +1 -0
  13. package/dist/collab/AwarenessState.js +76 -0
  14. package/dist/collab/AwarenessState.js.map +1 -0
  15. package/dist/collab/CollabProvider.d.ts +45 -0
  16. package/dist/collab/CollabProvider.d.ts.map +1 -0
  17. package/dist/collab/CollabProvider.js +153 -0
  18. package/dist/collab/CollabProvider.js.map +1 -0
  19. package/dist/coordinates.d.ts +132 -0
  20. package/dist/coordinates.d.ts.map +1 -0
  21. package/dist/coordinates.js +651 -0
  22. package/dist/coordinates.js.map +1 -0
  23. package/dist/decoration/Decoration.d.ts +36 -0
  24. package/dist/decoration/Decoration.d.ts.map +1 -0
  25. package/dist/decoration/Decoration.js +34 -0
  26. package/dist/decoration/Decoration.js.map +1 -0
  27. package/dist/decoration/DecorationSet.d.ts +16 -0
  28. package/dist/decoration/DecorationSet.d.ts.map +1 -0
  29. package/dist/decoration/DecorationSet.js +54 -0
  30. package/dist/decoration/DecorationSet.js.map +1 -0
  31. package/dist/diff/diff.d.ts +27 -0
  32. package/dist/diff/diff.d.ts.map +1 -0
  33. package/dist/diff/diff.js +219 -0
  34. package/dist/diff/diff.js.map +1 -0
  35. package/dist/index.d.ts +22 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +22 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/layout/HeightMap.d.ts +35 -0
  40. package/dist/layout/HeightMap.d.ts.map +1 -0
  41. package/dist/layout/HeightMap.js +95 -0
  42. package/dist/layout/HeightMap.js.map +1 -0
  43. package/dist/layout/softWrap.d.ts +23 -0
  44. package/dist/layout/softWrap.d.ts.map +1 -0
  45. package/dist/layout/softWrap.js +67 -0
  46. package/dist/layout/softWrap.js.map +1 -0
  47. package/dist/state/Annotation.d.ts +22 -0
  48. package/dist/state/Annotation.d.ts.map +1 -0
  49. package/dist/state/Annotation.js +38 -0
  50. package/dist/state/Annotation.js.map +1 -0
  51. package/dist/state/ChangeSet.d.ts +27 -0
  52. package/dist/state/ChangeSet.d.ts.map +1 -0
  53. package/dist/state/ChangeSet.js +162 -0
  54. package/dist/state/ChangeSet.js.map +1 -0
  55. package/dist/state/EditorState.d.ts +25 -0
  56. package/dist/state/EditorState.d.ts.map +1 -0
  57. package/dist/state/EditorState.js +110 -0
  58. package/dist/state/EditorState.js.map +1 -0
  59. package/dist/state/Extension.d.ts +16 -0
  60. package/dist/state/Extension.d.ts.map +1 -0
  61. package/dist/state/Extension.js +12 -0
  62. package/dist/state/Extension.js.map +1 -0
  63. package/dist/state/Facet.d.ts +13 -0
  64. package/dist/state/Facet.d.ts.map +1 -0
  65. package/dist/state/Facet.js +22 -0
  66. package/dist/state/Facet.js.map +1 -0
  67. package/dist/state/Keymap.d.ts +22 -0
  68. package/dist/state/Keymap.d.ts.map +1 -0
  69. package/dist/state/Keymap.js +10 -0
  70. package/dist/state/Keymap.js.map +1 -0
  71. package/dist/state/MultiCursorPaste.d.ts +14 -0
  72. package/dist/state/MultiCursorPaste.d.ts.map +1 -0
  73. package/dist/state/MultiCursorPaste.js +18 -0
  74. package/dist/state/MultiCursorPaste.js.map +1 -0
  75. package/dist/state/RectangularSelection.d.ts +12 -0
  76. package/dist/state/RectangularSelection.d.ts.map +1 -0
  77. package/dist/state/RectangularSelection.js +27 -0
  78. package/dist/state/RectangularSelection.js.map +1 -0
  79. package/dist/state/StateField.d.ts +18 -0
  80. package/dist/state/StateField.d.ts.map +1 -0
  81. package/dist/state/StateField.js +29 -0
  82. package/dist/state/StateField.js.map +1 -0
  83. package/dist/state/Transaction.d.ts +22 -0
  84. package/dist/state/Transaction.d.ts.map +1 -0
  85. package/dist/state/Transaction.js +23 -0
  86. package/dist/state/Transaction.js.map +1 -0
  87. package/dist/types.d.ts +161 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +6 -0
  90. package/dist/types.js.map +1 -0
  91. package/package.json +38 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Manages multi-user presence, remote cursors, and active selections.
3
+ */
4
+ export class AwarenessManager {
5
+ localClientId;
6
+ localUser;
7
+ peers = new Map();
8
+ listeners = new Set();
9
+ constructor(clientId, name = "Anonymous", color = "#58a6ff") {
10
+ this.localClientId = clientId;
11
+ this.localUser = {
12
+ clientId,
13
+ name,
14
+ color,
15
+ cursor: { line: 0, column: 0 },
16
+ selection: null,
17
+ lastActive: Date.now(),
18
+ };
19
+ }
20
+ setLocalState(cursor, selection = null) {
21
+ this.localUser.cursor = { ...cursor };
22
+ this.localUser.selection = selection ? { ...selection } : null;
23
+ this.localUser.lastActive = Date.now();
24
+ this.notify();
25
+ }
26
+ setLocalUserProfile(name, color) {
27
+ this.localUser.name = name;
28
+ this.localUser.color = color;
29
+ this.localUser.lastActive = Date.now();
30
+ this.notify();
31
+ }
32
+ getLocalUser() {
33
+ return { ...this.localUser };
34
+ }
35
+ updateRemotePeer(peer) {
36
+ if (peer.clientId === this.localClientId)
37
+ return;
38
+ this.peers.set(peer.clientId, { ...peer, lastActive: Date.now() });
39
+ this.notify();
40
+ }
41
+ removeRemotePeer(clientId) {
42
+ if (this.peers.delete(clientId)) {
43
+ this.notify();
44
+ }
45
+ }
46
+ getRemotePeers() {
47
+ this.pruneStalePeers();
48
+ return Array.from(this.peers.values());
49
+ }
50
+ pruneStalePeers(timeoutMs = 30000) {
51
+ const now = Date.now();
52
+ let changed = false;
53
+ for (const [id, peer] of this.peers.entries()) {
54
+ if (now - peer.lastActive > timeoutMs) {
55
+ this.peers.delete(id);
56
+ changed = true;
57
+ }
58
+ }
59
+ if (changed)
60
+ this.notify();
61
+ }
62
+ subscribe(listener) {
63
+ this.listeners.add(listener);
64
+ listener(this.getRemotePeers());
65
+ return () => {
66
+ this.listeners.delete(listener);
67
+ };
68
+ }
69
+ notify() {
70
+ const peers = this.getRemotePeers();
71
+ for (const listener of this.listeners) {
72
+ listener(peers);
73
+ }
74
+ }
75
+ }
76
+ //# sourceMappingURL=AwarenessState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AwarenessState.js","sourceRoot":"","sources":["../../src/collab/AwarenessState.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,OAAO,gBAAgB;IACX,aAAa,CAAS;IAC9B,SAAS,CAAW;IACpB,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;IACpC,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEjD,YAAY,QAAgB,EAAE,IAAI,GAAG,WAAW,EAAE,KAAK,GAAG,SAAS;QACjE,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG;YACf,QAAQ;YACR,IAAI;YACJ,KAAK;YACL,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;YAC9B,SAAS,EAAE,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;SACvB,CAAC;IACJ,CAAC;IAEM,aAAa,CAAC,MAAgB,EAAE,YAA0B,IAAI;QACnE,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/D,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEM,mBAAmB,CAAC,IAAY,EAAE,KAAa;QACpD,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEM,YAAY;QACjB,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC;IAEM,gBAAgB,CAAC,IAAc;QACpC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,aAAa;YAAE,OAAO;QACjD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAEM,gBAAgB,CAAC,QAAgB;QACtC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEM,cAAc;QACnB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAEM,eAAe,CAAC,SAAS,GAAG,KAAK;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9C,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,SAAS,EAAE,CAAC;gBACtC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,IAAI,OAAO;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC7B,CAAC;IAEM,SAAS,CAAC,QAA2B;QAC1C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAChC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC,CAAC;IACJ,CAAC;IAEO,MAAM;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,45 @@
1
+ import type { PieceTable } from "../buffer/PieceTable.js";
2
+ export interface CollabDelta {
3
+ type: "insert" | "delete";
4
+ from: number;
5
+ to?: number;
6
+ text?: string;
7
+ clientId: string;
8
+ clock: number;
9
+ }
10
+ export type CollabDeltaBroadcast = (delta: CollabDelta) => void;
11
+ /**
12
+ * Live Collaborative Editing CRDT Engine.
13
+ * Supports multi-client real-time synchronization with local undo isolation.
14
+ */
15
+ export declare class CollabProvider {
16
+ readonly clientId: string;
17
+ private clock;
18
+ private broadcast;
19
+ private localUndoStack;
20
+ private localRedoStack;
21
+ constructor(clientId: string, broadcast?: CollabDeltaBroadcast);
22
+ setBroadcast(broadcast: CollabDeltaBroadcast): void;
23
+ /**
24
+ * Apply a local edit initiated by the current user.
25
+ */
26
+ applyLocalInsert(doc: PieceTable, offset: number, text: string): CollabDelta;
27
+ /**
28
+ * Apply a local deletion initiated by the current user.
29
+ */
30
+ applyLocalDelete(doc: PieceTable, from: number, length: number): CollabDelta;
31
+ /**
32
+ * Ingest and apply a remote delta from another client.
33
+ * Remote edits do NOT pollute the local undo stack.
34
+ */
35
+ applyRemoteDelta(doc: PieceTable, delta: CollabDelta): void;
36
+ /**
37
+ * Revert the most recent edit made specifically by the local user.
38
+ */
39
+ undoLocal(doc: PieceTable): CollabDelta | null;
40
+ /**
41
+ * Redo the most recent undone local edit.
42
+ */
43
+ redoLocal(doc: PieceTable): CollabDelta | null;
44
+ }
45
+ //# sourceMappingURL=CollabProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollabProvider.d.ts","sourceRoot":"","sources":["../../src/collab/CollabProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAOhE;;;GAGG;AACH,qBAAa,cAAc;IACzB,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,cAAc,CAAyB;gBAEnC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,oBAAoB;IAKvD,YAAY,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAI1D;;OAEG;IACI,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW;IAkBnF;;OAEG;IACI,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW;IAmBnF;;;OAGG;IACI,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI;IAgBlE;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAqCrD;;OAEG;IACI,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;CAkCtD"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Live Collaborative Editing CRDT Engine.
3
+ * Supports multi-client real-time synchronization with local undo isolation.
4
+ */
5
+ export class CollabProvider {
6
+ clientId;
7
+ clock = 0;
8
+ broadcast = null;
9
+ localUndoStack = [];
10
+ localRedoStack = [];
11
+ constructor(clientId, broadcast) {
12
+ this.clientId = clientId;
13
+ if (broadcast)
14
+ this.broadcast = broadcast;
15
+ }
16
+ setBroadcast(broadcast) {
17
+ this.broadcast = broadcast;
18
+ }
19
+ /**
20
+ * Apply a local edit initiated by the current user.
21
+ */
22
+ applyLocalInsert(doc, offset, text) {
23
+ doc.insert(offset, text);
24
+ this.clock++;
25
+ const delta = {
26
+ type: "insert",
27
+ from: offset,
28
+ text,
29
+ clientId: this.clientId,
30
+ clock: this.clock,
31
+ };
32
+ this.localUndoStack.push({ delta });
33
+ this.localRedoStack = [];
34
+ this.broadcast?.(delta);
35
+ return delta;
36
+ }
37
+ /**
38
+ * Apply a local deletion initiated by the current user.
39
+ */
40
+ applyLocalDelete(doc, from, length) {
41
+ const deletedText = doc.getText(from, length);
42
+ doc.delete(from, length);
43
+ this.clock++;
44
+ const delta = {
45
+ type: "delete",
46
+ from,
47
+ to: from + length,
48
+ clientId: this.clientId,
49
+ clock: this.clock,
50
+ };
51
+ this.localUndoStack.push({ delta, revertedText: deletedText });
52
+ this.localRedoStack = [];
53
+ this.broadcast?.(delta);
54
+ return delta;
55
+ }
56
+ /**
57
+ * Ingest and apply a remote delta from another client.
58
+ * Remote edits do NOT pollute the local undo stack.
59
+ */
60
+ applyRemoteDelta(doc, delta) {
61
+ if (delta.clientId === this.clientId)
62
+ return;
63
+ this.clock = Math.max(this.clock, delta.clock) + 1;
64
+ if (delta.type === "insert" && delta.text) {
65
+ const safeFrom = Math.min(doc.length, delta.from);
66
+ doc.insert(safeFrom, delta.text);
67
+ }
68
+ else if (delta.type === "delete" && delta.to !== undefined) {
69
+ const safeFrom = Math.min(doc.length, delta.from);
70
+ const safeLen = Math.min(doc.length - safeFrom, delta.to - delta.from);
71
+ if (safeLen > 0) {
72
+ doc.delete(safeFrom, safeLen);
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Revert the most recent edit made specifically by the local user.
78
+ */
79
+ undoLocal(doc) {
80
+ const record = this.localUndoStack.pop();
81
+ if (!record)
82
+ return null;
83
+ let inverseDelta = null;
84
+ if (record.delta.type === "insert" && record.delta.text) {
85
+ // Revert insertion -> delete
86
+ const len = record.delta.text.length;
87
+ doc.delete(record.delta.from, len);
88
+ this.clock++;
89
+ inverseDelta = {
90
+ type: "delete",
91
+ from: record.delta.from,
92
+ to: record.delta.from + len,
93
+ clientId: this.clientId,
94
+ clock: this.clock,
95
+ };
96
+ }
97
+ else if (record.delta.type === "delete" && record.revertedText) {
98
+ // Revert deletion -> insert back
99
+ doc.insert(record.delta.from, record.revertedText);
100
+ this.clock++;
101
+ inverseDelta = {
102
+ type: "insert",
103
+ from: record.delta.from,
104
+ text: record.revertedText,
105
+ clientId: this.clientId,
106
+ clock: this.clock,
107
+ };
108
+ }
109
+ if (inverseDelta) {
110
+ this.localRedoStack.push(record);
111
+ this.broadcast?.(inverseDelta);
112
+ }
113
+ return inverseDelta;
114
+ }
115
+ /**
116
+ * Redo the most recent undone local edit.
117
+ */
118
+ redoLocal(doc) {
119
+ const record = this.localRedoStack.pop();
120
+ if (!record)
121
+ return null;
122
+ let delta = null;
123
+ if (record.delta.type === "insert" && record.delta.text) {
124
+ doc.insert(record.delta.from, record.delta.text);
125
+ this.clock++;
126
+ delta = {
127
+ type: "insert",
128
+ from: record.delta.from,
129
+ text: record.delta.text,
130
+ clientId: this.clientId,
131
+ clock: this.clock,
132
+ };
133
+ }
134
+ else if (record.delta.type === "delete" && record.delta.to) {
135
+ const len = record.delta.to - record.delta.from;
136
+ doc.delete(record.delta.from, len);
137
+ this.clock++;
138
+ delta = {
139
+ type: "delete",
140
+ from: record.delta.from,
141
+ to: record.delta.to,
142
+ clientId: this.clientId,
143
+ clock: this.clock,
144
+ };
145
+ }
146
+ if (delta) {
147
+ this.localUndoStack.push(record);
148
+ this.broadcast?.(delta);
149
+ }
150
+ return delta;
151
+ }
152
+ }
153
+ //# sourceMappingURL=CollabProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CollabProvider.js","sourceRoot":"","sources":["../../src/collab/CollabProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import type { Position, Range, Selection } from "./types.js";
2
+ /**
3
+ * Compute or retrieve cached line starts table for a given lines array.
4
+ */
5
+ export declare function computeLineStarts(lines: string[]): Uint32Array;
6
+ /**
7
+ * Convert 0-indexed (line, column) to character offset in full text.
8
+ */
9
+ export declare function positionToOffset(lines: string[], pos: Position): number;
10
+ /**
11
+ * Convert character offset to 0-indexed (line, column).
12
+ */
13
+ export declare function offsetToPosition(lines: string[], offset: number): Position;
14
+ export declare function isLeadSurrogate(code: number): boolean;
15
+ export declare function isTrailSurrogate(code: number): boolean;
16
+ /**
17
+ * Step one code point backward, keeping surrogate pairs (emoji, astral CJK)
18
+ * whole so backspace never leaves a lone surrogate behind.
19
+ */
20
+ export declare function stepBackCodePoint(text: string, offset: number): number;
21
+ /**
22
+ * Step one code point forward, keeping surrogate pairs whole so
23
+ * forward-delete never leaves a lone surrogate behind.
24
+ */
25
+ export declare function stepForwardCodePoint(text: string, offset: number): number;
26
+ /**
27
+ * Convert pixel (x, y) coordinates to (line, column) position.
28
+ */
29
+ export declare function pointToPosition(x: number, y: number, lineHeight: number, charWidth: number): Position;
30
+ /**
31
+ * Convert (line, column) position to pixel (x, y) coordinates.
32
+ */
33
+ export declare function positionToPoint(pos: Position, lineHeight: number, charWidth: number): {
34
+ x: number;
35
+ y: number;
36
+ };
37
+ /**
38
+ * Clamp a position to valid buffer bounds.
39
+ */
40
+ export declare function clampPosition(lines: string[] | {
41
+ length: number;
42
+ }, pos: Position): Position;
43
+ /**
44
+ * Check if two positions are equal.
45
+ */
46
+ export declare function arePositionsEqual(a: Position, b: Position): boolean;
47
+ /**
48
+ * Check if position a is strictly before or equal to position b.
49
+ */
50
+ export declare function isPositionBefore(a: Position, b: Position): boolean;
51
+ /**
52
+ * Normalize a Range ensuring start is before or equal to end.
53
+ */
54
+ export declare function normalizeRange(range: Range): Range;
55
+ /**
56
+ * Check if a position lies within a Range (inclusive).
57
+ */
58
+ export declare function isPositionInRange(pos: Position, range: Range): boolean;
59
+ /**
60
+ * Find the word boundaries at a given column in a line of text.
61
+ */
62
+ export declare function getWordRangeAt(lineText: string, line: number, column: number): Range;
63
+ /**
64
+ * Extract text within a given Range across lines.
65
+ */
66
+ export declare function getTextInRange(lines: string[], range: Range | null): string;
67
+ /**
68
+ * Convert a Selection (anchor + head) to a normalized Range (start <= end).
69
+ */
70
+ export declare function normalizeSelection(sel: Selection): Range;
71
+ /**
72
+ * Check if a selection is collapsed (anchor == head).
73
+ */
74
+ export declare function isSelectionCollapsed(sel: Selection): boolean;
75
+ /**
76
+ * Sort selections descending by maximum position (bottom-to-top, right-to-left).
77
+ * Necessary for multi-cursor mutations to avoid invalidating earlier offsets.
78
+ */
79
+ export declare function sortSelectionsDescending(selections: Selection[]): Selection[];
80
+ /**
81
+ * Remove duplicate cursors/selections.
82
+ */
83
+ export declare function deduplicateSelections(selections: Selection[]): Selection[];
84
+ export interface MultiEditResult {
85
+ newLines: string[];
86
+ newSelections: Selection[];
87
+ }
88
+ /**
89
+ * Apply text insertion across multiple cursors or selections in a single atomic pass.
90
+ */
91
+ export declare function applyMultiCursorInsert(lines: string[], selections: Selection[], insertText: string): MultiEditResult;
92
+ /**
93
+ * Apply deletion (backspace or forward delete) across multiple cursors or selections.
94
+ */
95
+ export declare function applyMultiCursorDelete(lines: string[], selections: Selection[], isForward: boolean): MultiEditResult;
96
+ /**
97
+ * Find word boundary in a line of text for word-by-word cursor navigation (Ctrl/Alt + Arrow).
98
+ */
99
+ export declare function findWordBoundary(lineText: string, column: number, direction: -1 | 1): number;
100
+ /**
101
+ * Toggle single-line comment on a range of lines.
102
+ */
103
+ export declare function toggleLinesComment(lines: string[], startLine: number, endLine: number, commentPrefix?: string): {
104
+ newLines: string[];
105
+ };
106
+ /**
107
+ * Check if the cursor is directly between an open/close bracket pair (e.g. `(|)`),
108
+ * in which case backspace should delete both characters.
109
+ */
110
+ export declare function isPairedBracketDelete(lineText: string, column: number): boolean;
111
+ /**
112
+ * Compute rectangular / column selection spanning across multiple lines from start to end position.
113
+ * Returns an array of Selections, one for each line in the rectangular bounding box.
114
+ */
115
+ export declare function computeColumnSelection(lines: string[], start: Position, end: Position): Selection[];
116
+ /**
117
+ * Compute column positions for vertical indent guides on a line of code.
118
+ */
119
+ export declare function computeIndentGuides(lineText: string, tabSize?: number): number[];
120
+ export interface RainbowBracket {
121
+ col: number;
122
+ depth: number;
123
+ char: string;
124
+ }
125
+ /**
126
+ * Calculate rainbow bracket nesting depths and column positions across a line.
127
+ */
128
+ export declare function computeRainbowBrackets(lineText: string, _language?: string, startDepth?: number): {
129
+ nextDepth: number;
130
+ brackets: RainbowBracket[];
131
+ };
132
+ //# sourceMappingURL=coordinates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../src/coordinates.ts"],"names":[],"mappings":"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"}