@codemirror/autocomplete 6.8.1 → 6.9.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/CHANGELOG.md +6 -0
- package/dist/index.cjs +32 -27
- package/dist/index.d.cts +16 -6
- package/dist/index.d.ts +16 -6
- package/dist/index.js +32 -27
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -202,6 +202,8 @@ class FuzzyMatcher {
|
|
|
202
202
|
this.any = [];
|
|
203
203
|
this.precise = [];
|
|
204
204
|
this.byWord = [];
|
|
205
|
+
this.score = 0;
|
|
206
|
+
this.matched = [];
|
|
205
207
|
for (let p = 0; p < pattern.length;) {
|
|
206
208
|
let char = state.codePointAt(pattern, p), size = state.codePointSize(char);
|
|
207
209
|
this.chars.push(char);
|
|
@@ -211,18 +213,23 @@ class FuzzyMatcher {
|
|
|
211
213
|
}
|
|
212
214
|
this.astral = pattern.length != this.chars.length;
|
|
213
215
|
}
|
|
216
|
+
ret(score, matched) {
|
|
217
|
+
this.score = score;
|
|
218
|
+
this.matched = matched;
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
214
221
|
// Matches a given word (completion) against the pattern (input).
|
|
215
|
-
// Will return
|
|
216
|
-
//
|
|
217
|
-
// indicating the matched parts of `word`.
|
|
222
|
+
// Will return a boolean indicating whether there was a match and,
|
|
223
|
+
// on success, set `this.score` to the score, `this.matched` to an
|
|
224
|
+
// array of `from, to` pairs indicating the matched parts of `word`.
|
|
218
225
|
//
|
|
219
226
|
// The score is a number that is more negative the worse the match
|
|
220
227
|
// is. See `Penalty` above.
|
|
221
228
|
match(word) {
|
|
222
229
|
if (this.pattern.length == 0)
|
|
223
|
-
return
|
|
230
|
+
return this.ret(-100 /* NotFull */, []);
|
|
224
231
|
if (word.length < this.pattern.length)
|
|
225
|
-
return
|
|
232
|
+
return false;
|
|
226
233
|
let { chars, folded, any, precise, byWord } = this;
|
|
227
234
|
// For single-character queries, only match when they occur right
|
|
228
235
|
// at the start
|
|
@@ -233,12 +240,12 @@ class FuzzyMatcher {
|
|
|
233
240
|
else if (first == folded[0])
|
|
234
241
|
score += -200 /* CaseFold */;
|
|
235
242
|
else
|
|
236
|
-
return
|
|
237
|
-
return
|
|
243
|
+
return false;
|
|
244
|
+
return this.ret(score, [0, firstSize]);
|
|
238
245
|
}
|
|
239
246
|
let direct = word.indexOf(this.pattern);
|
|
240
247
|
if (direct == 0)
|
|
241
|
-
return
|
|
248
|
+
return this.ret(word.length == this.pattern.length ? 0 : -100 /* NotFull */, [0, this.pattern.length]);
|
|
242
249
|
let len = chars.length, anyTo = 0;
|
|
243
250
|
if (direct < 0) {
|
|
244
251
|
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
|
@@ -249,7 +256,7 @@ class FuzzyMatcher {
|
|
|
249
256
|
}
|
|
250
257
|
// No match, exit immediately
|
|
251
258
|
if (anyTo < len)
|
|
252
|
-
return
|
|
259
|
+
return false;
|
|
253
260
|
}
|
|
254
261
|
// This tracks the extent of the precise (non-folded, not
|
|
255
262
|
// necessarily adjacent) match
|
|
@@ -294,28 +301,29 @@ class FuzzyMatcher {
|
|
|
294
301
|
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
|
295
302
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
|
296
303
|
if (adjacentTo == len && adjacentStart == 0)
|
|
297
|
-
return
|
|
304
|
+
return this.ret(-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), [0, adjacentEnd]);
|
|
298
305
|
if (direct > -1)
|
|
299
|
-
return
|
|
306
|
+
return this.ret(-700 /* NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
|
300
307
|
if (adjacentTo == len)
|
|
301
|
-
return
|
|
308
|
+
return this.ret(-200 /* CaseFold */ + -700 /* NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
|
302
309
|
if (byWordTo == len)
|
|
303
310
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
|
304
311
|
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
|
305
|
-
return chars.length == 2 ?
|
|
312
|
+
return chars.length == 2 ? false
|
|
313
|
+
: this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
|
306
314
|
}
|
|
307
315
|
result(score, positions, word) {
|
|
308
|
-
let result = [
|
|
316
|
+
let result = [], i = 0;
|
|
309
317
|
for (let pos of positions) {
|
|
310
318
|
let to = pos + (this.astral ? state.codePointSize(state.codePointAt(word, pos)) : 1);
|
|
311
|
-
if (i
|
|
319
|
+
if (i && result[i - 1] == pos)
|
|
312
320
|
result[i - 1] = to;
|
|
313
321
|
else {
|
|
314
322
|
result[i++] = pos;
|
|
315
323
|
result[i++] = to;
|
|
316
324
|
}
|
|
317
325
|
}
|
|
318
|
-
return result;
|
|
326
|
+
return this.ret(score - word.length, result);
|
|
319
327
|
}
|
|
320
328
|
}
|
|
321
329
|
|
|
@@ -398,8 +406,8 @@ function optionContent(config) {
|
|
|
398
406
|
render(completion, _s, match) {
|
|
399
407
|
let labelElt = document.createElement("span");
|
|
400
408
|
labelElt.className = "cm-completionLabel";
|
|
401
|
-
let
|
|
402
|
-
for (let j =
|
|
409
|
+
let label = completion.displayLabel || completion.label, off = 0;
|
|
410
|
+
for (let j = 0; j < match.length;) {
|
|
403
411
|
let from = match[j++], to = match[j++];
|
|
404
412
|
if (from > off)
|
|
405
413
|
labelElt.appendChild(document.createTextNode(label.slice(off, from)));
|
|
@@ -697,21 +705,18 @@ function sortOptions(active, state) {
|
|
|
697
705
|
};
|
|
698
706
|
for (let a of active)
|
|
699
707
|
if (a.hasResult()) {
|
|
708
|
+
let getMatch = a.result.getMatch;
|
|
700
709
|
if (a.result.filter === false) {
|
|
701
|
-
let getMatch = a.result.getMatch;
|
|
702
710
|
for (let option of a.result.options) {
|
|
703
|
-
|
|
704
|
-
if (getMatch)
|
|
705
|
-
for (let n of getMatch(option))
|
|
706
|
-
match.push(n);
|
|
707
|
-
addOption(new Option(option, a.source, match, match[0]));
|
|
711
|
+
addOption(new Option(option, a.source, getMatch ? getMatch(option) : [], 1e9 - options.length));
|
|
708
712
|
}
|
|
709
713
|
}
|
|
710
714
|
else {
|
|
711
|
-
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to))
|
|
715
|
+
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to));
|
|
712
716
|
for (let option of a.result.options)
|
|
713
|
-
if (
|
|
714
|
-
|
|
717
|
+
if (matcher.match(option.label)) {
|
|
718
|
+
let matched = !option.displayLabel ? matcher.matched : getMatch ? getMatch(option, matcher.matched) : [];
|
|
719
|
+
addOption(new Option(option, a.source, matched, matcher.score + (option.boost || 0)));
|
|
715
720
|
}
|
|
716
721
|
}
|
|
717
722
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -14,6 +14,13 @@ interface Completion {
|
|
|
14
14
|
*/
|
|
15
15
|
label: string;
|
|
16
16
|
/**
|
|
17
|
+
An optional override for the completion's visible label. When
|
|
18
|
+
using this, matched characters will only be highlighted if you
|
|
19
|
+
provide a [`getMatch`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.getMatch)
|
|
20
|
+
function.
|
|
21
|
+
*/
|
|
22
|
+
displayLabel?: string;
|
|
23
|
+
/**
|
|
17
24
|
An optional short piece of information to show (with a different
|
|
18
25
|
style) after the label.
|
|
19
26
|
*/
|
|
@@ -230,12 +237,15 @@ interface CompletionResult {
|
|
|
230
237
|
filter?: boolean;
|
|
231
238
|
/**
|
|
232
239
|
When [`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) is set to
|
|
233
|
-
`false
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
`false` or a completion has a
|
|
241
|
+
[`displayLabel`](https://codemirror.net/6/docs/ref/#autocomplete.Completion.displayLabel), this
|
|
242
|
+
may be provided to compute the ranges on the label that match
|
|
243
|
+
the input. Should return an array of numbers where each pair of
|
|
244
|
+
adjacent numbers provide the start and end of a range. The
|
|
245
|
+
second argument, the match found by the library, is only passed
|
|
246
|
+
when `filter` isn't `false`.
|
|
247
|
+
*/
|
|
248
|
+
getMatch?: (completion: Completion, matched?: readonly number[]) => readonly number[];
|
|
239
249
|
/**
|
|
240
250
|
Synchronously update the completion result after typing or
|
|
241
251
|
deletion. If given, this should not do any expensive work, since
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,13 @@ interface Completion {
|
|
|
14
14
|
*/
|
|
15
15
|
label: string;
|
|
16
16
|
/**
|
|
17
|
+
An optional override for the completion's visible label. When
|
|
18
|
+
using this, matched characters will only be highlighted if you
|
|
19
|
+
provide a [`getMatch`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.getMatch)
|
|
20
|
+
function.
|
|
21
|
+
*/
|
|
22
|
+
displayLabel?: string;
|
|
23
|
+
/**
|
|
17
24
|
An optional short piece of information to show (with a different
|
|
18
25
|
style) after the label.
|
|
19
26
|
*/
|
|
@@ -230,12 +237,15 @@ interface CompletionResult {
|
|
|
230
237
|
filter?: boolean;
|
|
231
238
|
/**
|
|
232
239
|
When [`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) is set to
|
|
233
|
-
`false
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
240
|
+
`false` or a completion has a
|
|
241
|
+
[`displayLabel`](https://codemirror.net/6/docs/ref/#autocomplete.Completion.displayLabel), this
|
|
242
|
+
may be provided to compute the ranges on the label that match
|
|
243
|
+
the input. Should return an array of numbers where each pair of
|
|
244
|
+
adjacent numbers provide the start and end of a range. The
|
|
245
|
+
second argument, the match found by the library, is only passed
|
|
246
|
+
when `filter` isn't `false`.
|
|
247
|
+
*/
|
|
248
|
+
getMatch?: (completion: Completion, matched?: readonly number[]) => readonly number[];
|
|
239
249
|
/**
|
|
240
250
|
Synchronously update the completion result after typing or
|
|
241
251
|
deletion. If given, this should not do any expensive work, since
|
package/dist/index.js
CHANGED
|
@@ -198,6 +198,8 @@ class FuzzyMatcher {
|
|
|
198
198
|
this.any = [];
|
|
199
199
|
this.precise = [];
|
|
200
200
|
this.byWord = [];
|
|
201
|
+
this.score = 0;
|
|
202
|
+
this.matched = [];
|
|
201
203
|
for (let p = 0; p < pattern.length;) {
|
|
202
204
|
let char = codePointAt(pattern, p), size = codePointSize(char);
|
|
203
205
|
this.chars.push(char);
|
|
@@ -207,18 +209,23 @@ class FuzzyMatcher {
|
|
|
207
209
|
}
|
|
208
210
|
this.astral = pattern.length != this.chars.length;
|
|
209
211
|
}
|
|
212
|
+
ret(score, matched) {
|
|
213
|
+
this.score = score;
|
|
214
|
+
this.matched = matched;
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
210
217
|
// Matches a given word (completion) against the pattern (input).
|
|
211
|
-
// Will return
|
|
212
|
-
//
|
|
213
|
-
// indicating the matched parts of `word`.
|
|
218
|
+
// Will return a boolean indicating whether there was a match and,
|
|
219
|
+
// on success, set `this.score` to the score, `this.matched` to an
|
|
220
|
+
// array of `from, to` pairs indicating the matched parts of `word`.
|
|
214
221
|
//
|
|
215
222
|
// The score is a number that is more negative the worse the match
|
|
216
223
|
// is. See `Penalty` above.
|
|
217
224
|
match(word) {
|
|
218
225
|
if (this.pattern.length == 0)
|
|
219
|
-
return
|
|
226
|
+
return this.ret(-100 /* NotFull */, []);
|
|
220
227
|
if (word.length < this.pattern.length)
|
|
221
|
-
return
|
|
228
|
+
return false;
|
|
222
229
|
let { chars, folded, any, precise, byWord } = this;
|
|
223
230
|
// For single-character queries, only match when they occur right
|
|
224
231
|
// at the start
|
|
@@ -229,12 +236,12 @@ class FuzzyMatcher {
|
|
|
229
236
|
else if (first == folded[0])
|
|
230
237
|
score += -200 /* CaseFold */;
|
|
231
238
|
else
|
|
232
|
-
return
|
|
233
|
-
return
|
|
239
|
+
return false;
|
|
240
|
+
return this.ret(score, [0, firstSize]);
|
|
234
241
|
}
|
|
235
242
|
let direct = word.indexOf(this.pattern);
|
|
236
243
|
if (direct == 0)
|
|
237
|
-
return
|
|
244
|
+
return this.ret(word.length == this.pattern.length ? 0 : -100 /* NotFull */, [0, this.pattern.length]);
|
|
238
245
|
let len = chars.length, anyTo = 0;
|
|
239
246
|
if (direct < 0) {
|
|
240
247
|
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
|
@@ -245,7 +252,7 @@ class FuzzyMatcher {
|
|
|
245
252
|
}
|
|
246
253
|
// No match, exit immediately
|
|
247
254
|
if (anyTo < len)
|
|
248
|
-
return
|
|
255
|
+
return false;
|
|
249
256
|
}
|
|
250
257
|
// This tracks the extent of the precise (non-folded, not
|
|
251
258
|
// necessarily adjacent) match
|
|
@@ -290,28 +297,29 @@ class FuzzyMatcher {
|
|
|
290
297
|
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
|
291
298
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
|
292
299
|
if (adjacentTo == len && adjacentStart == 0)
|
|
293
|
-
return
|
|
300
|
+
return this.ret(-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), [0, adjacentEnd]);
|
|
294
301
|
if (direct > -1)
|
|
295
|
-
return
|
|
302
|
+
return this.ret(-700 /* NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
|
296
303
|
if (adjacentTo == len)
|
|
297
|
-
return
|
|
304
|
+
return this.ret(-200 /* CaseFold */ + -700 /* NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
|
298
305
|
if (byWordTo == len)
|
|
299
306
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
|
300
307
|
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
|
301
|
-
return chars.length == 2 ?
|
|
308
|
+
return chars.length == 2 ? false
|
|
309
|
+
: this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
|
302
310
|
}
|
|
303
311
|
result(score, positions, word) {
|
|
304
|
-
let result = [
|
|
312
|
+
let result = [], i = 0;
|
|
305
313
|
for (let pos of positions) {
|
|
306
314
|
let to = pos + (this.astral ? codePointSize(codePointAt(word, pos)) : 1);
|
|
307
|
-
if (i
|
|
315
|
+
if (i && result[i - 1] == pos)
|
|
308
316
|
result[i - 1] = to;
|
|
309
317
|
else {
|
|
310
318
|
result[i++] = pos;
|
|
311
319
|
result[i++] = to;
|
|
312
320
|
}
|
|
313
321
|
}
|
|
314
|
-
return result;
|
|
322
|
+
return this.ret(score - word.length, result);
|
|
315
323
|
}
|
|
316
324
|
}
|
|
317
325
|
|
|
@@ -394,8 +402,8 @@ function optionContent(config) {
|
|
|
394
402
|
render(completion, _s, match) {
|
|
395
403
|
let labelElt = document.createElement("span");
|
|
396
404
|
labelElt.className = "cm-completionLabel";
|
|
397
|
-
let
|
|
398
|
-
for (let j =
|
|
405
|
+
let label = completion.displayLabel || completion.label, off = 0;
|
|
406
|
+
for (let j = 0; j < match.length;) {
|
|
399
407
|
let from = match[j++], to = match[j++];
|
|
400
408
|
if (from > off)
|
|
401
409
|
labelElt.appendChild(document.createTextNode(label.slice(off, from)));
|
|
@@ -693,21 +701,18 @@ function sortOptions(active, state) {
|
|
|
693
701
|
};
|
|
694
702
|
for (let a of active)
|
|
695
703
|
if (a.hasResult()) {
|
|
704
|
+
let getMatch = a.result.getMatch;
|
|
696
705
|
if (a.result.filter === false) {
|
|
697
|
-
let getMatch = a.result.getMatch;
|
|
698
706
|
for (let option of a.result.options) {
|
|
699
|
-
|
|
700
|
-
if (getMatch)
|
|
701
|
-
for (let n of getMatch(option))
|
|
702
|
-
match.push(n);
|
|
703
|
-
addOption(new Option(option, a.source, match, match[0]));
|
|
707
|
+
addOption(new Option(option, a.source, getMatch ? getMatch(option) : [], 1e9 - options.length));
|
|
704
708
|
}
|
|
705
709
|
}
|
|
706
710
|
else {
|
|
707
|
-
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to))
|
|
711
|
+
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to));
|
|
708
712
|
for (let option of a.result.options)
|
|
709
|
-
if (
|
|
710
|
-
|
|
713
|
+
if (matcher.match(option.label)) {
|
|
714
|
+
let matched = !option.displayLabel ? matcher.matched : getMatch ? getMatch(option, matcher.matched) : [];
|
|
715
|
+
addOption(new Option(option, a.source, matched, matcher.score + (option.boost || 0)));
|
|
711
716
|
}
|
|
712
717
|
}
|
|
713
718
|
}
|