@vscode/markdown-editor 0.0.2-24 → 0.0.2-25
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/config-Dvgk17FF.js +282 -0
- package/dist/config-Dvgk17FF.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +110 -5
- package/dist/index.js +2553 -2113
- package/dist/index.js.map +1 -1
- package/dist/observables.js +2 -2
- package/dist/{runOnChange-CkxK2gSn.js → runOnChange-e7FtCqOQ.js} +40 -40
- package/dist/{runOnChange-CkxK2gSn.js.map → runOnChange-e7FtCqOQ.js.map} +1 -1
- package/package.json +12 -1
- package/src/view/editor.css +11 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
const S = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?", f = {
|
|
2
|
+
wordSeparators: S,
|
|
3
|
+
wordSegmenterLocales: []
|
|
4
|
+
};
|
|
5
|
+
class C {
|
|
6
|
+
_separators;
|
|
7
|
+
_segmenter;
|
|
8
|
+
_cachedLine;
|
|
9
|
+
_cachedWords = [];
|
|
10
|
+
constructor(n) {
|
|
11
|
+
this._separators = new Set(n.wordSeparators), this._segmenter = L(n.wordSegmenterLocales);
|
|
12
|
+
}
|
|
13
|
+
classify(n) {
|
|
14
|
+
return n === void 0 || n === " " || n === " " ? 1 : this._separators.has(n) ? 2 : 0;
|
|
15
|
+
}
|
|
16
|
+
previousIntlWord(n, i) {
|
|
17
|
+
let t;
|
|
18
|
+
for (const r of this._intlWords(n)) {
|
|
19
|
+
if (r.index > i)
|
|
20
|
+
break;
|
|
21
|
+
t = r;
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
}
|
|
25
|
+
nextIntlWord(n, i) {
|
|
26
|
+
return this._intlWords(n).find((t) => t.index >= i);
|
|
27
|
+
}
|
|
28
|
+
_intlWords(n) {
|
|
29
|
+
if (!this._segmenter)
|
|
30
|
+
return [];
|
|
31
|
+
if (this._cachedLine === n)
|
|
32
|
+
return this._cachedWords;
|
|
33
|
+
const i = [];
|
|
34
|
+
for (const t of this._segmenter.segment(n))
|
|
35
|
+
t.isWordLike && i.push({ index: t.index, segment: t.segment });
|
|
36
|
+
return this._cachedLine = n, this._cachedWords = i, i;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function L(e) {
|
|
40
|
+
if (e.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
const n = [];
|
|
43
|
+
for (const i of e) {
|
|
44
|
+
if (typeof i != "string" || i.length === 0) {
|
|
45
|
+
console.warn("Ignoring invalid editor.wordSegmenterLocales entry", i);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
n.push(...Intl.Segmenter.supportedLocalesOf(i));
|
|
50
|
+
} catch (t) {
|
|
51
|
+
console.warn(`Ignoring invalid editor.wordSegmenterLocales entry: ${i}`, t);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (n.length !== 0)
|
|
55
|
+
try {
|
|
56
|
+
return new Intl.Segmenter(n, { granularity: "word" });
|
|
57
|
+
} catch (i) {
|
|
58
|
+
console.warn(`Unable to initialize editor.wordSegmenterLocales: ${n.join(", ")}`, i);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const v = /* @__PURE__ */ new Map();
|
|
63
|
+
function W(e) {
|
|
64
|
+
const n = `${e.wordSeparators}/${e.wordSegmenterLocales.join(",")}`;
|
|
65
|
+
let i = v.get(n);
|
|
66
|
+
return i || (i = new C(e), v.set(n, i)), i;
|
|
67
|
+
}
|
|
68
|
+
function _(e, n, i = f) {
|
|
69
|
+
if (n = p(n, 0, e.length), n === 0)
|
|
70
|
+
return 0;
|
|
71
|
+
let t = e.lastIndexOf(`
|
|
72
|
+
`, n - 1) + 1, r = e.indexOf(`
|
|
73
|
+
`, n);
|
|
74
|
+
r === -1 && (r = e.length);
|
|
75
|
+
let s = n - t;
|
|
76
|
+
if (s === 0) {
|
|
77
|
+
const a = t - 1;
|
|
78
|
+
t = a <= 0 ? 0 : e.lastIndexOf(`
|
|
79
|
+
`, a - 1) + 1, r = a, s = Math.max(0, a - t);
|
|
80
|
+
}
|
|
81
|
+
const l = e.slice(t, r), d = W(i);
|
|
82
|
+
let o = y(l, d, s);
|
|
83
|
+
return o?.type === 1 && o.end - o.start === 1 && o.nextClass === 0 && (o = y(l, d, o.start)), t + (o?.start ?? 0);
|
|
84
|
+
}
|
|
85
|
+
function x(e, n, i = f) {
|
|
86
|
+
if (n = p(n, 0, e.length), n === e.length)
|
|
87
|
+
return e.length;
|
|
88
|
+
let t = e.lastIndexOf(`
|
|
89
|
+
`, n - 1) + 1, r = e.indexOf(`
|
|
90
|
+
`, n);
|
|
91
|
+
r === -1 && (r = e.length);
|
|
92
|
+
let s = n - t;
|
|
93
|
+
n === r && r < e.length && (t = r + 1, r = e.indexOf(`
|
|
94
|
+
`, t), r === -1 && (r = e.length), s = 0);
|
|
95
|
+
const l = e.slice(t, r), d = W(i);
|
|
96
|
+
let o = O(l, d, s);
|
|
97
|
+
return o?.type === 1 && o.end - o.start === 1 && o.nextClass === 0 && (o = O(l, d, o.end)), t + (o?.end ?? l.length);
|
|
98
|
+
}
|
|
99
|
+
function E(e, n, i = f) {
|
|
100
|
+
if (n = p(n, 0, e.length), n === 0)
|
|
101
|
+
return 0;
|
|
102
|
+
const t = n === 0 ? 0 : e.lastIndexOf(`
|
|
103
|
+
`, n - 1) + 1, r = n - t;
|
|
104
|
+
if (r === 0)
|
|
105
|
+
return n - 1;
|
|
106
|
+
let s = r - 1;
|
|
107
|
+
for (; s >= 0 && (e[t + s] === " " || e[t + s] === " "); )
|
|
108
|
+
s--;
|
|
109
|
+
if (s + 1 < r - 1)
|
|
110
|
+
return t + s + 1;
|
|
111
|
+
let l = e.indexOf(`
|
|
112
|
+
`, n);
|
|
113
|
+
l === -1 && (l = e.length);
|
|
114
|
+
const d = e.slice(t, l), o = y(d, W(i), r);
|
|
115
|
+
return t + (o?.start ?? 0);
|
|
116
|
+
}
|
|
117
|
+
function A(e, n, i = f) {
|
|
118
|
+
if (n = p(n, 0, e.length), n === e.length)
|
|
119
|
+
return e.length;
|
|
120
|
+
const t = e.lastIndexOf(`
|
|
121
|
+
`, n - 1) + 1;
|
|
122
|
+
let r = e.indexOf(`
|
|
123
|
+
`, n);
|
|
124
|
+
r === -1 && (r = e.length);
|
|
125
|
+
const s = n - t, l = e.slice(t, r);
|
|
126
|
+
let d = s;
|
|
127
|
+
for (; d < l.length && (l[d] === " " || l[d] === " "); )
|
|
128
|
+
d++;
|
|
129
|
+
if (s < d)
|
|
130
|
+
return t + d;
|
|
131
|
+
const o = W(i), a = O(l, o, s);
|
|
132
|
+
if (a)
|
|
133
|
+
return t + a.end;
|
|
134
|
+
if (n < r || r === e.length)
|
|
135
|
+
return r;
|
|
136
|
+
const h = r + 1;
|
|
137
|
+
let c = e.indexOf(`
|
|
138
|
+
`, h);
|
|
139
|
+
c === -1 && (c = e.length);
|
|
140
|
+
const u = e.slice(h, c), g = O(u, o, 0);
|
|
141
|
+
return h + (g?.start ?? u.length);
|
|
142
|
+
}
|
|
143
|
+
function D(e, n, i = f) {
|
|
144
|
+
if (n = p(n, 0, e.length), n === e.length)
|
|
145
|
+
return { start: n, end: n };
|
|
146
|
+
const t = e[n];
|
|
147
|
+
if (/\s/u.test(t)) {
|
|
148
|
+
let g = n, m = n + 1;
|
|
149
|
+
for (; g > 0 && /\s/u.test(e[g - 1]); )
|
|
150
|
+
g--;
|
|
151
|
+
for (; m < e.length && /\s/u.test(e[m]); )
|
|
152
|
+
m++;
|
|
153
|
+
return { start: g, end: m };
|
|
154
|
+
}
|
|
155
|
+
const r = e.lastIndexOf(`
|
|
156
|
+
`, n - 1) + 1;
|
|
157
|
+
let s = e.indexOf(`
|
|
158
|
+
`, n);
|
|
159
|
+
s === -1 && (s = e.length);
|
|
160
|
+
const l = e.slice(r, s), d = n - r, o = W(i), a = o.previousIntlWord(l, d);
|
|
161
|
+
if (a && d < a.index + a.segment.length)
|
|
162
|
+
return {
|
|
163
|
+
start: r + a.index,
|
|
164
|
+
end: r + a.index + a.segment.length
|
|
165
|
+
};
|
|
166
|
+
const h = o.classify(t);
|
|
167
|
+
let c = d, u = d + 1;
|
|
168
|
+
for (; c > 0 && o.classify(l[c - 1]) === h; )
|
|
169
|
+
c--;
|
|
170
|
+
for (; u < l.length && o.classify(l[u]) === h; )
|
|
171
|
+
u++;
|
|
172
|
+
return { start: r + c, end: r + u };
|
|
173
|
+
}
|
|
174
|
+
function y(e, n, i) {
|
|
175
|
+
let t;
|
|
176
|
+
const r = n.previousIntlWord(e, i - 1);
|
|
177
|
+
for (let s = i - 1; s >= 0; s--) {
|
|
178
|
+
const l = n.classify(e[s]);
|
|
179
|
+
if (r && s === r.index)
|
|
180
|
+
return {
|
|
181
|
+
start: r.index,
|
|
182
|
+
end: r.index + r.segment.length,
|
|
183
|
+
type: 0,
|
|
184
|
+
nextClass: l
|
|
185
|
+
};
|
|
186
|
+
if (l === 0) {
|
|
187
|
+
if (t === 1) {
|
|
188
|
+
const d = s + 1;
|
|
189
|
+
return { start: d, end: w(e, n, t, d), type: t, nextClass: l };
|
|
190
|
+
}
|
|
191
|
+
t = 0;
|
|
192
|
+
} else if (l === 2) {
|
|
193
|
+
if (t === 0) {
|
|
194
|
+
const d = s + 1;
|
|
195
|
+
return { start: d, end: w(e, n, t, d), type: t, nextClass: l };
|
|
196
|
+
}
|
|
197
|
+
t = 1;
|
|
198
|
+
} else if (t !== void 0) {
|
|
199
|
+
const d = s + 1;
|
|
200
|
+
return { start: d, end: w(e, n, t, d), type: t, nextClass: l };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return t === void 0 ? void 0 : {
|
|
204
|
+
start: 0,
|
|
205
|
+
end: w(e, n, t, 0),
|
|
206
|
+
type: t,
|
|
207
|
+
nextClass: 1
|
|
208
|
+
/* Whitespace */
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function O(e, n, i) {
|
|
212
|
+
let t;
|
|
213
|
+
const r = n.nextIntlWord(e, i);
|
|
214
|
+
for (let s = i; s < e.length; s++) {
|
|
215
|
+
const l = n.classify(e[s]);
|
|
216
|
+
if (r && s === r.index)
|
|
217
|
+
return {
|
|
218
|
+
start: r.index,
|
|
219
|
+
end: r.index + r.segment.length,
|
|
220
|
+
type: 0,
|
|
221
|
+
nextClass: l
|
|
222
|
+
};
|
|
223
|
+
if (l === 0) {
|
|
224
|
+
if (t === 1) {
|
|
225
|
+
const d = s;
|
|
226
|
+
return { start: I(e, n, t, d - 1), end: d, type: t, nextClass: l };
|
|
227
|
+
}
|
|
228
|
+
t = 0;
|
|
229
|
+
} else if (l === 2) {
|
|
230
|
+
if (t === 0) {
|
|
231
|
+
const d = s;
|
|
232
|
+
return { start: I(e, n, t, d - 1), end: d, type: t, nextClass: l };
|
|
233
|
+
}
|
|
234
|
+
t = 1;
|
|
235
|
+
} else if (t !== void 0) {
|
|
236
|
+
const d = s;
|
|
237
|
+
return { start: I(e, n, t, d - 1), end: d, type: t, nextClass: l };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return t === void 0 ? void 0 : {
|
|
241
|
+
start: I(e, n, t, e.length - 1),
|
|
242
|
+
end: e.length,
|
|
243
|
+
type: t,
|
|
244
|
+
nextClass: 1
|
|
245
|
+
/* Whitespace */
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function w(e, n, i, t) {
|
|
249
|
+
const r = n.nextIntlWord(e, t);
|
|
250
|
+
for (let s = t; s < e.length; s++) {
|
|
251
|
+
if (r && s === r.index + r.segment.length)
|
|
252
|
+
return s;
|
|
253
|
+
const l = n.classify(e[s]);
|
|
254
|
+
if (l === 1 || i === 0 && l === 2 || i === 1 && l === 0)
|
|
255
|
+
return s;
|
|
256
|
+
}
|
|
257
|
+
return e.length;
|
|
258
|
+
}
|
|
259
|
+
function I(e, n, i, t) {
|
|
260
|
+
const r = n.previousIntlWord(e, t);
|
|
261
|
+
for (let s = t; s >= 0; s--) {
|
|
262
|
+
if (r && s === r.index)
|
|
263
|
+
return s;
|
|
264
|
+
const l = n.classify(e[s]);
|
|
265
|
+
if (l === 1 || i === 0 && l === 2 || i === 1 && l === 0)
|
|
266
|
+
return s + 1;
|
|
267
|
+
}
|
|
268
|
+
return 0;
|
|
269
|
+
}
|
|
270
|
+
function p(e, n, i) {
|
|
271
|
+
return Math.min(Math.max(e, n), i);
|
|
272
|
+
}
|
|
273
|
+
export {
|
|
274
|
+
f as D,
|
|
275
|
+
x as a,
|
|
276
|
+
E as b,
|
|
277
|
+
A as c,
|
|
278
|
+
D as d,
|
|
279
|
+
S as e,
|
|
280
|
+
_ as f
|
|
281
|
+
};
|
|
282
|
+
//# sourceMappingURL=config-Dvgk17FF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-Dvgk17FF.js","sources":["../src/core/wordUtils.ts"],"sourcesContent":["export const DEFAULT_WORD_SEPARATORS = '`~!@#$%^&*()-=+[{]}\\\\|;:\\'\",.<>/?';\n\nexport interface WordNavigationConfig {\n\treadonly wordSeparators: string;\n\treadonly wordSegmenterLocales: readonly string[];\n}\n\nexport const DEFAULT_WORD_NAVIGATION_CONFIG: WordNavigationConfig = {\n\twordSeparators: DEFAULT_WORD_SEPARATORS,\n\twordSegmenterLocales: [],\n};\n\nconst enum WordCharacterClass {\n\tRegular,\n\tWhitespace,\n\tSeparator,\n}\n\nconst enum WordType {\n\tRegular,\n\tSeparator,\n}\n\ninterface WordSpan {\n\treadonly start: number;\n\treadonly end: number;\n\treadonly type: WordType;\n\treadonly nextClass: WordCharacterClass;\n}\n\ninterface IntlWordSpan {\n\treadonly index: number;\n\treadonly segment: string;\n}\n\nclass WordClassifier {\n\tprivate readonly _separators: ReadonlySet<string>;\n\tprivate readonly _segmenter: Intl.Segmenter | undefined;\n\tprivate _cachedLine: string | undefined;\n\tprivate _cachedWords: readonly IntlWordSpan[] = [];\n\n\tconstructor(config: WordNavigationConfig) {\n\t\tthis._separators = new Set(config.wordSeparators);\n\t\tthis._segmenter = createWordSegmenter(config.wordSegmenterLocales);\n\t}\n\n\tclassify(character: string | undefined): WordCharacterClass {\n\t\tif (character === undefined) {\n\t\t\treturn WordCharacterClass.Whitespace;\n\t\t}\n\t\tif (character === ' ' || character === '\\t') {\n\t\t\treturn WordCharacterClass.Whitespace;\n\t\t}\n\t\treturn this._separators.has(character)\n\t\t\t? WordCharacterClass.Separator\n\t\t\t: WordCharacterClass.Regular;\n\t}\n\n\tpreviousIntlWord(line: string, offset: number): IntlWordSpan | undefined {\n\t\tlet candidate: IntlWordSpan | undefined;\n\t\tfor (const word of this._intlWords(line)) {\n\t\t\tif (word.index > offset) { break; }\n\t\t\tcandidate = word;\n\t\t}\n\t\treturn candidate;\n\t}\n\n\tnextIntlWord(line: string, offset: number): IntlWordSpan | undefined {\n\t\treturn this._intlWords(line).find(word => word.index >= offset);\n\t}\n\n\tprivate _intlWords(line: string): readonly IntlWordSpan[] {\n\t\tif (!this._segmenter) { return []; }\n\t\tif (this._cachedLine === line) { return this._cachedWords; }\n\n\t\tconst words: IntlWordSpan[] = [];\n\t\tfor (const segment of this._segmenter.segment(line)) {\n\t\t\tif (segment.isWordLike) {\n\t\t\t\twords.push({ index: segment.index, segment: segment.segment });\n\t\t\t}\n\t\t}\n\t\tthis._cachedLine = line;\n\t\tthis._cachedWords = words;\n\t\treturn words;\n\t}\n}\n\nfunction createWordSegmenter(locales: readonly string[]): Intl.Segmenter | undefined {\n\tif (locales.length === 0) { return undefined; }\n\tconst supportedLocales: string[] = [];\n\tfor (const locale of locales as readonly unknown[]) {\n\t\tif (typeof locale !== 'string' || locale.length === 0) {\n\t\t\tconsole.warn('Ignoring invalid editor.wordSegmenterLocales entry', locale);\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tsupportedLocales.push(...Intl.Segmenter.supportedLocalesOf(locale));\n\t\t} catch (error) {\n\t\t\tconsole.warn(`Ignoring invalid editor.wordSegmenterLocales entry: ${locale}`, error);\n\t\t}\n\t}\n\tif (supportedLocales.length === 0) { return undefined; }\n\ttry {\n\t\treturn new Intl.Segmenter(supportedLocales, { granularity: 'word' });\n\t} catch (error) {\n\t\tconsole.warn(`Unable to initialize editor.wordSegmenterLocales: ${supportedLocales.join(', ')}`, error);\n\t\treturn undefined;\n\t}\n}\n\nconst classifierCache = new Map<string, WordClassifier>();\n\nfunction getClassifier(config: WordNavigationConfig): WordClassifier {\n\tconst key = `${config.wordSeparators}/${config.wordSegmenterLocales.join(',')}`;\n\tlet classifier = classifierCache.get(key);\n\tif (!classifier) {\n\t\tclassifier = new WordClassifier(config);\n\t\tclassifierCache.set(key, classifier);\n\t}\n\treturn classifier;\n}\n\nexport function findWordBoundaryLeft(\n\ttext: string,\n\toffset: number,\n\tconfig: WordNavigationConfig = DEFAULT_WORD_NAVIGATION_CONFIG,\n): number {\n\toffset = clamp(offset, 0, text.length);\n\tif (offset === 0) { return 0; }\n\n\tlet lineStart = text.lastIndexOf('\\n', offset - 1) + 1;\n\tlet lineEnd = text.indexOf('\\n', offset);\n\tif (lineEnd === -1) { lineEnd = text.length; }\n\tlet localOffset = offset - lineStart;\n\tif (localOffset === 0) {\n\t\tconst previousLineEnd = lineStart - 1;\n\t\tlineStart = previousLineEnd <= 0\n\t\t\t? 0\n\t\t\t: text.lastIndexOf('\\n', previousLineEnd - 1) + 1;\n\t\tlineEnd = previousLineEnd;\n\t\tlocalOffset = Math.max(0, previousLineEnd - lineStart);\n\t}\n\n\tconst line = text.slice(lineStart, lineEnd);\n\tconst classifier = getClassifier(config);\n\tlet previous = findPreviousWord(line, classifier, localOffset);\n\tif (\n\t\tprevious?.type === WordType.Separator\n\t\t&& previous.end - previous.start === 1\n\t\t&& previous.nextClass === WordCharacterClass.Regular\n\t) {\n\t\tprevious = findPreviousWord(line, classifier, previous.start);\n\t}\n\treturn lineStart + (previous?.start ?? 0);\n}\n\nexport function findWordBoundaryRight(\n\ttext: string,\n\toffset: number,\n\tconfig: WordNavigationConfig = DEFAULT_WORD_NAVIGATION_CONFIG,\n): number {\n\toffset = clamp(offset, 0, text.length);\n\tif (offset === text.length) { return text.length; }\n\n\tlet lineStart = text.lastIndexOf('\\n', offset - 1) + 1;\n\tlet lineEnd = text.indexOf('\\n', offset);\n\tif (lineEnd === -1) { lineEnd = text.length; }\n\tlet localOffset = offset - lineStart;\n\tif (offset === lineEnd && lineEnd < text.length) {\n\t\tlineStart = lineEnd + 1;\n\t\tlineEnd = text.indexOf('\\n', lineStart);\n\t\tif (lineEnd === -1) { lineEnd = text.length; }\n\t\tlocalOffset = 0;\n\t}\n\n\tconst line = text.slice(lineStart, lineEnd);\n\tconst classifier = getClassifier(config);\n\tlet next = findNextWord(line, classifier, localOffset);\n\tif (\n\t\tnext?.type === WordType.Separator\n\t\t&& next.end - next.start === 1\n\t\t&& next.nextClass === WordCharacterClass.Regular\n\t) {\n\t\tnext = findNextWord(line, classifier, next.end);\n\t}\n\treturn lineStart + (next?.end ?? line.length);\n}\n\nexport function findWordDeleteBoundaryLeft(\n\ttext: string,\n\toffset: number,\n\tconfig: WordNavigationConfig = DEFAULT_WORD_NAVIGATION_CONFIG,\n): number {\n\toffset = clamp(offset, 0, text.length);\n\tif (offset === 0) { return 0; }\n\n\tconst lineStart = offset === 0 ? 0 : text.lastIndexOf('\\n', offset - 1) + 1;\n\tconst localOffset = offset - lineStart;\n\tif (localOffset === 0) {\n\t\treturn offset - 1;\n\t}\n\n\tlet lastNonWhitespace = localOffset - 1;\n\twhile (\n\t\tlastNonWhitespace >= 0\n\t\t&& (text[lineStart + lastNonWhitespace] === ' ' || text[lineStart + lastNonWhitespace] === '\\t')\n\t) {\n\t\tlastNonWhitespace--;\n\t}\n\tif (lastNonWhitespace + 1 < localOffset - 1) {\n\t\treturn lineStart + lastNonWhitespace + 1;\n\t}\n\n\tlet lineEnd = text.indexOf('\\n', offset);\n\tif (lineEnd === -1) { lineEnd = text.length; }\n\tconst line = text.slice(lineStart, lineEnd);\n\tconst previous = findPreviousWord(line, getClassifier(config), localOffset);\n\treturn lineStart + (previous?.start ?? 0);\n}\n\nexport function findWordDeleteBoundaryRight(\n\ttext: string,\n\toffset: number,\n\tconfig: WordNavigationConfig = DEFAULT_WORD_NAVIGATION_CONFIG,\n): number {\n\toffset = clamp(offset, 0, text.length);\n\tif (offset === text.length) { return text.length; }\n\n\tconst lineStart = text.lastIndexOf('\\n', offset - 1) + 1;\n\tlet lineEnd = text.indexOf('\\n', offset);\n\tif (lineEnd === -1) { lineEnd = text.length; }\n\tconst localOffset = offset - lineStart;\n\tconst line = text.slice(lineStart, lineEnd);\n\n\tlet firstNonWhitespace = localOffset;\n\twhile (\n\t\tfirstNonWhitespace < line.length\n\t\t&& (line[firstNonWhitespace] === ' ' || line[firstNonWhitespace] === '\\t')\n\t) {\n\t\tfirstNonWhitespace++;\n\t}\n\tif (localOffset < firstNonWhitespace) {\n\t\treturn lineStart + firstNonWhitespace;\n\t}\n\n\tconst classifier = getClassifier(config);\n\tconst next = findNextWord(line, classifier, localOffset);\n\tif (next) {\n\t\treturn lineStart + next.end;\n\t}\n\tif (offset < lineEnd || lineEnd === text.length) {\n\t\treturn lineEnd;\n\t}\n\n\tconst nextLineStart = lineEnd + 1;\n\tlet nextLineEnd = text.indexOf('\\n', nextLineStart);\n\tif (nextLineEnd === -1) { nextLineEnd = text.length; }\n\tconst nextLine = text.slice(nextLineStart, nextLineEnd);\n\tconst nextLineWord = findNextWord(nextLine, classifier, 0);\n\treturn nextLineStart + (nextLineWord?.start ?? nextLine.length);\n}\n\nexport function findWordAt(\n\ttext: string,\n\toffset: number,\n\tconfig: WordNavigationConfig = DEFAULT_WORD_NAVIGATION_CONFIG,\n): { start: number; end: number } {\n\toffset = clamp(offset, 0, text.length);\n\tif (offset === text.length) {\n\t\treturn { start: offset, end: offset };\n\t}\n\n\tconst character = text[offset];\n\tif (/\\s/u.test(character)) {\n\t\tlet start = offset;\n\t\tlet end = offset + 1;\n\t\twhile (start > 0 && /\\s/u.test(text[start - 1])) { start--; }\n\t\twhile (end < text.length && /\\s/u.test(text[end])) { end++; }\n\t\treturn { start, end };\n\t}\n\n\tconst lineStart = text.lastIndexOf('\\n', offset - 1) + 1;\n\tlet lineEnd = text.indexOf('\\n', offset);\n\tif (lineEnd === -1) { lineEnd = text.length; }\n\tconst line = text.slice(lineStart, lineEnd);\n\tconst localOffset = offset - lineStart;\n\tconst classifier = getClassifier(config);\n\n\tconst intlWord = classifier.previousIntlWord(line, localOffset);\n\tif (intlWord && localOffset < intlWord.index + intlWord.segment.length) {\n\t\treturn {\n\t\t\tstart: lineStart + intlWord.index,\n\t\t\tend: lineStart + intlWord.index + intlWord.segment.length,\n\t\t};\n\t}\n\n\tconst characterClass = classifier.classify(character);\n\tlet start = localOffset;\n\tlet end = localOffset + 1;\n\twhile (start > 0 && classifier.classify(line[start - 1]) === characterClass) { start--; }\n\twhile (end < line.length && classifier.classify(line[end]) === characterClass) { end++; }\n\treturn { start: lineStart + start, end: lineStart + end };\n}\n\nfunction findPreviousWord(line: string, classifier: WordClassifier, offset: number): WordSpan | undefined {\n\tlet type: WordType | undefined;\n\tconst previousIntlWord = classifier.previousIntlWord(line, offset - 1);\n\n\tfor (let index = offset - 1; index >= 0; index--) {\n\t\tconst characterClass = classifier.classify(line[index]);\n\t\tif (previousIntlWord && index === previousIntlWord.index) {\n\t\t\treturn {\n\t\t\t\tstart: previousIntlWord.index,\n\t\t\t\tend: previousIntlWord.index + previousIntlWord.segment.length,\n\t\t\t\ttype: WordType.Regular,\n\t\t\t\tnextClass: characterClass,\n\t\t\t};\n\t\t}\n\n\t\tif (characterClass === WordCharacterClass.Regular) {\n\t\t\tif (type === WordType.Separator) {\n\t\t\t\tconst start = index + 1;\n\t\t\t\treturn { start, end: findWordEnd(line, classifier, type, start), type, nextClass: characterClass };\n\t\t\t}\n\t\t\ttype = WordType.Regular;\n\t\t} else if (characterClass === WordCharacterClass.Separator) {\n\t\t\tif (type === WordType.Regular) {\n\t\t\t\tconst start = index + 1;\n\t\t\t\treturn { start, end: findWordEnd(line, classifier, type, start), type, nextClass: characterClass };\n\t\t\t}\n\t\t\ttype = WordType.Separator;\n\t\t} else if (type !== undefined) {\n\t\t\tconst start = index + 1;\n\t\t\treturn { start, end: findWordEnd(line, classifier, type, start), type, nextClass: characterClass };\n\t\t}\n\t}\n\n\treturn type === undefined\n\t\t? undefined\n\t\t: { start: 0, end: findWordEnd(line, classifier, type, 0), type, nextClass: WordCharacterClass.Whitespace };\n}\n\nfunction findNextWord(line: string, classifier: WordClassifier, offset: number): WordSpan | undefined {\n\tlet type: WordType | undefined;\n\tconst nextIntlWord = classifier.nextIntlWord(line, offset);\n\n\tfor (let index = offset; index < line.length; index++) {\n\t\tconst characterClass = classifier.classify(line[index]);\n\t\tif (nextIntlWord && index === nextIntlWord.index) {\n\t\t\treturn {\n\t\t\t\tstart: nextIntlWord.index,\n\t\t\t\tend: nextIntlWord.index + nextIntlWord.segment.length,\n\t\t\t\ttype: WordType.Regular,\n\t\t\t\tnextClass: characterClass,\n\t\t\t};\n\t\t}\n\n\t\tif (characterClass === WordCharacterClass.Regular) {\n\t\t\tif (type === WordType.Separator) {\n\t\t\t\tconst end = index;\n\t\t\t\treturn { start: findWordStart(line, classifier, type, end - 1), end, type, nextClass: characterClass };\n\t\t\t}\n\t\t\ttype = WordType.Regular;\n\t\t} else if (characterClass === WordCharacterClass.Separator) {\n\t\t\tif (type === WordType.Regular) {\n\t\t\t\tconst end = index;\n\t\t\t\treturn { start: findWordStart(line, classifier, type, end - 1), end, type, nextClass: characterClass };\n\t\t\t}\n\t\t\ttype = WordType.Separator;\n\t\t} else if (type !== undefined) {\n\t\t\tconst end = index;\n\t\t\treturn { start: findWordStart(line, classifier, type, end - 1), end, type, nextClass: characterClass };\n\t\t}\n\t}\n\n\treturn type === undefined\n\t\t? undefined\n\t\t: {\n\t\t\tstart: findWordStart(line, classifier, type, line.length - 1),\n\t\t\tend: line.length,\n\t\t\ttype,\n\t\t\tnextClass: WordCharacterClass.Whitespace,\n\t\t};\n}\n\nfunction findWordEnd(line: string, classifier: WordClassifier, type: WordType, start: number): number {\n\tconst nextIntlWord = classifier.nextIntlWord(line, start);\n\tfor (let index = start; index < line.length; index++) {\n\t\tif (nextIntlWord && index === nextIntlWord.index + nextIntlWord.segment.length) {\n\t\t\treturn index;\n\t\t}\n\t\tconst characterClass = classifier.classify(line[index]);\n\t\tif (\n\t\t\tcharacterClass === WordCharacterClass.Whitespace\n\t\t\t|| (type === WordType.Regular && characterClass === WordCharacterClass.Separator)\n\t\t\t|| (type === WordType.Separator && characterClass === WordCharacterClass.Regular)\n\t\t) {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn line.length;\n}\n\nfunction findWordStart(line: string, classifier: WordClassifier, type: WordType, start: number): number {\n\tconst previousIntlWord = classifier.previousIntlWord(line, start);\n\tfor (let index = start; index >= 0; index--) {\n\t\tif (previousIntlWord && index === previousIntlWord.index) {\n\t\t\treturn index;\n\t\t}\n\t\tconst characterClass = classifier.classify(line[index]);\n\t\tif (\n\t\t\tcharacterClass === WordCharacterClass.Whitespace\n\t\t\t|| (type === WordType.Regular && characterClass === WordCharacterClass.Separator)\n\t\t\t|| (type === WordType.Separator && characterClass === WordCharacterClass.Regular)\n\t\t) {\n\t\t\treturn index + 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(Math.max(value, min), max);\n}\n"],"names":["DEFAULT_WORD_SEPARATORS","DEFAULT_WORD_NAVIGATION_CONFIG","WordClassifier","config","createWordSegmenter","character","line","offset","candidate","word","words","segment","locales","supportedLocales","locale","error","classifierCache","getClassifier","key","classifier","findWordBoundaryLeft","text","clamp","lineStart","lineEnd","localOffset","previousLineEnd","previous","findPreviousWord","findWordBoundaryRight","next","findNextWord","findWordDeleteBoundaryLeft","lastNonWhitespace","findWordDeleteBoundaryRight","firstNonWhitespace","nextLineStart","nextLineEnd","nextLine","nextLineWord","findWordAt","start","end","intlWord","characterClass","type","previousIntlWord","index","findWordEnd","nextIntlWord","findWordStart","value","min","max"],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const DEFAULT_WORD_NAVIGATION_CONFIG: WordNavigationConfig;
|
|
2
|
+
|
|
3
|
+
export declare const DEFAULT_WORD_SEPARATORS = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?";
|
|
4
|
+
|
|
5
|
+
export declare interface WordNavigationConfig {
|
|
6
|
+
readonly wordSeparators: string;
|
|
7
|
+
readonly wordSegmenterLocales: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { }
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/index.d.ts
CHANGED
|
@@ -575,6 +575,8 @@ export declare interface CursorCommandContext {
|
|
|
575
575
|
readonly selection: Selection_2;
|
|
576
576
|
readonly document: DocumentAstNode;
|
|
577
577
|
readonly activeBlock: BlockAstNode | undefined;
|
|
578
|
+
readonly markerVisibleBlocks: ReadonlySet<BlockAstNode>;
|
|
579
|
+
readonly wordNavigationConfig: WordNavigationConfig;
|
|
578
580
|
}
|
|
579
581
|
|
|
580
582
|
export declare const cursorDocumentEnd: CursorCommand;
|
|
@@ -583,6 +585,8 @@ export declare const cursorDocumentStart: CursorCommand;
|
|
|
583
585
|
|
|
584
586
|
export declare const cursorDown: VisualCursorCommand;
|
|
585
587
|
|
|
588
|
+
export declare type CursorKeyboardAction = 'left' | 'right' | 'up' | 'down' | 'wordLeft' | 'wordRight' | 'visualLineStart' | 'visualLineEnd' | 'logicalLineStart' | 'logicalLineEnd' | 'documentStart' | 'documentEnd';
|
|
589
|
+
|
|
586
590
|
export declare const cursorLeft: CursorCommand;
|
|
587
591
|
|
|
588
592
|
export declare const cursorLineEnd: CursorCommand;
|
|
@@ -642,12 +646,24 @@ export declare class CursorViewRendering {
|
|
|
642
646
|
constructor(offset: SourceOffset, visible: boolean, rect: Rect2D);
|
|
643
647
|
}
|
|
644
648
|
|
|
649
|
+
export declare const cursorVisualLineEnd: VisualCursorCommand;
|
|
650
|
+
|
|
651
|
+
export declare const cursorVisualLineStart: VisualCursorCommand;
|
|
652
|
+
|
|
645
653
|
export declare const cursorWordLeft: CursorCommand;
|
|
646
654
|
|
|
647
655
|
export declare const cursorWordRight: CursorCommand;
|
|
648
656
|
|
|
657
|
+
export declare const DEFAULT_WORD_NAVIGATION_CONFIG: WordNavigationConfig;
|
|
658
|
+
|
|
659
|
+
export declare const DEFAULT_WORD_SEPARATORS = "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?";
|
|
660
|
+
|
|
649
661
|
export declare const deleteLeft: EditCommand;
|
|
650
662
|
|
|
663
|
+
export declare const deleteLineLeft: EditCommand;
|
|
664
|
+
|
|
665
|
+
export declare const deleteLineRight: EditCommand;
|
|
666
|
+
|
|
651
667
|
export declare const deleteRight: EditCommand;
|
|
652
668
|
|
|
653
669
|
export declare const deleteWordLeft: EditCommand;
|
|
@@ -839,6 +855,8 @@ export declare type EditCommand = (ctx: CursorCommandContext) => {
|
|
|
839
855
|
readonly selection: Selection_2;
|
|
840
856
|
} | undefined;
|
|
841
857
|
|
|
858
|
+
export declare type EditKeyboardAction = 'deleteLeft' | 'deleteRight' | 'deleteWordLeft' | 'deleteWordRight' | 'deleteLineLeft' | 'deleteLineRight';
|
|
859
|
+
|
|
842
860
|
/**
|
|
843
861
|
* Translates raw browser input (mouse, keyboard, EditContext) into model
|
|
844
862
|
* mutations. Knows about DOM event types but never reads/writes the DOM
|
|
@@ -855,6 +873,8 @@ export declare class EditorController extends Disposable {
|
|
|
855
873
|
private readonly _model;
|
|
856
874
|
private readonly _view;
|
|
857
875
|
private _desiredColumn;
|
|
876
|
+
private readonly _keyboardPlatform;
|
|
877
|
+
private readonly _keyboardProfile;
|
|
858
878
|
/** Running click count for the current multi-click sequence (1, 2, 3, …). */
|
|
859
879
|
private _clickCount;
|
|
860
880
|
/** Timestamp and position of the previous pointer-down, for multi-click detection. */
|
|
@@ -874,7 +894,27 @@ export declare class EditorController extends Disposable {
|
|
|
874
894
|
private _selectedText;
|
|
875
895
|
private readonly _updateModifierState;
|
|
876
896
|
private readonly _clearModifierState;
|
|
897
|
+
/**
|
|
898
|
+
* Drop any native DOM selection over the rendered text.
|
|
899
|
+
*
|
|
900
|
+
* The editor paints selection from `model.selection`, so a browser
|
|
901
|
+
* selection there is always spurious: nothing reads it (copy/cut read the
|
|
902
|
+
* model, hit-testing uses the measured layout) and nothing clears it, so it
|
|
903
|
+
* lingers as a second highlight even after the caret moves away.
|
|
904
|
+
* {@link isCaretMotionKey} stops the common source synchronously; this is
|
|
905
|
+
* the backstop for the rest of the browser's editing commands, which are
|
|
906
|
+
* platform- and version-specific and cannot be enumerated (Shift+PageDown
|
|
907
|
+
* and macOS Shift+Ctrl+B both reach one today).
|
|
908
|
+
*
|
|
909
|
+
* Scoped twice so it only ever discards selections the editor owns: the
|
|
910
|
+
* range must touch the rendered text (overlays such as comment widgets sit
|
|
911
|
+
* beside it and stay selectable), and input focus must still be inside this
|
|
912
|
+
* editor (so a host find-in-page, which selects while its own input is
|
|
913
|
+
* focused, is left alone).
|
|
914
|
+
*/
|
|
915
|
+
private readonly _discardNativeSelection;
|
|
877
916
|
private readonly _handleKeyDown;
|
|
917
|
+
private _executeKeyboardAction;
|
|
878
918
|
/**
|
|
879
919
|
* Context-aware Enter: splits / line-breaks via {@link insertSmartEnter}, or
|
|
880
920
|
* arms a transient empty paragraph when at the end of a paragraph.
|
|
@@ -890,6 +930,8 @@ export declare interface EditorControllerOptions {
|
|
|
890
930
|
* strategy (e.g. `AsyncClipboardStrategy`) in hosts that swallow them.
|
|
891
931
|
*/
|
|
892
932
|
readonly clipboardStrategy?: IClipboardStrategy;
|
|
933
|
+
readonly keyboardPlatform?: KeyboardPlatform;
|
|
934
|
+
readonly keyboardProfile?: KeyboardProfile;
|
|
893
935
|
}
|
|
894
936
|
|
|
895
937
|
/**
|
|
@@ -920,6 +962,20 @@ export declare class EditorCoordinateTransform {
|
|
|
920
962
|
private _convertRect;
|
|
921
963
|
}
|
|
922
964
|
|
|
965
|
+
export declare type EditorKeyboardAction = {
|
|
966
|
+
readonly kind: 'cursor';
|
|
967
|
+
readonly command: CursorKeyboardAction;
|
|
968
|
+
readonly extend: boolean;
|
|
969
|
+
} | {
|
|
970
|
+
readonly kind: 'edit';
|
|
971
|
+
readonly command: EditKeyboardAction;
|
|
972
|
+
} | {
|
|
973
|
+
readonly kind: 'selectAll';
|
|
974
|
+
} | {
|
|
975
|
+
readonly kind: 'enter';
|
|
976
|
+
readonly command: 'smartEnter' | 'insertParagraph' | 'insertHardLineBreak';
|
|
977
|
+
};
|
|
978
|
+
|
|
923
979
|
export declare class EditorModel {
|
|
924
980
|
private readonly _parser;
|
|
925
981
|
/**
|
|
@@ -930,6 +986,7 @@ export declare class EditorModel {
|
|
|
930
986
|
*/
|
|
931
987
|
private _pendingEdit;
|
|
932
988
|
readonly sourceText: ISettableObservable<StringValue, void>;
|
|
989
|
+
readonly wordNavigationConfig: ISettableObservable<WordNavigationConfig, void>;
|
|
933
990
|
/**
|
|
934
991
|
* Read-only mode. When `true`, the editor never reveals a block's source
|
|
935
992
|
* markers (markdown special characters like `**`, `#`, list bullets, code
|
|
@@ -1024,6 +1081,7 @@ export declare class EditorModel {
|
|
|
1024
1081
|
insertedRanges: OffsetRange[];
|
|
1025
1082
|
changedBlocks: Set<BlockAstNode>;
|
|
1026
1083
|
} | undefined, void>;
|
|
1084
|
+
readonly markerVisibleBlocks: IObservableWithChange<Set<BlockAstNode>, void>;
|
|
1027
1085
|
/**
|
|
1028
1086
|
* Arm a {@link PendingParagraph} at the given gap, minting a fresh synthetic
|
|
1029
1087
|
* AST node for it, and park the caret at the gap start. No source edit is
|
|
@@ -1042,7 +1100,7 @@ export declare class EditorModel {
|
|
|
1042
1100
|
* lines, and place the caret after the inserted text.
|
|
1043
1101
|
*/
|
|
1044
1102
|
materializePendingParagraph(text: string): void;
|
|
1045
|
-
applyEdit(edit: StringEdit): void;
|
|
1103
|
+
applyEdit(edit: StringEdit, selection?: Selection_2): void;
|
|
1046
1104
|
applyEditForSelection(edit: StringEdit): void;
|
|
1047
1105
|
}
|
|
1048
1106
|
|
|
@@ -1200,6 +1258,13 @@ export declare class EditorView extends Disposable {
|
|
|
1200
1258
|
* have `pointer-events: none`, so the hit-test sees through them.
|
|
1201
1259
|
*/
|
|
1202
1260
|
isPointInContent(point: Point2D): boolean;
|
|
1261
|
+
/**
|
|
1262
|
+
* Whether `node` sits inside the rendered source text — the region whose
|
|
1263
|
+
* selection this editor paints itself from `model.selection`. Overlays
|
|
1264
|
+
* anchored beside the text (comment widgets and the like) are *not* part of
|
|
1265
|
+
* it and keep their own native selection behaviour.
|
|
1266
|
+
*/
|
|
1267
|
+
containsRenderedContent(node: Node | null | undefined): boolean;
|
|
1203
1268
|
private readonly _renderAutorun;
|
|
1204
1269
|
/** Current mounted blocks, or empty before the first render. */
|
|
1205
1270
|
private get _blocks();
|
|
@@ -1278,14 +1343,18 @@ declare class EmphasisViewData {
|
|
|
1278
1343
|
*/
|
|
1279
1344
|
export declare function findNodeOffsetById(root: AstNode, target: AstNode): number | undefined;
|
|
1280
1345
|
|
|
1281
|
-
export declare function findWordAt(text: string, offset: number): {
|
|
1346
|
+
export declare function findWordAt(text: string, offset: number, config?: WordNavigationConfig): {
|
|
1282
1347
|
start: number;
|
|
1283
1348
|
end: number;
|
|
1284
1349
|
};
|
|
1285
1350
|
|
|
1286
|
-
export declare function findWordBoundaryLeft(text: string, offset: number): number;
|
|
1351
|
+
export declare function findWordBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1352
|
+
|
|
1353
|
+
export declare function findWordBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1287
1354
|
|
|
1288
|
-
export declare function
|
|
1355
|
+
export declare function findWordDeleteBoundaryLeft(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1356
|
+
|
|
1357
|
+
export declare function findWordDeleteBoundaryRight(text: string, offset: number, config?: WordNavigationConfig): number;
|
|
1289
1358
|
|
|
1290
1359
|
export declare function getAnnotatedSource(node: AstNode, source: string, offset?: number): string;
|
|
1291
1360
|
|
|
@@ -1362,6 +1431,8 @@ declare class HeadingViewData {
|
|
|
1362
1431
|
constructor(ast: HeadingAstNode, content: readonly AnyViewData[]);
|
|
1363
1432
|
}
|
|
1364
1433
|
|
|
1434
|
+
export declare function hiddenCursorRanges(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number): readonly OffsetRange[];
|
|
1435
|
+
|
|
1365
1436
|
/**
|
|
1366
1437
|
* The editor operations a clipboard strategy drives. The strategy never
|
|
1367
1438
|
* touches the model or the DOM directly — it asks through this seam, so the
|
|
@@ -1600,6 +1671,29 @@ export declare interface ISyntaxHighlighterDocument extends IDisposable {
|
|
|
1600
1671
|
readonly snapshot: IObservableWithChange<ISyntaxHighlightedSnapshot, LengthEdit>;
|
|
1601
1672
|
}
|
|
1602
1673
|
|
|
1674
|
+
export declare interface KeyboardBinding {
|
|
1675
|
+
readonly key: string;
|
|
1676
|
+
readonly modifiers?: KeyboardModifiers;
|
|
1677
|
+
readonly platforms?: readonly KeyboardPlatform[];
|
|
1678
|
+
readonly action: EditorKeyboardAction;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
export declare interface KeyboardModifiers {
|
|
1682
|
+
readonly shift?: boolean;
|
|
1683
|
+
readonly alt?: boolean;
|
|
1684
|
+
readonly ctrl?: boolean;
|
|
1685
|
+
readonly meta?: boolean;
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
export declare type KeyboardPlatform = 'macos' | 'windows' | 'linux';
|
|
1689
|
+
|
|
1690
|
+
export declare interface KeyboardProfile {
|
|
1691
|
+
/**
|
|
1692
|
+
* Bindings in priority order. The first exact key/modifier/platform match wins.
|
|
1693
|
+
*/
|
|
1694
|
+
readonly bindings: readonly KeyboardBinding[];
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1603
1697
|
declare abstract class LeafAstNode extends AstNode {
|
|
1604
1698
|
abstract readonly content: string;
|
|
1605
1699
|
get children(): readonly AstNode[];
|
|
@@ -1934,10 +2028,12 @@ declare interface NestedItem {
|
|
|
1934
2028
|
* Move the cursor one position left or right, skipping over hidden marker
|
|
1935
2029
|
* ranges in inactive blocks (and inactive items of an active list).
|
|
1936
2030
|
*/
|
|
1937
|
-
export declare function nextCursorPosition(doc: DocumentAstNode,
|
|
2031
|
+
export declare function nextCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, direction: 'left' | 'right'): number;
|
|
1938
2032
|
|
|
1939
2033
|
declare const NO_ACTIVE_BLOCKS: unique symbol;
|
|
1940
2034
|
|
|
2035
|
+
export declare function normalizeCursorPosition(doc: DocumentAstNode, markerVisibleBlocks: ReadonlySet<BlockAstNode>, cursor: number, target: number, direction: 'left' | 'right', includeHiddenRangeBoundary?: boolean): number;
|
|
2036
|
+
|
|
1941
2037
|
export declare class OffsetRange {
|
|
1942
2038
|
readonly start: number;
|
|
1943
2039
|
readonly endExclusive: number;
|
|
@@ -2689,6 +2785,8 @@ export declare class VisualLineMap {
|
|
|
2689
2785
|
offsetAtPoint(point: Point2D): SourceOffset;
|
|
2690
2786
|
/** Snap `x` to the nearest offset on a specific line. */
|
|
2691
2787
|
offsetInLineAtX(lineIndex: number, x: number): SourceOffset;
|
|
2788
|
+
lineStartOffset(lineIndex: number): SourceOffset | undefined;
|
|
2789
|
+
lineEndOffset(lineIndex: number): SourceOffset | undefined;
|
|
2692
2790
|
}
|
|
2693
2791
|
|
|
2694
2792
|
/**
|
|
@@ -2739,6 +2837,8 @@ declare interface VisualRunSource {
|
|
|
2739
2837
|
readonly coordinateSpace: EditorCoordinateSpace;
|
|
2740
2838
|
}
|
|
2741
2839
|
|
|
2840
|
+
export declare const vscodeKeyboardProfile: KeyboardProfile;
|
|
2841
|
+
|
|
2742
2842
|
export declare class VscodeStackedCommentsView extends StackedCommentsPresenter {
|
|
2743
2843
|
protected createWidget(comment: Comment_2): StackWidget;
|
|
2744
2844
|
}
|
|
@@ -2747,4 +2847,9 @@ export declare class VsCodeV2CommentsView extends StackedCommentsPresenter {
|
|
|
2747
2847
|
protected createWidget(comment: Comment_2): StackWidget;
|
|
2748
2848
|
}
|
|
2749
2849
|
|
|
2850
|
+
export declare interface WordNavigationConfig {
|
|
2851
|
+
readonly wordSeparators: string;
|
|
2852
|
+
readonly wordSegmenterLocales: readonly string[];
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2750
2855
|
export { }
|