@codemirror/autocomplete 6.14.0 → 6.15.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 +34 -11
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +34 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -214,7 +214,7 @@ class FuzzyMatcher {
|
|
|
214
214
|
ret(score, matched) {
|
|
215
215
|
this.score = score;
|
|
216
216
|
this.matched = matched;
|
|
217
|
-
return
|
|
217
|
+
return this;
|
|
218
218
|
}
|
|
219
219
|
// Matches a given word (completion) against the pattern (input).
|
|
220
220
|
// Will return a boolean indicating whether there was a match and,
|
|
@@ -227,7 +227,7 @@ class FuzzyMatcher {
|
|
|
227
227
|
if (this.pattern.length == 0)
|
|
228
228
|
return this.ret(-100 /* Penalty.NotFull */, []);
|
|
229
229
|
if (word.length < this.pattern.length)
|
|
230
|
-
return
|
|
230
|
+
return null;
|
|
231
231
|
let { chars, folded, any, precise, byWord } = this;
|
|
232
232
|
// For single-character queries, only match when they occur right
|
|
233
233
|
// at the start
|
|
@@ -238,7 +238,7 @@ class FuzzyMatcher {
|
|
|
238
238
|
else if (first == folded[0])
|
|
239
239
|
score += -200 /* Penalty.CaseFold */;
|
|
240
240
|
else
|
|
241
|
-
return
|
|
241
|
+
return null;
|
|
242
242
|
return this.ret(score, [0, firstSize]);
|
|
243
243
|
}
|
|
244
244
|
let direct = word.indexOf(this.pattern);
|
|
@@ -254,7 +254,7 @@ class FuzzyMatcher {
|
|
|
254
254
|
}
|
|
255
255
|
// No match, exit immediately
|
|
256
256
|
if (anyTo < len)
|
|
257
|
-
return
|
|
257
|
+
return null;
|
|
258
258
|
}
|
|
259
259
|
// This tracks the extent of the precise (non-folded, not
|
|
260
260
|
// necessarily adjacent) match
|
|
@@ -307,7 +307,7 @@ class FuzzyMatcher {
|
|
|
307
307
|
if (byWordTo == len)
|
|
308
308
|
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
|
|
309
309
|
(wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
|
|
310
|
-
return chars.length == 2 ?
|
|
310
|
+
return chars.length == 2 ? null
|
|
311
311
|
: this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
|
|
312
312
|
}
|
|
313
313
|
result(score, positions, word) {
|
|
@@ -324,6 +324,25 @@ class FuzzyMatcher {
|
|
|
324
324
|
return this.ret(score - word.length, result);
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
|
+
class StrictMatcher {
|
|
328
|
+
constructor(pattern) {
|
|
329
|
+
this.pattern = pattern;
|
|
330
|
+
this.matched = [];
|
|
331
|
+
this.score = 0;
|
|
332
|
+
this.folded = pattern.toLowerCase();
|
|
333
|
+
}
|
|
334
|
+
match(word) {
|
|
335
|
+
if (word.length < this.pattern.length)
|
|
336
|
+
return null;
|
|
337
|
+
let start = word.slice(0, this.pattern.length);
|
|
338
|
+
let match = start == this.pattern ? 0 : start.toLowerCase() == this.folded ? -200 /* Penalty.CaseFold */ : null;
|
|
339
|
+
if (match == null)
|
|
340
|
+
return null;
|
|
341
|
+
this.matched = [0, start.length];
|
|
342
|
+
this.score = match + (word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */);
|
|
343
|
+
return this;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
327
346
|
|
|
328
347
|
const completionConfig = state.Facet.define({
|
|
329
348
|
combine(configs) {
|
|
@@ -341,6 +360,7 @@ const completionConfig = state.Facet.define({
|
|
|
341
360
|
icons: true,
|
|
342
361
|
addToOptions: [],
|
|
343
362
|
positionInfo: defaultPositionInfo,
|
|
363
|
+
filterStrict: false,
|
|
344
364
|
compareCompletions: (a, b) => a.label.localeCompare(b.label),
|
|
345
365
|
interactionDelay: 75,
|
|
346
366
|
updateSyncTime: 100
|
|
@@ -350,7 +370,8 @@ const completionConfig = state.Facet.define({
|
|
|
350
370
|
icons: (a, b) => a && b,
|
|
351
371
|
tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
|
|
352
372
|
optionClass: (a, b) => c => joinClass(a(c), b(c)),
|
|
353
|
-
addToOptions: (a, b) => a.concat(b)
|
|
373
|
+
addToOptions: (a, b) => a.concat(b),
|
|
374
|
+
filterStrict: (a, b) => a || b,
|
|
354
375
|
});
|
|
355
376
|
}
|
|
356
377
|
});
|
|
@@ -710,6 +731,7 @@ function sortOptions(active, state) {
|
|
|
710
731
|
sections.push(typeof section == "string" ? { name } : section);
|
|
711
732
|
}
|
|
712
733
|
};
|
|
734
|
+
let conf = state.facet(completionConfig);
|
|
713
735
|
for (let a of active)
|
|
714
736
|
if (a.hasResult()) {
|
|
715
737
|
let getMatch = a.result.getMatch;
|
|
@@ -719,11 +741,12 @@ function sortOptions(active, state) {
|
|
|
719
741
|
}
|
|
720
742
|
}
|
|
721
743
|
else {
|
|
722
|
-
let
|
|
744
|
+
let pattern = state.sliceDoc(a.from, a.to), match;
|
|
745
|
+
let matcher = conf.filterStrict ? new StrictMatcher(pattern) : new FuzzyMatcher(pattern);
|
|
723
746
|
for (let option of a.result.options)
|
|
724
|
-
if (matcher.match(option.label)) {
|
|
725
|
-
let matched = !option.displayLabel ?
|
|
726
|
-
addOption(new Option(option, a.source, matched,
|
|
747
|
+
if (match = matcher.match(option.label)) {
|
|
748
|
+
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
|
|
749
|
+
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
|
|
727
750
|
}
|
|
728
751
|
}
|
|
729
752
|
}
|
|
@@ -741,7 +764,7 @@ function sortOptions(active, state) {
|
|
|
741
764
|
}
|
|
742
765
|
}
|
|
743
766
|
let result = [], prev = null;
|
|
744
|
-
let compare =
|
|
767
|
+
let compare = conf.compareCompletions;
|
|
745
768
|
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
|
|
746
769
|
let cur = opt.completion;
|
|
747
770
|
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
|
package/dist/index.d.cts
CHANGED
|
@@ -390,6 +390,13 @@ interface CompletionConfig {
|
|
|
390
390
|
*/
|
|
391
391
|
compareCompletions?: (a: Completion, b: Completion) => number;
|
|
392
392
|
/**
|
|
393
|
+
When set to true (the default is false), turn off fuzzy matching
|
|
394
|
+
of completions and only show those that start with the text the
|
|
395
|
+
user typed. Only takes effect for results where
|
|
396
|
+
[`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) isn't false.
|
|
397
|
+
*/
|
|
398
|
+
filterStrict?: boolean;
|
|
399
|
+
/**
|
|
393
400
|
By default, commands relating to an open completion only take
|
|
394
401
|
effect 75 milliseconds after the completion opened, so that key
|
|
395
402
|
presses made before the user is aware of the tooltip don't go to
|
package/dist/index.d.ts
CHANGED
|
@@ -390,6 +390,13 @@ interface CompletionConfig {
|
|
|
390
390
|
*/
|
|
391
391
|
compareCompletions?: (a: Completion, b: Completion) => number;
|
|
392
392
|
/**
|
|
393
|
+
When set to true (the default is false), turn off fuzzy matching
|
|
394
|
+
of completions and only show those that start with the text the
|
|
395
|
+
user typed. Only takes effect for results where
|
|
396
|
+
[`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) isn't false.
|
|
397
|
+
*/
|
|
398
|
+
filterStrict?: boolean;
|
|
399
|
+
/**
|
|
393
400
|
By default, commands relating to an open completion only take
|
|
394
401
|
effect 75 milliseconds after the completion opened, so that key
|
|
395
402
|
presses made before the user is aware of the tooltip don't go to
|
package/dist/index.js
CHANGED
|
@@ -212,7 +212,7 @@ class FuzzyMatcher {
|
|
|
212
212
|
ret(score, matched) {
|
|
213
213
|
this.score = score;
|
|
214
214
|
this.matched = matched;
|
|
215
|
-
return
|
|
215
|
+
return this;
|
|
216
216
|
}
|
|
217
217
|
// Matches a given word (completion) against the pattern (input).
|
|
218
218
|
// Will return a boolean indicating whether there was a match and,
|
|
@@ -225,7 +225,7 @@ class FuzzyMatcher {
|
|
|
225
225
|
if (this.pattern.length == 0)
|
|
226
226
|
return this.ret(-100 /* Penalty.NotFull */, []);
|
|
227
227
|
if (word.length < this.pattern.length)
|
|
228
|
-
return
|
|
228
|
+
return null;
|
|
229
229
|
let { chars, folded, any, precise, byWord } = this;
|
|
230
230
|
// For single-character queries, only match when they occur right
|
|
231
231
|
// at the start
|
|
@@ -236,7 +236,7 @@ class FuzzyMatcher {
|
|
|
236
236
|
else if (first == folded[0])
|
|
237
237
|
score += -200 /* Penalty.CaseFold */;
|
|
238
238
|
else
|
|
239
|
-
return
|
|
239
|
+
return null;
|
|
240
240
|
return this.ret(score, [0, firstSize]);
|
|
241
241
|
}
|
|
242
242
|
let direct = word.indexOf(this.pattern);
|
|
@@ -252,7 +252,7 @@ class FuzzyMatcher {
|
|
|
252
252
|
}
|
|
253
253
|
// No match, exit immediately
|
|
254
254
|
if (anyTo < len)
|
|
255
|
-
return
|
|
255
|
+
return null;
|
|
256
256
|
}
|
|
257
257
|
// This tracks the extent of the precise (non-folded, not
|
|
258
258
|
// necessarily adjacent) match
|
|
@@ -305,7 +305,7 @@ class FuzzyMatcher {
|
|
|
305
305
|
if (byWordTo == len)
|
|
306
306
|
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
|
|
307
307
|
(wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
|
|
308
|
-
return chars.length == 2 ?
|
|
308
|
+
return chars.length == 2 ? null
|
|
309
309
|
: this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
|
|
310
310
|
}
|
|
311
311
|
result(score, positions, word) {
|
|
@@ -322,6 +322,25 @@ class FuzzyMatcher {
|
|
|
322
322
|
return this.ret(score - word.length, result);
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
+
class StrictMatcher {
|
|
326
|
+
constructor(pattern) {
|
|
327
|
+
this.pattern = pattern;
|
|
328
|
+
this.matched = [];
|
|
329
|
+
this.score = 0;
|
|
330
|
+
this.folded = pattern.toLowerCase();
|
|
331
|
+
}
|
|
332
|
+
match(word) {
|
|
333
|
+
if (word.length < this.pattern.length)
|
|
334
|
+
return null;
|
|
335
|
+
let start = word.slice(0, this.pattern.length);
|
|
336
|
+
let match = start == this.pattern ? 0 : start.toLowerCase() == this.folded ? -200 /* Penalty.CaseFold */ : null;
|
|
337
|
+
if (match == null)
|
|
338
|
+
return null;
|
|
339
|
+
this.matched = [0, start.length];
|
|
340
|
+
this.score = match + (word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */);
|
|
341
|
+
return this;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
325
344
|
|
|
326
345
|
const completionConfig = /*@__PURE__*/Facet.define({
|
|
327
346
|
combine(configs) {
|
|
@@ -339,6 +358,7 @@ const completionConfig = /*@__PURE__*/Facet.define({
|
|
|
339
358
|
icons: true,
|
|
340
359
|
addToOptions: [],
|
|
341
360
|
positionInfo: defaultPositionInfo,
|
|
361
|
+
filterStrict: false,
|
|
342
362
|
compareCompletions: (a, b) => a.label.localeCompare(b.label),
|
|
343
363
|
interactionDelay: 75,
|
|
344
364
|
updateSyncTime: 100
|
|
@@ -348,7 +368,8 @@ const completionConfig = /*@__PURE__*/Facet.define({
|
|
|
348
368
|
icons: (a, b) => a && b,
|
|
349
369
|
tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
|
|
350
370
|
optionClass: (a, b) => c => joinClass(a(c), b(c)),
|
|
351
|
-
addToOptions: (a, b) => a.concat(b)
|
|
371
|
+
addToOptions: (a, b) => a.concat(b),
|
|
372
|
+
filterStrict: (a, b) => a || b,
|
|
352
373
|
});
|
|
353
374
|
}
|
|
354
375
|
});
|
|
@@ -708,6 +729,7 @@ function sortOptions(active, state) {
|
|
|
708
729
|
sections.push(typeof section == "string" ? { name } : section);
|
|
709
730
|
}
|
|
710
731
|
};
|
|
732
|
+
let conf = state.facet(completionConfig);
|
|
711
733
|
for (let a of active)
|
|
712
734
|
if (a.hasResult()) {
|
|
713
735
|
let getMatch = a.result.getMatch;
|
|
@@ -717,11 +739,12 @@ function sortOptions(active, state) {
|
|
|
717
739
|
}
|
|
718
740
|
}
|
|
719
741
|
else {
|
|
720
|
-
let
|
|
742
|
+
let pattern = state.sliceDoc(a.from, a.to), match;
|
|
743
|
+
let matcher = conf.filterStrict ? new StrictMatcher(pattern) : new FuzzyMatcher(pattern);
|
|
721
744
|
for (let option of a.result.options)
|
|
722
|
-
if (matcher.match(option.label)) {
|
|
723
|
-
let matched = !option.displayLabel ?
|
|
724
|
-
addOption(new Option(option, a.source, matched,
|
|
745
|
+
if (match = matcher.match(option.label)) {
|
|
746
|
+
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
|
|
747
|
+
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
|
|
725
748
|
}
|
|
726
749
|
}
|
|
727
750
|
}
|
|
@@ -739,7 +762,7 @@ function sortOptions(active, state) {
|
|
|
739
762
|
}
|
|
740
763
|
}
|
|
741
764
|
let result = [], prev = null;
|
|
742
|
-
let compare =
|
|
765
|
+
let compare = conf.compareCompletions;
|
|
743
766
|
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
|
|
744
767
|
let cur = opt.completion;
|
|
745
768
|
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
|