@codemirror/autocomplete 0.19.8 → 0.19.12
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 +28 -0
- package/dist/index.cjs +31 -22
- package/dist/index.js +31 -22
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## 0.19.12 (2022-01-11)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix completion navigation with PageUp/Down when the completion tooltip isn't part of the view DOM.
|
|
6
|
+
|
|
7
|
+
## 0.19.11 (2022-01-11)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Fix a bug that caused page up/down to only move the selection by two options in the completion tooltip.
|
|
12
|
+
|
|
13
|
+
## 0.19.10 (2022-01-05)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Make sure the info tooltip is hidden when the selected option is scrolled out of view.
|
|
18
|
+
|
|
19
|
+
Fix a bug in the completion ranking that would sometimes give options that match the input by word start chars higher scores than appropriate.
|
|
20
|
+
|
|
21
|
+
Options are now sorted (ascending) by length when their match score is otherwise identical.
|
|
22
|
+
|
|
23
|
+
## 0.19.9 (2021-11-26)
|
|
24
|
+
|
|
25
|
+
### Bug fixes
|
|
26
|
+
|
|
27
|
+
Fix an issue where info tooltips would be visible in an inappropriate position when there was no room to place them properly.
|
|
28
|
+
|
|
1
29
|
## 0.19.8 (2021-11-17)
|
|
2
30
|
|
|
3
31
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -246,7 +246,7 @@ class FuzzyMatcher {
|
|
|
246
246
|
let byWordTo = 0, byWordFolded = false;
|
|
247
247
|
// If we've found a partial adjacent match, these track its state
|
|
248
248
|
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
|
|
249
|
-
let hasLower = /[a-z]/.test(word);
|
|
249
|
+
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
|
|
250
250
|
// Go over the option's text, scanning for the various kinds of matches
|
|
251
251
|
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
|
|
252
252
|
let next = text.codePointAt(word, i);
|
|
@@ -268,26 +268,30 @@ class FuzzyMatcher {
|
|
|
268
268
|
let ch, type = next < 0xff
|
|
269
269
|
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
|
|
270
270
|
: ((ch = text.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
|
|
271
|
-
if (
|
|
272
|
-
(chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
|
273
|
-
|
|
271
|
+
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
|
|
272
|
+
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
|
273
|
+
byWord[byWordTo++] = i;
|
|
274
|
+
else if (byWord.length)
|
|
275
|
+
wordAdjacent = false;
|
|
276
|
+
}
|
|
274
277
|
prevType = type;
|
|
275
278
|
i += text.codePointSize(next);
|
|
276
279
|
}
|
|
277
|
-
if (byWordTo == len && byWord[0] == 0)
|
|
280
|
+
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
|
278
281
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
|
279
282
|
if (adjacentTo == len && adjacentStart == 0)
|
|
280
|
-
return [-200 /* CaseFold
|
|
283
|
+
return [-200 /* CaseFold */ - word.length, 0, adjacentEnd];
|
|
281
284
|
if (direct > -1)
|
|
282
|
-
return [-700 /* NotStart
|
|
285
|
+
return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
|
|
283
286
|
if (adjacentTo == len)
|
|
284
|
-
return [-200 /* CaseFold */ + -700 /* NotStart
|
|
287
|
+
return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
|
|
285
288
|
if (byWordTo == len)
|
|
286
|
-
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart
|
|
289
|
+
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
|
290
|
+
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
|
287
291
|
return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
|
288
292
|
}
|
|
289
293
|
result(score, positions, word) {
|
|
290
|
-
let result = [score], i = 1;
|
|
294
|
+
let result = [score - word.length], i = 1;
|
|
291
295
|
for (let pos of positions) {
|
|
292
296
|
let to = pos + (this.astral ? text.codePointSize(text.codePointAt(word, pos)) : 1);
|
|
293
297
|
if (i > 1 && result[i - 1] == pos)
|
|
@@ -483,12 +487,14 @@ class CompletionTooltip {
|
|
|
483
487
|
let sel = this.dom.querySelector("[aria-selected]");
|
|
484
488
|
if (!sel || !this.info)
|
|
485
489
|
return null;
|
|
486
|
-
let
|
|
487
|
-
let
|
|
488
|
-
|
|
490
|
+
let listRect = this.dom.getBoundingClientRect();
|
|
491
|
+
let infoRect = this.info.getBoundingClientRect();
|
|
492
|
+
let selRect = sel.getBoundingClientRect();
|
|
493
|
+
if (selRect.top > Math.min(innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
|
|
489
494
|
return null;
|
|
495
|
+
let top = Math.max(0, Math.min(selRect.top, innerHeight - infoRect.height)) - listRect.top;
|
|
490
496
|
let left = this.view.textDirection == view.Direction.RTL;
|
|
491
|
-
let spaceLeft =
|
|
497
|
+
let spaceLeft = listRect.left, spaceRight = innerWidth - listRect.right;
|
|
492
498
|
if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
|
|
493
499
|
left = false;
|
|
494
500
|
else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
|
|
@@ -496,10 +502,12 @@ class CompletionTooltip {
|
|
|
496
502
|
return { top, left };
|
|
497
503
|
}
|
|
498
504
|
positionInfo(pos) {
|
|
499
|
-
if (this.info
|
|
500
|
-
this.info.style.top = pos.top + "px";
|
|
501
|
-
|
|
502
|
-
|
|
505
|
+
if (this.info) {
|
|
506
|
+
this.info.style.top = (pos ? pos.top : -1e6) + "px";
|
|
507
|
+
if (pos) {
|
|
508
|
+
this.info.classList.toggle("cm-completionInfo-left", pos.left);
|
|
509
|
+
this.info.classList.toggle("cm-completionInfo-right", !pos.left);
|
|
510
|
+
}
|
|
503
511
|
}
|
|
504
512
|
}
|
|
505
513
|
createListBox(options, id, range) {
|
|
@@ -773,9 +781,10 @@ function moveCompletionSelection(forward, by = "option") {
|
|
|
773
781
|
let cState = view.state.field(completionState, false);
|
|
774
782
|
if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
|
|
775
783
|
return false;
|
|
776
|
-
let step = 1, tooltip;
|
|
777
|
-
if (by == "page" && (tooltip = view.
|
|
778
|
-
step = Math.max(2, Math.floor(tooltip.offsetHeight /
|
|
784
|
+
let step = 1, tooltip$1;
|
|
785
|
+
if (by == "page" && (tooltip$1 = tooltip.getTooltip(view, cState.open.tooltip)))
|
|
786
|
+
step = Math.max(2, Math.floor(tooltip$1.dom.offsetHeight /
|
|
787
|
+
tooltip$1.dom.querySelector("li").offsetHeight) - 1);
|
|
779
788
|
let selected = cState.open.selected + step * (forward ? 1 : -1), { length } = cState.open.options;
|
|
780
789
|
if (selected < 0)
|
|
781
790
|
selected = by == "page" ? 0 : length - 1;
|
|
@@ -989,7 +998,7 @@ const baseTheme = view.EditorView.baseTheme({
|
|
|
989
998
|
}
|
|
990
999
|
},
|
|
991
1000
|
"&light .cm-tooltip-autocomplete ul li[aria-selected]": {
|
|
992
|
-
background: "#
|
|
1001
|
+
background: "#17c",
|
|
993
1002
|
color: "white",
|
|
994
1003
|
},
|
|
995
1004
|
"&dark .cm-tooltip-autocomplete ul li[aria-selected]": {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Annotation, Facet, combineConfig, StateEffect, StateField, Prec, EditorSelection, Text } from '@codemirror/state';
|
|
2
2
|
import { Direction, logException, EditorView, ViewPlugin, Decoration, WidgetType, keymap } from '@codemirror/view';
|
|
3
|
-
import { showTooltip } from '@codemirror/tooltip';
|
|
3
|
+
import { showTooltip, getTooltip } from '@codemirror/tooltip';
|
|
4
4
|
import { syntaxTree, indentUnit } from '@codemirror/language';
|
|
5
5
|
import { codePointAt, codePointSize, fromCodePoint } from '@codemirror/text';
|
|
6
6
|
|
|
@@ -242,7 +242,7 @@ class FuzzyMatcher {
|
|
|
242
242
|
let byWordTo = 0, byWordFolded = false;
|
|
243
243
|
// If we've found a partial adjacent match, these track its state
|
|
244
244
|
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
|
|
245
|
-
let hasLower = /[a-z]/.test(word);
|
|
245
|
+
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
|
|
246
246
|
// Go over the option's text, scanning for the various kinds of matches
|
|
247
247
|
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
|
|
248
248
|
let next = codePointAt(word, i);
|
|
@@ -264,26 +264,30 @@ class FuzzyMatcher {
|
|
|
264
264
|
let ch, type = next < 0xff
|
|
265
265
|
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
|
|
266
266
|
: ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
|
|
267
|
-
if (
|
|
268
|
-
(chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
|
269
|
-
|
|
267
|
+
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
|
|
268
|
+
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
|
269
|
+
byWord[byWordTo++] = i;
|
|
270
|
+
else if (byWord.length)
|
|
271
|
+
wordAdjacent = false;
|
|
272
|
+
}
|
|
270
273
|
prevType = type;
|
|
271
274
|
i += codePointSize(next);
|
|
272
275
|
}
|
|
273
|
-
if (byWordTo == len && byWord[0] == 0)
|
|
276
|
+
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
|
274
277
|
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
|
275
278
|
if (adjacentTo == len && adjacentStart == 0)
|
|
276
|
-
return [-200 /* CaseFold
|
|
279
|
+
return [-200 /* CaseFold */ - word.length, 0, adjacentEnd];
|
|
277
280
|
if (direct > -1)
|
|
278
|
-
return [-700 /* NotStart
|
|
281
|
+
return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
|
|
279
282
|
if (adjacentTo == len)
|
|
280
|
-
return [-200 /* CaseFold */ + -700 /* NotStart
|
|
283
|
+
return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
|
|
281
284
|
if (byWordTo == len)
|
|
282
|
-
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart
|
|
285
|
+
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
|
286
|
+
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
|
283
287
|
return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
|
284
288
|
}
|
|
285
289
|
result(score, positions, word) {
|
|
286
|
-
let result = [score], i = 1;
|
|
290
|
+
let result = [score - word.length], i = 1;
|
|
287
291
|
for (let pos of positions) {
|
|
288
292
|
let to = pos + (this.astral ? codePointSize(codePointAt(word, pos)) : 1);
|
|
289
293
|
if (i > 1 && result[i - 1] == pos)
|
|
@@ -479,12 +483,14 @@ class CompletionTooltip {
|
|
|
479
483
|
let sel = this.dom.querySelector("[aria-selected]");
|
|
480
484
|
if (!sel || !this.info)
|
|
481
485
|
return null;
|
|
482
|
-
let
|
|
483
|
-
let
|
|
484
|
-
|
|
486
|
+
let listRect = this.dom.getBoundingClientRect();
|
|
487
|
+
let infoRect = this.info.getBoundingClientRect();
|
|
488
|
+
let selRect = sel.getBoundingClientRect();
|
|
489
|
+
if (selRect.top > Math.min(innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
|
|
485
490
|
return null;
|
|
491
|
+
let top = Math.max(0, Math.min(selRect.top, innerHeight - infoRect.height)) - listRect.top;
|
|
486
492
|
let left = this.view.textDirection == Direction.RTL;
|
|
487
|
-
let spaceLeft =
|
|
493
|
+
let spaceLeft = listRect.left, spaceRight = innerWidth - listRect.right;
|
|
488
494
|
if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
|
|
489
495
|
left = false;
|
|
490
496
|
else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
|
|
@@ -492,10 +498,12 @@ class CompletionTooltip {
|
|
|
492
498
|
return { top, left };
|
|
493
499
|
}
|
|
494
500
|
positionInfo(pos) {
|
|
495
|
-
if (this.info
|
|
496
|
-
this.info.style.top = pos.top + "px";
|
|
497
|
-
|
|
498
|
-
|
|
501
|
+
if (this.info) {
|
|
502
|
+
this.info.style.top = (pos ? pos.top : -1e6) + "px";
|
|
503
|
+
if (pos) {
|
|
504
|
+
this.info.classList.toggle("cm-completionInfo-left", pos.left);
|
|
505
|
+
this.info.classList.toggle("cm-completionInfo-right", !pos.left);
|
|
506
|
+
}
|
|
499
507
|
}
|
|
500
508
|
}
|
|
501
509
|
createListBox(options, id, range) {
|
|
@@ -770,8 +778,9 @@ function moveCompletionSelection(forward, by = "option") {
|
|
|
770
778
|
if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
|
|
771
779
|
return false;
|
|
772
780
|
let step = 1, tooltip;
|
|
773
|
-
if (by == "page" && (tooltip = view.
|
|
774
|
-
step = Math.max(2, Math.floor(tooltip.offsetHeight /
|
|
781
|
+
if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
|
|
782
|
+
step = Math.max(2, Math.floor(tooltip.dom.offsetHeight /
|
|
783
|
+
tooltip.dom.querySelector("li").offsetHeight) - 1);
|
|
775
784
|
let selected = cState.open.selected + step * (forward ? 1 : -1), { length } = cState.open.options;
|
|
776
785
|
if (selected < 0)
|
|
777
786
|
selected = by == "page" ? 0 : length - 1;
|
|
@@ -985,7 +994,7 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
|
|
985
994
|
}
|
|
986
995
|
},
|
|
987
996
|
"&light .cm-tooltip-autocomplete ul li[aria-selected]": {
|
|
988
|
-
background: "#
|
|
997
|
+
background: "#17c",
|
|
989
998
|
color: "white",
|
|
990
999
|
},
|
|
991
1000
|
"&dark .cm-tooltip-autocomplete ul li[aria-selected]": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/autocomplete",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.12",
|
|
4
4
|
"description": "Autocompletion for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@codemirror/language": "^0.19.0",
|
|
30
30
|
"@codemirror/state": "^0.19.4",
|
|
31
31
|
"@codemirror/text": "^0.19.2",
|
|
32
|
-
"@codemirror/tooltip": "^0.19.
|
|
32
|
+
"@codemirror/tooltip": "^0.19.12",
|
|
33
33
|
"@codemirror/view": "^0.19.0",
|
|
34
34
|
"@lezer/common": "^0.15.0"
|
|
35
35
|
},
|