mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-05 02:39:46 +02:00
Update npm
This commit is contained in:
parent
8341712d58
commit
1bd85100b9
5320 changed files with 58396 additions and 344722 deletions
80
node_modules/@codemirror/autocomplete/CHANGELOG.md
generated
vendored
80
node_modules/@codemirror/autocomplete/CHANGELOG.md
generated
vendored
|
@ -1,3 +1,83 @@
|
|||
## 6.15.0 (2024-03-13)
|
||||
|
||||
### New features
|
||||
|
||||
The new `filterStrict` option can be used to turn off fuzzy matching of completions.
|
||||
|
||||
## 6.14.0 (2024-03-10)
|
||||
|
||||
### New features
|
||||
|
||||
Completion results can now define a `map` method that can be used to adjust position-dependent information for document changes.
|
||||
|
||||
## 6.13.0 (2024-02-29)
|
||||
|
||||
### New features
|
||||
|
||||
Completions may now provide 'commit characters' that, when typed, commit the completion before inserting the character.
|
||||
|
||||
## 6.12.0 (2024-01-12)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make sure snippet completions also set `userEvent` to `input.complete`.
|
||||
|
||||
Fix a crash when the editor lost focus during an update and autocompletion was active.
|
||||
|
||||
Fix a crash when using a snippet that has only one field, but multiple instances of that field.
|
||||
|
||||
### New features
|
||||
|
||||
The new `activateOnTypingDelay` option allows control over the debounce time before the completions are queried when the user types.
|
||||
|
||||
## 6.11.1 (2023-11-27)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug that caused typing over closed brackets after pressing enter to still not work in many situations.
|
||||
|
||||
## 6.11.0 (2023-11-09)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix an issue that would prevent typing over closed brackets after starting a new line with enter.
|
||||
|
||||
### New features
|
||||
|
||||
Additional elements rendered in completion options with `addToOptions` are now given access to the editor view.
|
||||
|
||||
## 6.10.2 (2023-10-13)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug that caused `updateSyncTime` to always delay the initial population of the tooltip.
|
||||
|
||||
## 6.10.1 (2023-10-11)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug where picking a selection with the mouse could use the wrong completion if the completion list was updated after being opened.
|
||||
|
||||
## 6.10.0 (2023-10-11)
|
||||
|
||||
### New features
|
||||
|
||||
The new autocompletion configuration option `updateSyncTime` allows control over how long fast sources are held back waiting for slower completion sources.
|
||||
|
||||
## 6.9.2 (2023-10-06)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Fix a bug in `completeAnyWord` that could cause it to generate invalid regular expressions and crash.
|
||||
|
||||
## 6.9.1 (2023-09-14)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
Make sure the cursor is scrolled into view after inserting completion text.
|
||||
|
||||
Make sure scrolling completions into view doesn't get confused when the tooltip is scaled.
|
||||
|
||||
## 6.9.0 (2023-07-18)
|
||||
|
||||
### New features
|
||||
|
|
294
node_modules/@codemirror/autocomplete/dist/index.cjs
generated
vendored
294
node_modules/@codemirror/autocomplete/dist/index.cjs
generated
vendored
|
@ -1,7 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
var state = require('@codemirror/state');
|
||||
var view = require('@codemirror/view');
|
||||
var language = require('@codemirror/language');
|
||||
|
@ -175,7 +173,7 @@ function insertCompletionText(state$1, text, from, to) {
|
|||
changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
|
||||
range: state.EditorSelection.cursor(range.from + fromOff + text.length)
|
||||
};
|
||||
})), { userEvent: "input.complete" });
|
||||
})), { scrollIntoView: true, userEvent: "input.complete" });
|
||||
}
|
||||
const SourceCache = new WeakMap();
|
||||
function asSource(source) {
|
||||
|
@ -216,7 +214,7 @@ class FuzzyMatcher {
|
|||
ret(score, matched) {
|
||||
this.score = score;
|
||||
this.matched = matched;
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
// Matches a given word (completion) against the pattern (input).
|
||||
// Will return a boolean indicating whether there was a match and,
|
||||
|
@ -227,25 +225,25 @@ class FuzzyMatcher {
|
|||
// is. See `Penalty` above.
|
||||
match(word) {
|
||||
if (this.pattern.length == 0)
|
||||
return this.ret(-100 /* NotFull */, []);
|
||||
return this.ret(-100 /* Penalty.NotFull */, []);
|
||||
if (word.length < this.pattern.length)
|
||||
return false;
|
||||
return null;
|
||||
let { chars, folded, any, precise, byWord } = this;
|
||||
// For single-character queries, only match when they occur right
|
||||
// at the start
|
||||
if (chars.length == 1) {
|
||||
let first = state.codePointAt(word, 0), firstSize = state.codePointSize(first);
|
||||
let score = firstSize == word.length ? 0 : -100 /* NotFull */;
|
||||
let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
|
||||
if (first == chars[0]) ;
|
||||
else if (first == folded[0])
|
||||
score += -200 /* CaseFold */;
|
||||
score += -200 /* Penalty.CaseFold */;
|
||||
else
|
||||
return false;
|
||||
return null;
|
||||
return this.ret(score, [0, firstSize]);
|
||||
}
|
||||
let direct = word.indexOf(this.pattern);
|
||||
if (direct == 0)
|
||||
return this.ret(word.length == this.pattern.length ? 0 : -100 /* NotFull */, [0, this.pattern.length]);
|
||||
return this.ret(word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, [0, this.pattern.length]);
|
||||
let len = chars.length, anyTo = 0;
|
||||
if (direct < 0) {
|
||||
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
||||
|
@ -256,7 +254,7 @@ class FuzzyMatcher {
|
|||
}
|
||||
// No match, exit immediately
|
||||
if (anyTo < len)
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
// This tracks the extent of the precise (non-folded, not
|
||||
// necessarily adjacent) match
|
||||
|
@ -269,7 +267,7 @@ class FuzzyMatcher {
|
|||
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
|
||||
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
|
||||
// Go over the option's text, scanning for the various kinds of matches
|
||||
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
|
||||
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
|
||||
let next = state.codePointAt(word, i);
|
||||
if (direct < 0) {
|
||||
if (preciseTo < len && next == chars[preciseTo])
|
||||
|
@ -287,9 +285,9 @@ class FuzzyMatcher {
|
|||
}
|
||||
}
|
||||
let ch, type = next < 0xff
|
||||
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
|
||||
: ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
|
||||
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
|
||||
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
|
||||
: ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
|
||||
if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
|
||||
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
||||
byWord[byWordTo++] = i;
|
||||
else if (byWord.length)
|
||||
|
@ -299,18 +297,18 @@ class FuzzyMatcher {
|
|||
i += state.codePointSize(next);
|
||||
}
|
||||
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
||||
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
||||
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
|
||||
if (adjacentTo == len && adjacentStart == 0)
|
||||
return this.ret(-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), [0, adjacentEnd]);
|
||||
return this.ret(-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), [0, adjacentEnd]);
|
||||
if (direct > -1)
|
||||
return this.ret(-700 /* NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
||||
return this.ret(-700 /* Penalty.NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
||||
if (adjacentTo == len)
|
||||
return this.ret(-200 /* CaseFold */ + -700 /* NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
||||
return this.ret(-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
||||
if (byWordTo == len)
|
||||
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
||||
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
||||
return chars.length == 2 ? false
|
||||
: this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
||||
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
|
||||
(wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
|
||||
return chars.length == 2 ? null
|
||||
: this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
|
||||
}
|
||||
result(score, positions, word) {
|
||||
let result = [], i = 0;
|
||||
|
@ -326,11 +324,31 @@ class FuzzyMatcher {
|
|||
return this.ret(score - word.length, result);
|
||||
}
|
||||
}
|
||||
class StrictMatcher {
|
||||
constructor(pattern) {
|
||||
this.pattern = pattern;
|
||||
this.matched = [];
|
||||
this.score = 0;
|
||||
this.folded = pattern.toLowerCase();
|
||||
}
|
||||
match(word) {
|
||||
if (word.length < this.pattern.length)
|
||||
return null;
|
||||
let start = word.slice(0, this.pattern.length);
|
||||
let match = start == this.pattern ? 0 : start.toLowerCase() == this.folded ? -200 /* Penalty.CaseFold */ : null;
|
||||
if (match == null)
|
||||
return null;
|
||||
this.matched = [0, start.length];
|
||||
this.score = match + (word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
const completionConfig = state.Facet.define({
|
||||
combine(configs) {
|
||||
return state.combineConfig(configs, {
|
||||
activateOnTyping: true,
|
||||
activateOnTypingDelay: 100,
|
||||
selectOnOpen: true,
|
||||
override: null,
|
||||
closeOnBlur: true,
|
||||
|
@ -342,22 +360,25 @@ const completionConfig = state.Facet.define({
|
|||
icons: true,
|
||||
addToOptions: [],
|
||||
positionInfo: defaultPositionInfo,
|
||||
filterStrict: false,
|
||||
compareCompletions: (a, b) => a.label.localeCompare(b.label),
|
||||
interactionDelay: 75
|
||||
interactionDelay: 75,
|
||||
updateSyncTime: 100
|
||||
}, {
|
||||
defaultKeymap: (a, b) => a && b,
|
||||
closeOnBlur: (a, b) => a && b,
|
||||
icons: (a, b) => a && b,
|
||||
tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
|
||||
optionClass: (a, b) => c => joinClass(a(c), b(c)),
|
||||
addToOptions: (a, b) => a.concat(b)
|
||||
addToOptions: (a, b) => a.concat(b),
|
||||
filterStrict: (a, b) => a || b,
|
||||
});
|
||||
}
|
||||
});
|
||||
function joinClass(a, b) {
|
||||
return a ? b ? a + " " + b : a : b;
|
||||
}
|
||||
function defaultPositionInfo(view$1, list, option, info, space) {
|
||||
function defaultPositionInfo(view$1, list, option, info, space, tooltip) {
|
||||
let rtl = view$1.textDirection == view.Direction.RTL, left = rtl, narrow = false;
|
||||
let side = "top", offset, maxWidth;
|
||||
let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
|
||||
|
@ -368,11 +389,11 @@ function defaultPositionInfo(view$1, list, option, info, space) {
|
|||
left = true;
|
||||
if (infoWidth <= (left ? spaceLeft : spaceRight)) {
|
||||
offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
|
||||
maxWidth = Math.min(400 /* Width */, left ? spaceLeft : spaceRight);
|
||||
maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight);
|
||||
}
|
||||
else {
|
||||
narrow = true;
|
||||
maxWidth = Math.min(400 /* Width */, (rtl ? list.right : space.right - list.left) - 30 /* Margin */);
|
||||
maxWidth = Math.min(400 /* Info.Width */, (rtl ? list.right : space.right - list.left) - 30 /* Info.Margin */);
|
||||
let spaceBelow = space.bottom - list.bottom;
|
||||
if (spaceBelow >= infoHeight || spaceBelow > list.top) { // Below the completion
|
||||
offset = option.bottom - list.top;
|
||||
|
@ -382,8 +403,10 @@ function defaultPositionInfo(view$1, list, option, info, space) {
|
|||
offset = list.bottom - option.top;
|
||||
}
|
||||
}
|
||||
let scaleY = (list.bottom - list.top) / tooltip.offsetHeight;
|
||||
let scaleX = (list.right - list.left) / tooltip.offsetWidth;
|
||||
return {
|
||||
style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
|
||||
style: `${side}: ${offset / scaleY}px; max-width: ${maxWidth / scaleX}px`,
|
||||
class: "cm-completionInfo-" + (narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right")
|
||||
};
|
||||
}
|
||||
|
@ -403,7 +426,7 @@ function optionContent(config) {
|
|||
position: 20
|
||||
});
|
||||
content.push({
|
||||
render(completion, _s, match) {
|
||||
render(completion, _s, _v, match) {
|
||||
let labelElt = document.createElement("span");
|
||||
labelElt.className = "cm-completionLabel";
|
||||
let label = completion.displayLabel || completion.label, off = 0;
|
||||
|
@ -471,6 +494,7 @@ class CompletionTooltip {
|
|||
this.dom.className = "cm-tooltip-autocomplete";
|
||||
this.updateTooltipClass(view.state);
|
||||
this.dom.addEventListener("mousedown", (e) => {
|
||||
let { options } = view.state.field(stateField).open;
|
||||
for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
|
||||
if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
|
||||
this.applyCompletion(view, options[+match[1]]);
|
||||
|
@ -485,22 +509,32 @@ class CompletionTooltip {
|
|||
e.relatedTarget != view.contentDOM)
|
||||
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
});
|
||||
this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
|
||||
this.showOptions(options, cState.id);
|
||||
}
|
||||
mount() { this.updateSel(); }
|
||||
showOptions(options, id) {
|
||||
if (this.list)
|
||||
this.list.remove();
|
||||
this.list = this.dom.appendChild(this.createListBox(options, id, this.range));
|
||||
this.list.addEventListener("scroll", () => {
|
||||
if (this.info)
|
||||
this.view.requestMeasure(this.placeInfoReq);
|
||||
});
|
||||
}
|
||||
mount() { this.updateSel(); }
|
||||
update(update) {
|
||||
var _a, _b, _c;
|
||||
var _a;
|
||||
let cState = update.state.field(this.stateField);
|
||||
let prevState = update.startState.field(this.stateField);
|
||||
this.updateTooltipClass(update.state);
|
||||
if (cState != prevState) {
|
||||
let { options, selected, disabled } = cState.open;
|
||||
if (!prevState.open || prevState.open.options != options) {
|
||||
this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions);
|
||||
this.showOptions(options, cState.id);
|
||||
}
|
||||
this.updateSel();
|
||||
if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
|
||||
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
|
||||
if (disabled != ((_a = prevState.open) === null || _a === void 0 ? void 0 : _a.disabled))
|
||||
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!disabled);
|
||||
}
|
||||
}
|
||||
updateTooltipClass(state) {
|
||||
|
@ -524,12 +558,7 @@ class CompletionTooltip {
|
|||
let cState = this.view.state.field(this.stateField), open = cState.open;
|
||||
if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
|
||||
this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
|
||||
this.list.remove();
|
||||
this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
|
||||
this.list.addEventListener("scroll", () => {
|
||||
if (this.info)
|
||||
this.view.requestMeasure(this.placeInfoReq);
|
||||
});
|
||||
this.showOptions(open.options, cState.id);
|
||||
}
|
||||
if (this.updateSelectedOption(open.selected)) {
|
||||
this.destroyInfo();
|
||||
|
@ -603,7 +632,7 @@ class CompletionTooltip {
|
|||
if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 ||
|
||||
selRect.bottom < Math.max(space.top, listRect.top) + 10)
|
||||
return null;
|
||||
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
|
||||
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space, this.dom);
|
||||
}
|
||||
placeInfo(pos) {
|
||||
if (this.info) {
|
||||
|
@ -646,7 +675,7 @@ class CompletionTooltip {
|
|||
if (cls)
|
||||
li.className = cls;
|
||||
for (let source of this.optionContent) {
|
||||
let node = source(completion, this.view.state, match);
|
||||
let node = source(completion, this.view.state, this.view, match);
|
||||
if (node)
|
||||
li.appendChild(node);
|
||||
}
|
||||
|
@ -669,18 +698,17 @@ class CompletionTooltip {
|
|||
this.destroyInfo();
|
||||
}
|
||||
}
|
||||
// We allocate a new function instance every time the completion
|
||||
// changes to force redrawing/repositioning of the tooltip
|
||||
function completionTooltip(stateField, applyCompletion) {
|
||||
return (view) => new CompletionTooltip(view, stateField, applyCompletion);
|
||||
}
|
||||
function scrollIntoView(container, element) {
|
||||
let parent = container.getBoundingClientRect();
|
||||
let self = element.getBoundingClientRect();
|
||||
let scaleY = parent.height / container.offsetHeight;
|
||||
if (self.top < parent.top)
|
||||
container.scrollTop -= parent.top - self.top;
|
||||
container.scrollTop -= (parent.top - self.top) / scaleY;
|
||||
else if (self.bottom > parent.bottom)
|
||||
container.scrollTop += self.bottom - parent.bottom;
|
||||
container.scrollTop += (self.bottom - parent.bottom) / scaleY;
|
||||
}
|
||||
|
||||
// Used to pick a preferred option when two options with the same
|
||||
|
@ -703,6 +731,7 @@ function sortOptions(active, state) {
|
|||
sections.push(typeof section == "string" ? { name } : section);
|
||||
}
|
||||
};
|
||||
let conf = state.facet(completionConfig);
|
||||
for (let a of active)
|
||||
if (a.hasResult()) {
|
||||
let getMatch = a.result.getMatch;
|
||||
|
@ -712,11 +741,12 @@ function sortOptions(active, state) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to));
|
||||
let pattern = state.sliceDoc(a.from, a.to), match;
|
||||
let matcher = conf.filterStrict ? new StrictMatcher(pattern) : new FuzzyMatcher(pattern);
|
||||
for (let option of a.result.options)
|
||||
if (matcher.match(option.label)) {
|
||||
let matched = !option.displayLabel ? matcher.matched : getMatch ? getMatch(option, matcher.matched) : [];
|
||||
addOption(new Option(option, a.source, matched, matcher.score + (option.boost || 0)));
|
||||
if (match = matcher.match(option.label)) {
|
||||
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
|
||||
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -734,7 +764,7 @@ function sortOptions(active, state) {
|
|||
}
|
||||
}
|
||||
let result = [], prev = null;
|
||||
let compare = state.facet(completionConfig).compareCompletions;
|
||||
let compare = conf.compareCompletions;
|
||||
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
|
||||
let cur = opt.completion;
|
||||
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
|
||||
|
@ -763,7 +793,7 @@ class CompletionDialog {
|
|||
static build(active, state, id, prev, conf) {
|
||||
let options = sortOptions(active, state);
|
||||
if (!options.length) {
|
||||
return prev && active.some(a => a.state == 1 /* Pending */) ?
|
||||
return prev && active.some(a => a.state == 1 /* State.Pending */) ?
|
||||
new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
|
||||
}
|
||||
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
|
||||
|
@ -777,7 +807,7 @@ class CompletionDialog {
|
|||
}
|
||||
return new CompletionDialog(options, makeAttrs(id, selected), {
|
||||
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
||||
create: completionTooltip(completionState, applyCompletion),
|
||||
create: createTooltip,
|
||||
above: conf.aboveCursor,
|
||||
}, prev ? prev.timestamp : Date.now(), selected, false);
|
||||
}
|
||||
|
@ -800,7 +830,7 @@ class CompletionState {
|
|||
state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
||||
let active = sources.map(source => {
|
||||
let value = this.active.find(s => s.source == source) ||
|
||||
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
|
||||
new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
|
||||
return value.update(tr, conf);
|
||||
});
|
||||
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
|
||||
|
@ -811,10 +841,10 @@ class CompletionState {
|
|||
if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
|
||||
!sameResults(active, this.active))
|
||||
open = CompletionDialog.build(active, state, this.id, open, conf);
|
||||
else if (open && open.disabled && !active.some(a => a.state == 1 /* Pending */))
|
||||
else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
|
||||
open = null;
|
||||
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
|
||||
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
|
||||
if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
|
||||
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
|
||||
for (let effect of tr.effects)
|
||||
if (effect.is(setSelectedEffect))
|
||||
open = open && open.setSelected(effect.value, this.id);
|
||||
|
@ -868,13 +898,13 @@ class ActiveSource {
|
|||
value = value.handleUserEvent(tr, event, conf);
|
||||
else if (tr.docChanged)
|
||||
value = value.handleChange(tr);
|
||||
else if (tr.selection && value.state != 0 /* Inactive */)
|
||||
value = new ActiveSource(value.source, 0 /* Inactive */);
|
||||
else if (tr.selection && value.state != 0 /* State.Inactive */)
|
||||
value = new ActiveSource(value.source, 0 /* State.Inactive */);
|
||||
for (let effect of tr.effects) {
|
||||
if (effect.is(startCompletionEffect))
|
||||
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
|
||||
value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
|
||||
else if (effect.is(closeCompletionEffect))
|
||||
value = new ActiveSource(value.source, 0 /* Inactive */);
|
||||
value = new ActiveSource(value.source, 0 /* State.Inactive */);
|
||||
else if (effect.is(setActiveEffect))
|
||||
for (let active of effect.value)
|
||||
if (active.source == value.source)
|
||||
|
@ -883,10 +913,10 @@ class ActiveSource {
|
|||
return value;
|
||||
}
|
||||
handleUserEvent(tr, type, conf) {
|
||||
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
|
||||
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
|
||||
}
|
||||
handleChange(tr) {
|
||||
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
||||
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
|
||||
}
|
||||
map(changes) {
|
||||
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
|
||||
|
@ -894,7 +924,7 @@ class ActiveSource {
|
|||
}
|
||||
class ActiveResult extends ActiveSource {
|
||||
constructor(source, explicitPos, result, from, to) {
|
||||
super(source, 2 /* Result */, explicitPos);
|
||||
super(source, 2 /* State.Result */, explicitPos);
|
||||
this.result = result;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
|
@ -902,26 +932,33 @@ class ActiveResult extends ActiveSource {
|
|||
hasResult() { return true; }
|
||||
handleUserEvent(tr, type, conf) {
|
||||
var _a;
|
||||
let result = this.result;
|
||||
if (result.map && !tr.changes.empty)
|
||||
result = result.map(result, tr.changes);
|
||||
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
||||
let pos = cur(tr.state);
|
||||
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
||||
pos > to ||
|
||||
pos > to || !result ||
|
||||
type == "delete" && cur(tr.startState) == this.from)
|
||||
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
||||
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
|
||||
if (checkValid(this.result.validFor, tr.state, from, to))
|
||||
return new ActiveResult(this.source, explicitPos, this.result, from, to);
|
||||
if (this.result.update &&
|
||||
(updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
|
||||
return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
|
||||
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
|
||||
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
|
||||
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
||||
if (checkValid(result.validFor, tr.state, from, to))
|
||||
return new ActiveResult(this.source, explicitPos, result, from, to);
|
||||
if (result.update &&
|
||||
(result = result.update(result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
|
||||
return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
|
||||
return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
|
||||
}
|
||||
handleChange(tr) {
|
||||
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
||||
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
|
||||
}
|
||||
map(mapping) {
|
||||
return mapping.empty ? this :
|
||||
new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
|
||||
if (mapping.empty)
|
||||
return this;
|
||||
let result = this.result.map ? this.result.map(this.result, mapping) : this.result;
|
||||
if (!result)
|
||||
return new ActiveSource(this.source, 0 /* State.Inactive */);
|
||||
return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
|
||||
}
|
||||
}
|
||||
function checkValid(validFor, state, from, to) {
|
||||
|
@ -953,6 +990,7 @@ function applyCompletion(view, option) {
|
|||
apply(view, option.completion, result.from, result.to);
|
||||
return true;
|
||||
}
|
||||
const createTooltip = completionTooltip(completionState, applyCompletion);
|
||||
|
||||
/**
|
||||
Returns a command that moves the completion selection forward or
|
||||
|
@ -1003,7 +1041,7 @@ Close the currently active completion.
|
|||
*/
|
||||
const closeCompletion = (view) => {
|
||||
let cState = view.state.field(completionState, false);
|
||||
if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
|
||||
if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
|
||||
return false;
|
||||
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
return true;
|
||||
|
@ -1019,16 +1057,17 @@ class RunningQuery {
|
|||
this.done = undefined;
|
||||
}
|
||||
}
|
||||
const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
|
||||
const MaxUpdateCount = 50, MinAbortTime = 1000;
|
||||
const completionPlugin = view.ViewPlugin.fromClass(class {
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
this.debounceUpdate = -1;
|
||||
this.running = [];
|
||||
this.debounceAccept = -1;
|
||||
this.composing = 0 /* None */;
|
||||
this.pendingStart = false;
|
||||
this.composing = 0 /* CompositionState.None */;
|
||||
for (let active of view.state.field(completionState).active)
|
||||
if (active.state == 1 /* Pending */)
|
||||
if (active.state == 1 /* State.Pending */)
|
||||
this.startQuery(active);
|
||||
}
|
||||
update(update) {
|
||||
|
@ -1059,21 +1098,25 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|||
}
|
||||
if (this.debounceUpdate > -1)
|
||||
clearTimeout(this.debounceUpdate);
|
||||
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
|
||||
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
||||
if (this.composing != 0 /* None */)
|
||||
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect))))
|
||||
this.pendingStart = true;
|
||||
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay;
|
||||
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
|
||||
? setTimeout(() => this.startUpdate(), delay) : -1;
|
||||
if (this.composing != 0 /* CompositionState.None */)
|
||||
for (let tr of update.transactions) {
|
||||
if (getUserEvent(tr) == "input")
|
||||
this.composing = 2 /* Changed */;
|
||||
else if (this.composing == 2 /* Changed */ && tr.selection)
|
||||
this.composing = 3 /* ChangedAndMoved */;
|
||||
this.composing = 2 /* CompositionState.Changed */;
|
||||
else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
|
||||
this.composing = 3 /* CompositionState.ChangedAndMoved */;
|
||||
}
|
||||
}
|
||||
startUpdate() {
|
||||
this.debounceUpdate = -1;
|
||||
this.pendingStart = false;
|
||||
let { state } = this.view, cState = state.field(completionState);
|
||||
for (let active of cState.active) {
|
||||
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
|
||||
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
|
||||
this.startQuery(active);
|
||||
}
|
||||
}
|
||||
|
@ -1096,7 +1139,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|||
if (this.running.every(q => q.done !== undefined))
|
||||
this.accept();
|
||||
else if (this.debounceAccept < 0)
|
||||
this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
|
||||
this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
|
||||
}
|
||||
// For each finished query in this.running, try to create a result
|
||||
// or, if appropriate, restart the query.
|
||||
|
@ -1124,14 +1167,14 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|||
}
|
||||
}
|
||||
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
||||
if (current && current.state == 1 /* Pending */) {
|
||||
if (current && current.state == 1 /* State.Pending */) {
|
||||
if (query.done == null) {
|
||||
// Explicitly failed. Should clear the pending status if it
|
||||
// hasn't been re-set in the meantime.
|
||||
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
|
||||
let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
|
||||
for (let tr of query.updates)
|
||||
active = active.update(tr, conf);
|
||||
if (active.state != 1 /* Pending */)
|
||||
if (active.state != 1 /* State.Pending */)
|
||||
updated.push(active);
|
||||
}
|
||||
else {
|
||||
|
@ -1150,22 +1193,37 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|||
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
||||
let dialog = state.open && view.getTooltip(this.view, state.open.tooltip);
|
||||
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
||||
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
|
||||
}
|
||||
},
|
||||
compositionstart() {
|
||||
this.composing = 1 /* Started */;
|
||||
this.composing = 1 /* CompositionState.Started */;
|
||||
},
|
||||
compositionend() {
|
||||
if (this.composing == 3 /* ChangedAndMoved */) {
|
||||
if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
|
||||
// Safari fires compositionend events synchronously, possibly
|
||||
// from inside an update, so dispatch asynchronously to avoid reentrancy
|
||||
setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
|
||||
}
|
||||
this.composing = 0 /* None */;
|
||||
this.composing = 0 /* CompositionState.None */;
|
||||
}
|
||||
}
|
||||
});
|
||||
const windows = typeof navigator == "object" && /Win/.test(navigator.platform);
|
||||
const commitCharacters = state.Prec.highest(view.EditorView.domEventHandlers({
|
||||
keydown(event, view) {
|
||||
let field = view.state.field(completionState, false);
|
||||
if (!field || !field.open || field.open.disabled || field.open.selected < 0 ||
|
||||
event.key.length > 1 || event.ctrlKey && !(windows && event.altKey) || event.metaKey)
|
||||
return false;
|
||||
let option = field.open.options[field.open.selected];
|
||||
let result = field.active.find(a => a.source == option.source);
|
||||
let commitChars = option.completion.commitCharacters || result.result.commitCharacters;
|
||||
if (commitChars && commitChars.indexOf(event.key) > -1)
|
||||
applyCompletion(view, option);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
const baseTheme = view.EditorView.baseTheme({
|
||||
".cm-tooltip.cm-tooltip-autocomplete": {
|
||||
|
@ -1222,13 +1280,13 @@ const baseTheme = view.EditorView.baseTheme({
|
|||
position: "absolute",
|
||||
padding: "3px 9px",
|
||||
width: "max-content",
|
||||
maxWidth: `${400 /* Width */}px`,
|
||||
maxWidth: `${400 /* Info.Width */}px`,
|
||||
boxSizing: "border-box"
|
||||
},
|
||||
".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
|
||||
".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
|
||||
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
|
||||
"&light .cm-snippetField": { backgroundColor: "#00000022" },
|
||||
"&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
|
||||
".cm-snippetFieldPosition": {
|
||||
|
@ -1458,11 +1516,11 @@ function snippet(template) {
|
|||
let spec = {
|
||||
changes: { from, to, insert: state.Text.of(text) },
|
||||
scrollIntoView: true,
|
||||
annotations: completion ? pickedCompletion.of(completion) : undefined
|
||||
annotations: completion ? [pickedCompletion.of(completion), state.Transaction.userEvent.of("input.complete")] : undefined
|
||||
};
|
||||
if (ranges.length)
|
||||
spec.selection = fieldSelection(ranges, 0);
|
||||
if (ranges.length > 1) {
|
||||
if (ranges.some(r => r.field > 0)) {
|
||||
let active = new ActiveSnippet(ranges, 0);
|
||||
let effects = spec.effects = [setActive.of(active)];
|
||||
if (editor.state.field(snippetState, false) === undefined)
|
||||
|
@ -1479,7 +1537,8 @@ function moveField(dir) {
|
|||
let next = active.active + dir, last = dir > 0 && !active.ranges.some(r => r.field == next + dir);
|
||||
dispatch(state.update({
|
||||
selection: fieldSelection(active.ranges, next),
|
||||
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next))
|
||||
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next)),
|
||||
scrollIntoView: true
|
||||
}));
|
||||
return true;
|
||||
};
|
||||
|
@ -1551,14 +1610,16 @@ const snippetPointerHandler = view.EditorView.domEventHandlers({
|
|||
return false;
|
||||
view.dispatch({
|
||||
selection: fieldSelection(active.ranges, match.field),
|
||||
effects: setActive.of(active.ranges.some(r => r.field > match.field) ? new ActiveSnippet(active.ranges, match.field) : null)
|
||||
effects: setActive.of(active.ranges.some(r => r.field > match.field)
|
||||
? new ActiveSnippet(active.ranges, match.field) : null),
|
||||
scrollIntoView: true
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
function wordRE(wordChars) {
|
||||
let escaped = wordChars.replace(/[\\[.+*?(){|^$]/g, "\\$&");
|
||||
let escaped = wordChars.replace(/[\]\-\\]/g, "\\$&");
|
||||
try {
|
||||
return new RegExp(`[\\p{Alphabetic}\\p{Number}_${escaped}]+`, "ug");
|
||||
}
|
||||
|
@ -1581,7 +1642,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|||
if (!seen[m[0]] && pos + m.index != ignoreAt) {
|
||||
result.push({ type: "text", label: m[0] });
|
||||
seen[m[0]] = true;
|
||||
if (result.length >= 2000 /* MaxList */)
|
||||
if (result.length >= 2000 /* C.MaxList */)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1589,7 +1650,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|||
}
|
||||
}
|
||||
function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
||||
let big = doc.length >= 1000 /* MinCacheLen */;
|
||||
let big = doc.length >= 1000 /* C.MinCacheLen */;
|
||||
let cached = big && cache.get(doc);
|
||||
if (cached)
|
||||
return cached;
|
||||
|
@ -1597,7 +1658,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|||
if (doc.children) {
|
||||
let pos = 0;
|
||||
for (let ch of doc.children) {
|
||||
if (ch.length >= 1000 /* MinCacheLen */) {
|
||||
if (ch.length >= 1000 /* C.MinCacheLen */) {
|
||||
for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
|
||||
if (!seen[c.label]) {
|
||||
seen[c.label] = true;
|
||||
|
@ -1614,7 +1675,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|||
else {
|
||||
storeWords(doc, wordRE, result, seen, ignoreAt);
|
||||
}
|
||||
if (big && result.length < 2000 /* MaxList */)
|
||||
if (big && result.length < 2000 /* C.MaxList */)
|
||||
cache.set(doc, result);
|
||||
return result;
|
||||
}
|
||||
|
@ -1630,7 +1691,7 @@ const completeAnyWord = context => {
|
|||
if (!token && !context.explicit)
|
||||
return null;
|
||||
let from = token ? token.from : context.pos;
|
||||
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
|
||||
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from);
|
||||
return { from, options, validFor: mapRE(re, s => "^" + s) };
|
||||
};
|
||||
|
||||
|
@ -1652,13 +1713,11 @@ closedBracket.endSide = -1;
|
|||
const bracketState = state.StateField.define({
|
||||
create() { return state.RangeSet.empty; },
|
||||
update(value, tr) {
|
||||
if (tr.selection) {
|
||||
let lineStart = tr.state.doc.lineAt(tr.selection.main.head).from;
|
||||
let prevLineStart = tr.startState.doc.lineAt(tr.startState.selection.main.head).from;
|
||||
if (lineStart != tr.changes.mapPos(prevLineStart, -1))
|
||||
value = state.RangeSet.empty;
|
||||
}
|
||||
value = value.map(tr.changes);
|
||||
if (tr.selection) {
|
||||
let line = tr.state.doc.lineAt(tr.selection.main.head);
|
||||
value = value.update({ filter: from => from >= line.from && from <= line.to });
|
||||
}
|
||||
for (let effect of tr.effects)
|
||||
if (effect.is(closeBracketEffect))
|
||||
value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
|
||||
|
@ -1886,6 +1945,7 @@ Returns an extension that enables autocompletion.
|
|||
*/
|
||||
function autocompletion(config = {}) {
|
||||
return [
|
||||
commitCharacters,
|
||||
completionState,
|
||||
completionConfig.of(config),
|
||||
completionPlugin,
|
||||
|
@ -1922,8 +1982,8 @@ returns `null`.
|
|||
*/
|
||||
function completionStatus(state) {
|
||||
let cState = state.field(completionState, false);
|
||||
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
|
||||
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
|
||||
return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending"
|
||||
: cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null;
|
||||
}
|
||||
const completionArrayCache = new WeakMap;
|
||||
/**
|
||||
|
|
67
node_modules/@codemirror/autocomplete/dist/index.d.cts
generated
vendored
67
node_modules/@codemirror/autocomplete/dist/index.d.cts
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
import * as _codemirror_state from '@codemirror/state';
|
||||
import { EditorState, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
|
||||
import { EditorState, ChangeDesc, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
|
||||
import { EditorView, Rect, KeyBinding, Command } from '@codemirror/view';
|
||||
import * as _lezer_common from '@lezer/common';
|
||||
|
||||
|
@ -9,7 +9,7 @@ Objects type used to represent individual completions.
|
|||
interface Completion {
|
||||
/**
|
||||
The label to show in the completion picker. This is what input
|
||||
is matched agains to determine whether a completion matches (and
|
||||
is matched against to determine whether a completion matches (and
|
||||
how well it matches).
|
||||
*/
|
||||
label: string;
|
||||
|
@ -54,6 +54,11 @@ interface Completion {
|
|||
*/
|
||||
type?: string;
|
||||
/**
|
||||
When this option is selected, and one of these characters is
|
||||
typed, insert the completion before typing the character.
|
||||
*/
|
||||
commitCharacters?: readonly string[];
|
||||
/**
|
||||
When given, should be a number from -99 to 99 that adjusts how
|
||||
this completion is ranked compared to other completions that
|
||||
match the input as well as this one. A negative number moves it
|
||||
|
@ -75,7 +80,7 @@ The type returned from
|
|||
node, null to indicate there is no info, or an object with an
|
||||
optional `destroy` method that cleans up the node.
|
||||
*/
|
||||
declare type CompletionInfo = Node | null | {
|
||||
type CompletionInfo = Node | null | {
|
||||
dom: Node;
|
||||
destroy?(): void;
|
||||
};
|
||||
|
@ -196,7 +201,7 @@ may return its [result](https://codemirror.net/6/docs/ref/#autocomplete.Completi
|
|||
synchronously or as a promise. Returning null indicates no
|
||||
completions are available.
|
||||
*/
|
||||
declare type CompletionSource = (context: CompletionContext) => CompletionResult | null | Promise<CompletionResult | null>;
|
||||
type CompletionSource = (context: CompletionContext) => CompletionResult | null | Promise<CompletionResult | null>;
|
||||
/**
|
||||
Interface for objects returned by completion sources.
|
||||
*/
|
||||
|
@ -255,6 +260,20 @@ interface CompletionResult {
|
|||
completion still applies in the new state.
|
||||
*/
|
||||
update?: (current: CompletionResult, from: number, to: number, context: CompletionContext) => CompletionResult | null;
|
||||
/**
|
||||
When results contain position-dependent information in, for
|
||||
example, `apply` methods, you can provide this method to update
|
||||
the result for transactions that happen after the query. It is
|
||||
not necessary to update `from` and `to`—those are tracked
|
||||
automatically.
|
||||
*/
|
||||
map?: (current: CompletionResult, changes: ChangeDesc) => CompletionResult | null;
|
||||
/**
|
||||
Set a default set of [commit
|
||||
characters](https://codemirror.net/6/docs/ref/#autocomplete.Completion.commitCharacters) for all
|
||||
options in this result.
|
||||
*/
|
||||
commitCharacters?: readonly string[];
|
||||
}
|
||||
/**
|
||||
This annotation is added to transactions that are produced by
|
||||
|
@ -275,6 +294,14 @@ interface CompletionConfig {
|
|||
*/
|
||||
activateOnTyping?: boolean;
|
||||
/**
|
||||
The amount of time to wait for further typing before querying
|
||||
completion sources via
|
||||
[`activateOnTyping`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.activateOnTyping).
|
||||
Defaults to 100, which should be fine unless your completion
|
||||
source is very slow and/or doesn't use `validFor`.
|
||||
*/
|
||||
activateOnTypingDelay?: number;
|
||||
/**
|
||||
By default, when completion opens, the first option is selected
|
||||
and can be confirmed with
|
||||
[`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion). When this
|
||||
|
@ -340,17 +367,17 @@ interface CompletionConfig {
|
|||
80.
|
||||
*/
|
||||
addToOptions?: {
|
||||
render: (completion: Completion, state: EditorState) => Node | null;
|
||||
render: (completion: Completion, state: EditorState, view: EditorView) => Node | null;
|
||||
position: number;
|
||||
}[];
|
||||
/**
|
||||
By default, [info](https://codemirror.net/6/docs/ref/#autocomplet.Completion.info) tooltips are
|
||||
placed to the side of the selected. This option can be used to
|
||||
override that. It will be given rectangles for the list of
|
||||
completions, the selected option, the info element, and the
|
||||
availble [tooltip space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace),
|
||||
and should return style and/or class strings for the info
|
||||
element.
|
||||
By default, [info](https://codemirror.net/6/docs/ref/#autocomplete.Completion.info) tooltips are
|
||||
placed to the side of the selected completion. This option can
|
||||
be used to override that. It will be given rectangles for the
|
||||
list of completions, the selected option, the info element, and
|
||||
the availble [tooltip
|
||||
space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace), and should return
|
||||
style and/or class strings for the info element.
|
||||
*/
|
||||
positionInfo?: (view: EditorView, list: Rect, option: Rect, info: Rect, space: Rect) => {
|
||||
style?: string;
|
||||
|
@ -363,12 +390,26 @@ interface CompletionConfig {
|
|||
*/
|
||||
compareCompletions?: (a: Completion, b: Completion) => number;
|
||||
/**
|
||||
When set to true (the default is false), turn off fuzzy matching
|
||||
of completions and only show those that start with the text the
|
||||
user typed. Only takes effect for results where
|
||||
[`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) isn't false.
|
||||
*/
|
||||
filterStrict?: boolean;
|
||||
/**
|
||||
By default, commands relating to an open completion only take
|
||||
effect 75 milliseconds after the completion opened, so that key
|
||||
presses made before the user is aware of the tooltip don't go to
|
||||
the tooltip. This option can be used to configure that delay.
|
||||
*/
|
||||
interactionDelay?: number;
|
||||
/**
|
||||
When there are multiple asynchronous completion sources, this
|
||||
controls how long the extension waits for a slow source before
|
||||
displaying results from faster sources. Defaults to 100
|
||||
milliseconds.
|
||||
*/
|
||||
updateSyncTime?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -564,4 +605,4 @@ the currently selected completion.
|
|||
*/
|
||||
declare function setSelectedCompletion(index: number): StateEffect<unknown>;
|
||||
|
||||
export { CloseBracketConfig, Completion, CompletionContext, CompletionInfo, CompletionResult, CompletionSection, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
||||
export { type CloseBracketConfig, type Completion, CompletionContext, type CompletionInfo, type CompletionResult, type CompletionSection, type CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
||||
|
|
67
node_modules/@codemirror/autocomplete/dist/index.d.ts
generated
vendored
67
node_modules/@codemirror/autocomplete/dist/index.d.ts
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
import * as _codemirror_state from '@codemirror/state';
|
||||
import { EditorState, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
|
||||
import { EditorState, ChangeDesc, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
|
||||
import { EditorView, Rect, KeyBinding, Command } from '@codemirror/view';
|
||||
import * as _lezer_common from '@lezer/common';
|
||||
|
||||
|
@ -9,7 +9,7 @@ Objects type used to represent individual completions.
|
|||
interface Completion {
|
||||
/**
|
||||
The label to show in the completion picker. This is what input
|
||||
is matched agains to determine whether a completion matches (and
|
||||
is matched against to determine whether a completion matches (and
|
||||
how well it matches).
|
||||
*/
|
||||
label: string;
|
||||
|
@ -54,6 +54,11 @@ interface Completion {
|
|||
*/
|
||||
type?: string;
|
||||
/**
|
||||
When this option is selected, and one of these characters is
|
||||
typed, insert the completion before typing the character.
|
||||
*/
|
||||
commitCharacters?: readonly string[];
|
||||
/**
|
||||
When given, should be a number from -99 to 99 that adjusts how
|
||||
this completion is ranked compared to other completions that
|
||||
match the input as well as this one. A negative number moves it
|
||||
|
@ -75,7 +80,7 @@ The type returned from
|
|||
node, null to indicate there is no info, or an object with an
|
||||
optional `destroy` method that cleans up the node.
|
||||
*/
|
||||
declare type CompletionInfo = Node | null | {
|
||||
type CompletionInfo = Node | null | {
|
||||
dom: Node;
|
||||
destroy?(): void;
|
||||
};
|
||||
|
@ -196,7 +201,7 @@ may return its [result](https://codemirror.net/6/docs/ref/#autocomplete.Completi
|
|||
synchronously or as a promise. Returning null indicates no
|
||||
completions are available.
|
||||
*/
|
||||
declare type CompletionSource = (context: CompletionContext) => CompletionResult | null | Promise<CompletionResult | null>;
|
||||
type CompletionSource = (context: CompletionContext) => CompletionResult | null | Promise<CompletionResult | null>;
|
||||
/**
|
||||
Interface for objects returned by completion sources.
|
||||
*/
|
||||
|
@ -255,6 +260,20 @@ interface CompletionResult {
|
|||
completion still applies in the new state.
|
||||
*/
|
||||
update?: (current: CompletionResult, from: number, to: number, context: CompletionContext) => CompletionResult | null;
|
||||
/**
|
||||
When results contain position-dependent information in, for
|
||||
example, `apply` methods, you can provide this method to update
|
||||
the result for transactions that happen after the query. It is
|
||||
not necessary to update `from` and `to`—those are tracked
|
||||
automatically.
|
||||
*/
|
||||
map?: (current: CompletionResult, changes: ChangeDesc) => CompletionResult | null;
|
||||
/**
|
||||
Set a default set of [commit
|
||||
characters](https://codemirror.net/6/docs/ref/#autocomplete.Completion.commitCharacters) for all
|
||||
options in this result.
|
||||
*/
|
||||
commitCharacters?: readonly string[];
|
||||
}
|
||||
/**
|
||||
This annotation is added to transactions that are produced by
|
||||
|
@ -275,6 +294,14 @@ interface CompletionConfig {
|
|||
*/
|
||||
activateOnTyping?: boolean;
|
||||
/**
|
||||
The amount of time to wait for further typing before querying
|
||||
completion sources via
|
||||
[`activateOnTyping`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.activateOnTyping).
|
||||
Defaults to 100, which should be fine unless your completion
|
||||
source is very slow and/or doesn't use `validFor`.
|
||||
*/
|
||||
activateOnTypingDelay?: number;
|
||||
/**
|
||||
By default, when completion opens, the first option is selected
|
||||
and can be confirmed with
|
||||
[`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion). When this
|
||||
|
@ -340,17 +367,17 @@ interface CompletionConfig {
|
|||
80.
|
||||
*/
|
||||
addToOptions?: {
|
||||
render: (completion: Completion, state: EditorState) => Node | null;
|
||||
render: (completion: Completion, state: EditorState, view: EditorView) => Node | null;
|
||||
position: number;
|
||||
}[];
|
||||
/**
|
||||
By default, [info](https://codemirror.net/6/docs/ref/#autocomplet.Completion.info) tooltips are
|
||||
placed to the side of the selected. This option can be used to
|
||||
override that. It will be given rectangles for the list of
|
||||
completions, the selected option, the info element, and the
|
||||
availble [tooltip space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace),
|
||||
and should return style and/or class strings for the info
|
||||
element.
|
||||
By default, [info](https://codemirror.net/6/docs/ref/#autocomplete.Completion.info) tooltips are
|
||||
placed to the side of the selected completion. This option can
|
||||
be used to override that. It will be given rectangles for the
|
||||
list of completions, the selected option, the info element, and
|
||||
the availble [tooltip
|
||||
space](https://codemirror.net/6/docs/ref/#view.tooltips^config.tooltipSpace), and should return
|
||||
style and/or class strings for the info element.
|
||||
*/
|
||||
positionInfo?: (view: EditorView, list: Rect, option: Rect, info: Rect, space: Rect) => {
|
||||
style?: string;
|
||||
|
@ -363,12 +390,26 @@ interface CompletionConfig {
|
|||
*/
|
||||
compareCompletions?: (a: Completion, b: Completion) => number;
|
||||
/**
|
||||
When set to true (the default is false), turn off fuzzy matching
|
||||
of completions and only show those that start with the text the
|
||||
user typed. Only takes effect for results where
|
||||
[`filter`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.filter) isn't false.
|
||||
*/
|
||||
filterStrict?: boolean;
|
||||
/**
|
||||
By default, commands relating to an open completion only take
|
||||
effect 75 milliseconds after the completion opened, so that key
|
||||
presses made before the user is aware of the tooltip don't go to
|
||||
the tooltip. This option can be used to configure that delay.
|
||||
*/
|
||||
interactionDelay?: number;
|
||||
/**
|
||||
When there are multiple asynchronous completion sources, this
|
||||
controls how long the extension waits for a slow source before
|
||||
displaying results from faster sources. Defaults to 100
|
||||
milliseconds.
|
||||
*/
|
||||
updateSyncTime?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -564,4 +605,4 @@ the currently selected completion.
|
|||
*/
|
||||
declare function setSelectedCompletion(index: number): StateEffect<unknown>;
|
||||
|
||||
export { CloseBracketConfig, Completion, CompletionContext, CompletionInfo, CompletionResult, CompletionSection, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
||||
export { type CloseBracketConfig, type Completion, CompletionContext, type CompletionInfo, type CompletionResult, type CompletionSection, type CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
||||
|
|
294
node_modules/@codemirror/autocomplete/dist/index.js
generated
vendored
294
node_modules/@codemirror/autocomplete/dist/index.js
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
import { Annotation, StateEffect, EditorSelection, codePointAt, codePointSize, fromCodePoint, Facet, combineConfig, StateField, Prec, Text, MapMode, RangeValue, RangeSet, CharCategory } from '@codemirror/state';
|
||||
import { Annotation, StateEffect, EditorSelection, codePointAt, codePointSize, fromCodePoint, Facet, combineConfig, StateField, Prec, Text, Transaction, MapMode, RangeValue, RangeSet, CharCategory } from '@codemirror/state';
|
||||
import { Direction, logException, showTooltip, EditorView, ViewPlugin, getTooltip, Decoration, WidgetType, keymap } from '@codemirror/view';
|
||||
import { syntaxTree, indentUnit } from '@codemirror/language';
|
||||
|
||||
|
@ -171,7 +171,7 @@ function insertCompletionText(state, text, from, to) {
|
|||
changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
|
||||
range: EditorSelection.cursor(range.from + fromOff + text.length)
|
||||
};
|
||||
})), { userEvent: "input.complete" });
|
||||
})), { scrollIntoView: true, userEvent: "input.complete" });
|
||||
}
|
||||
const SourceCache = /*@__PURE__*/new WeakMap();
|
||||
function asSource(source) {
|
||||
|
@ -212,7 +212,7 @@ class FuzzyMatcher {
|
|||
ret(score, matched) {
|
||||
this.score = score;
|
||||
this.matched = matched;
|
||||
return true;
|
||||
return this;
|
||||
}
|
||||
// Matches a given word (completion) against the pattern (input).
|
||||
// Will return a boolean indicating whether there was a match and,
|
||||
|
@ -223,25 +223,25 @@ class FuzzyMatcher {
|
|||
// is. See `Penalty` above.
|
||||
match(word) {
|
||||
if (this.pattern.length == 0)
|
||||
return this.ret(-100 /* NotFull */, []);
|
||||
return this.ret(-100 /* Penalty.NotFull */, []);
|
||||
if (word.length < this.pattern.length)
|
||||
return false;
|
||||
return null;
|
||||
let { chars, folded, any, precise, byWord } = this;
|
||||
// For single-character queries, only match when they occur right
|
||||
// at the start
|
||||
if (chars.length == 1) {
|
||||
let first = codePointAt(word, 0), firstSize = codePointSize(first);
|
||||
let score = firstSize == word.length ? 0 : -100 /* NotFull */;
|
||||
let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
|
||||
if (first == chars[0]) ;
|
||||
else if (first == folded[0])
|
||||
score += -200 /* CaseFold */;
|
||||
score += -200 /* Penalty.CaseFold */;
|
||||
else
|
||||
return false;
|
||||
return null;
|
||||
return this.ret(score, [0, firstSize]);
|
||||
}
|
||||
let direct = word.indexOf(this.pattern);
|
||||
if (direct == 0)
|
||||
return this.ret(word.length == this.pattern.length ? 0 : -100 /* NotFull */, [0, this.pattern.length]);
|
||||
return this.ret(word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, [0, this.pattern.length]);
|
||||
let len = chars.length, anyTo = 0;
|
||||
if (direct < 0) {
|
||||
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
||||
|
@ -252,7 +252,7 @@ class FuzzyMatcher {
|
|||
}
|
||||
// No match, exit immediately
|
||||
if (anyTo < len)
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
// This tracks the extent of the precise (non-folded, not
|
||||
// necessarily adjacent) match
|
||||
|
@ -265,7 +265,7 @@ class FuzzyMatcher {
|
|||
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
|
||||
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
|
||||
// Go over the option's text, scanning for the various kinds of matches
|
||||
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
|
||||
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
|
||||
let next = codePointAt(word, i);
|
||||
if (direct < 0) {
|
||||
if (preciseTo < len && next == chars[preciseTo])
|
||||
|
@ -283,9 +283,9 @@ class FuzzyMatcher {
|
|||
}
|
||||
}
|
||||
let ch, type = next < 0xff
|
||||
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
|
||||
: ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
|
||||
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
|
||||
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
|
||||
: ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
|
||||
if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
|
||||
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
||||
byWord[byWordTo++] = i;
|
||||
else if (byWord.length)
|
||||
|
@ -295,18 +295,18 @@ class FuzzyMatcher {
|
|||
i += codePointSize(next);
|
||||
}
|
||||
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
||||
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
||||
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
|
||||
if (adjacentTo == len && adjacentStart == 0)
|
||||
return this.ret(-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), [0, adjacentEnd]);
|
||||
return this.ret(-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), [0, adjacentEnd]);
|
||||
if (direct > -1)
|
||||
return this.ret(-700 /* NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
||||
return this.ret(-700 /* Penalty.NotStart */ - word.length, [direct, direct + this.pattern.length]);
|
||||
if (adjacentTo == len)
|
||||
return this.ret(-200 /* CaseFold */ + -700 /* NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
||||
return this.ret(-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, [adjacentStart, adjacentEnd]);
|
||||
if (byWordTo == len)
|
||||
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
||||
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
||||
return chars.length == 2 ? false
|
||||
: this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
||||
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
|
||||
(wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
|
||||
return chars.length == 2 ? null
|
||||
: this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
|
||||
}
|
||||
result(score, positions, word) {
|
||||
let result = [], i = 0;
|
||||
|
@ -322,11 +322,31 @@ class FuzzyMatcher {
|
|||
return this.ret(score - word.length, result);
|
||||
}
|
||||
}
|
||||
class StrictMatcher {
|
||||
constructor(pattern) {
|
||||
this.pattern = pattern;
|
||||
this.matched = [];
|
||||
this.score = 0;
|
||||
this.folded = pattern.toLowerCase();
|
||||
}
|
||||
match(word) {
|
||||
if (word.length < this.pattern.length)
|
||||
return null;
|
||||
let start = word.slice(0, this.pattern.length);
|
||||
let match = start == this.pattern ? 0 : start.toLowerCase() == this.folded ? -200 /* Penalty.CaseFold */ : null;
|
||||
if (match == null)
|
||||
return null;
|
||||
this.matched = [0, start.length];
|
||||
this.score = match + (word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
const completionConfig = /*@__PURE__*/Facet.define({
|
||||
combine(configs) {
|
||||
return combineConfig(configs, {
|
||||
activateOnTyping: true,
|
||||
activateOnTypingDelay: 100,
|
||||
selectOnOpen: true,
|
||||
override: null,
|
||||
closeOnBlur: true,
|
||||
|
@ -338,22 +358,25 @@ const completionConfig = /*@__PURE__*/Facet.define({
|
|||
icons: true,
|
||||
addToOptions: [],
|
||||
positionInfo: defaultPositionInfo,
|
||||
filterStrict: false,
|
||||
compareCompletions: (a, b) => a.label.localeCompare(b.label),
|
||||
interactionDelay: 75
|
||||
interactionDelay: 75,
|
||||
updateSyncTime: 100
|
||||
}, {
|
||||
defaultKeymap: (a, b) => a && b,
|
||||
closeOnBlur: (a, b) => a && b,
|
||||
icons: (a, b) => a && b,
|
||||
tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
|
||||
optionClass: (a, b) => c => joinClass(a(c), b(c)),
|
||||
addToOptions: (a, b) => a.concat(b)
|
||||
addToOptions: (a, b) => a.concat(b),
|
||||
filterStrict: (a, b) => a || b,
|
||||
});
|
||||
}
|
||||
});
|
||||
function joinClass(a, b) {
|
||||
return a ? b ? a + " " + b : a : b;
|
||||
}
|
||||
function defaultPositionInfo(view, list, option, info, space) {
|
||||
function defaultPositionInfo(view, list, option, info, space, tooltip) {
|
||||
let rtl = view.textDirection == Direction.RTL, left = rtl, narrow = false;
|
||||
let side = "top", offset, maxWidth;
|
||||
let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
|
||||
|
@ -364,11 +387,11 @@ function defaultPositionInfo(view, list, option, info, space) {
|
|||
left = true;
|
||||
if (infoWidth <= (left ? spaceLeft : spaceRight)) {
|
||||
offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
|
||||
maxWidth = Math.min(400 /* Width */, left ? spaceLeft : spaceRight);
|
||||
maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight);
|
||||
}
|
||||
else {
|
||||
narrow = true;
|
||||
maxWidth = Math.min(400 /* Width */, (rtl ? list.right : space.right - list.left) - 30 /* Margin */);
|
||||
maxWidth = Math.min(400 /* Info.Width */, (rtl ? list.right : space.right - list.left) - 30 /* Info.Margin */);
|
||||
let spaceBelow = space.bottom - list.bottom;
|
||||
if (spaceBelow >= infoHeight || spaceBelow > list.top) { // Below the completion
|
||||
offset = option.bottom - list.top;
|
||||
|
@ -378,8 +401,10 @@ function defaultPositionInfo(view, list, option, info, space) {
|
|||
offset = list.bottom - option.top;
|
||||
}
|
||||
}
|
||||
let scaleY = (list.bottom - list.top) / tooltip.offsetHeight;
|
||||
let scaleX = (list.right - list.left) / tooltip.offsetWidth;
|
||||
return {
|
||||
style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
|
||||
style: `${side}: ${offset / scaleY}px; max-width: ${maxWidth / scaleX}px`,
|
||||
class: "cm-completionInfo-" + (narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right")
|
||||
};
|
||||
}
|
||||
|
@ -399,7 +424,7 @@ function optionContent(config) {
|
|||
position: 20
|
||||
});
|
||||
content.push({
|
||||
render(completion, _s, match) {
|
||||
render(completion, _s, _v, match) {
|
||||
let labelElt = document.createElement("span");
|
||||
labelElt.className = "cm-completionLabel";
|
||||
let label = completion.displayLabel || completion.label, off = 0;
|
||||
|
@ -467,6 +492,7 @@ class CompletionTooltip {
|
|||
this.dom.className = "cm-tooltip-autocomplete";
|
||||
this.updateTooltipClass(view.state);
|
||||
this.dom.addEventListener("mousedown", (e) => {
|
||||
let { options } = view.state.field(stateField).open;
|
||||
for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
|
||||
if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
|
||||
this.applyCompletion(view, options[+match[1]]);
|
||||
|
@ -481,22 +507,32 @@ class CompletionTooltip {
|
|||
e.relatedTarget != view.contentDOM)
|
||||
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
});
|
||||
this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
|
||||
this.showOptions(options, cState.id);
|
||||
}
|
||||
mount() { this.updateSel(); }
|
||||
showOptions(options, id) {
|
||||
if (this.list)
|
||||
this.list.remove();
|
||||
this.list = this.dom.appendChild(this.createListBox(options, id, this.range));
|
||||
this.list.addEventListener("scroll", () => {
|
||||
if (this.info)
|
||||
this.view.requestMeasure(this.placeInfoReq);
|
||||
});
|
||||
}
|
||||
mount() { this.updateSel(); }
|
||||
update(update) {
|
||||
var _a, _b, _c;
|
||||
var _a;
|
||||
let cState = update.state.field(this.stateField);
|
||||
let prevState = update.startState.field(this.stateField);
|
||||
this.updateTooltipClass(update.state);
|
||||
if (cState != prevState) {
|
||||
let { options, selected, disabled } = cState.open;
|
||||
if (!prevState.open || prevState.open.options != options) {
|
||||
this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions);
|
||||
this.showOptions(options, cState.id);
|
||||
}
|
||||
this.updateSel();
|
||||
if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
|
||||
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
|
||||
if (disabled != ((_a = prevState.open) === null || _a === void 0 ? void 0 : _a.disabled))
|
||||
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!disabled);
|
||||
}
|
||||
}
|
||||
updateTooltipClass(state) {
|
||||
|
@ -520,12 +556,7 @@ class CompletionTooltip {
|
|||
let cState = this.view.state.field(this.stateField), open = cState.open;
|
||||
if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
|
||||
this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
|
||||
this.list.remove();
|
||||
this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
|
||||
this.list.addEventListener("scroll", () => {
|
||||
if (this.info)
|
||||
this.view.requestMeasure(this.placeInfoReq);
|
||||
});
|
||||
this.showOptions(open.options, cState.id);
|
||||
}
|
||||
if (this.updateSelectedOption(open.selected)) {
|
||||
this.destroyInfo();
|
||||
|
@ -599,7 +630,7 @@ class CompletionTooltip {
|
|||
if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 ||
|
||||
selRect.bottom < Math.max(space.top, listRect.top) + 10)
|
||||
return null;
|
||||
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
|
||||
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space, this.dom);
|
||||
}
|
||||
placeInfo(pos) {
|
||||
if (this.info) {
|
||||
|
@ -642,7 +673,7 @@ class CompletionTooltip {
|
|||
if (cls)
|
||||
li.className = cls;
|
||||
for (let source of this.optionContent) {
|
||||
let node = source(completion, this.view.state, match);
|
||||
let node = source(completion, this.view.state, this.view, match);
|
||||
if (node)
|
||||
li.appendChild(node);
|
||||
}
|
||||
|
@ -665,18 +696,17 @@ class CompletionTooltip {
|
|||
this.destroyInfo();
|
||||
}
|
||||
}
|
||||
// We allocate a new function instance every time the completion
|
||||
// changes to force redrawing/repositioning of the tooltip
|
||||
function completionTooltip(stateField, applyCompletion) {
|
||||
return (view) => new CompletionTooltip(view, stateField, applyCompletion);
|
||||
}
|
||||
function scrollIntoView(container, element) {
|
||||
let parent = container.getBoundingClientRect();
|
||||
let self = element.getBoundingClientRect();
|
||||
let scaleY = parent.height / container.offsetHeight;
|
||||
if (self.top < parent.top)
|
||||
container.scrollTop -= parent.top - self.top;
|
||||
container.scrollTop -= (parent.top - self.top) / scaleY;
|
||||
else if (self.bottom > parent.bottom)
|
||||
container.scrollTop += self.bottom - parent.bottom;
|
||||
container.scrollTop += (self.bottom - parent.bottom) / scaleY;
|
||||
}
|
||||
|
||||
// Used to pick a preferred option when two options with the same
|
||||
|
@ -699,6 +729,7 @@ function sortOptions(active, state) {
|
|||
sections.push(typeof section == "string" ? { name } : section);
|
||||
}
|
||||
};
|
||||
let conf = state.facet(completionConfig);
|
||||
for (let a of active)
|
||||
if (a.hasResult()) {
|
||||
let getMatch = a.result.getMatch;
|
||||
|
@ -708,11 +739,12 @@ function sortOptions(active, state) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to));
|
||||
let pattern = state.sliceDoc(a.from, a.to), match;
|
||||
let matcher = conf.filterStrict ? new StrictMatcher(pattern) : new FuzzyMatcher(pattern);
|
||||
for (let option of a.result.options)
|
||||
if (matcher.match(option.label)) {
|
||||
let matched = !option.displayLabel ? matcher.matched : getMatch ? getMatch(option, matcher.matched) : [];
|
||||
addOption(new Option(option, a.source, matched, matcher.score + (option.boost || 0)));
|
||||
if (match = matcher.match(option.label)) {
|
||||
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
|
||||
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -730,7 +762,7 @@ function sortOptions(active, state) {
|
|||
}
|
||||
}
|
||||
let result = [], prev = null;
|
||||
let compare = state.facet(completionConfig).compareCompletions;
|
||||
let compare = conf.compareCompletions;
|
||||
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
|
||||
let cur = opt.completion;
|
||||
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
|
||||
|
@ -759,7 +791,7 @@ class CompletionDialog {
|
|||
static build(active, state, id, prev, conf) {
|
||||
let options = sortOptions(active, state);
|
||||
if (!options.length) {
|
||||
return prev && active.some(a => a.state == 1 /* Pending */) ?
|
||||
return prev && active.some(a => a.state == 1 /* State.Pending */) ?
|
||||
new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
|
||||
}
|
||||
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
|
||||
|
@ -773,7 +805,7 @@ class CompletionDialog {
|
|||
}
|
||||
return new CompletionDialog(options, makeAttrs(id, selected), {
|
||||
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
||||
create: completionTooltip(completionState, applyCompletion),
|
||||
create: createTooltip,
|
||||
above: conf.aboveCursor,
|
||||
}, prev ? prev.timestamp : Date.now(), selected, false);
|
||||
}
|
||||
|
@ -796,7 +828,7 @@ class CompletionState {
|
|||
state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
||||
let active = sources.map(source => {
|
||||
let value = this.active.find(s => s.source == source) ||
|
||||
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
|
||||
new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
|
||||
return value.update(tr, conf);
|
||||
});
|
||||
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
|
||||
|
@ -807,10 +839,10 @@ class CompletionState {
|
|||
if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
|
||||
!sameResults(active, this.active))
|
||||
open = CompletionDialog.build(active, state, this.id, open, conf);
|
||||
else if (open && open.disabled && !active.some(a => a.state == 1 /* Pending */))
|
||||
else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
|
||||
open = null;
|
||||
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
|
||||
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
|
||||
if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
|
||||
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
|
||||
for (let effect of tr.effects)
|
||||
if (effect.is(setSelectedEffect))
|
||||
open = open && open.setSelected(effect.value, this.id);
|
||||
|
@ -864,13 +896,13 @@ class ActiveSource {
|
|||
value = value.handleUserEvent(tr, event, conf);
|
||||
else if (tr.docChanged)
|
||||
value = value.handleChange(tr);
|
||||
else if (tr.selection && value.state != 0 /* Inactive */)
|
||||
value = new ActiveSource(value.source, 0 /* Inactive */);
|
||||
else if (tr.selection && value.state != 0 /* State.Inactive */)
|
||||
value = new ActiveSource(value.source, 0 /* State.Inactive */);
|
||||
for (let effect of tr.effects) {
|
||||
if (effect.is(startCompletionEffect))
|
||||
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
|
||||
value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
|
||||
else if (effect.is(closeCompletionEffect))
|
||||
value = new ActiveSource(value.source, 0 /* Inactive */);
|
||||
value = new ActiveSource(value.source, 0 /* State.Inactive */);
|
||||
else if (effect.is(setActiveEffect))
|
||||
for (let active of effect.value)
|
||||
if (active.source == value.source)
|
||||
|
@ -879,10 +911,10 @@ class ActiveSource {
|
|||
return value;
|
||||
}
|
||||
handleUserEvent(tr, type, conf) {
|
||||
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
|
||||
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
|
||||
}
|
||||
handleChange(tr) {
|
||||
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
||||
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
|
||||
}
|
||||
map(changes) {
|
||||
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
|
||||
|
@ -890,7 +922,7 @@ class ActiveSource {
|
|||
}
|
||||
class ActiveResult extends ActiveSource {
|
||||
constructor(source, explicitPos, result, from, to) {
|
||||
super(source, 2 /* Result */, explicitPos);
|
||||
super(source, 2 /* State.Result */, explicitPos);
|
||||
this.result = result;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
|
@ -898,26 +930,33 @@ class ActiveResult extends ActiveSource {
|
|||
hasResult() { return true; }
|
||||
handleUserEvent(tr, type, conf) {
|
||||
var _a;
|
||||
let result = this.result;
|
||||
if (result.map && !tr.changes.empty)
|
||||
result = result.map(result, tr.changes);
|
||||
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
||||
let pos = cur(tr.state);
|
||||
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
||||
pos > to ||
|
||||
pos > to || !result ||
|
||||
type == "delete" && cur(tr.startState) == this.from)
|
||||
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
||||
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
|
||||
if (checkValid(this.result.validFor, tr.state, from, to))
|
||||
return new ActiveResult(this.source, explicitPos, this.result, from, to);
|
||||
if (this.result.update &&
|
||||
(updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
|
||||
return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
|
||||
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
|
||||
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
|
||||
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
||||
if (checkValid(result.validFor, tr.state, from, to))
|
||||
return new ActiveResult(this.source, explicitPos, result, from, to);
|
||||
if (result.update &&
|
||||
(result = result.update(result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
|
||||
return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
|
||||
return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
|
||||
}
|
||||
handleChange(tr) {
|
||||
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
||||
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
|
||||
}
|
||||
map(mapping) {
|
||||
return mapping.empty ? this :
|
||||
new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
|
||||
if (mapping.empty)
|
||||
return this;
|
||||
let result = this.result.map ? this.result.map(this.result, mapping) : this.result;
|
||||
if (!result)
|
||||
return new ActiveSource(this.source, 0 /* State.Inactive */);
|
||||
return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
|
||||
}
|
||||
}
|
||||
function checkValid(validFor, state, from, to) {
|
||||
|
@ -949,6 +988,7 @@ function applyCompletion(view, option) {
|
|||
apply(view, option.completion, result.from, result.to);
|
||||
return true;
|
||||
}
|
||||
const createTooltip = /*@__PURE__*/completionTooltip(completionState, applyCompletion);
|
||||
|
||||
/**
|
||||
Returns a command that moves the completion selection forward or
|
||||
|
@ -999,7 +1039,7 @@ Close the currently active completion.
|
|||
*/
|
||||
const closeCompletion = (view) => {
|
||||
let cState = view.state.field(completionState, false);
|
||||
if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
|
||||
if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
|
||||
return false;
|
||||
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
return true;
|
||||
|
@ -1015,16 +1055,17 @@ class RunningQuery {
|
|||
this.done = undefined;
|
||||
}
|
||||
}
|
||||
const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
|
||||
const MaxUpdateCount = 50, MinAbortTime = 1000;
|
||||
const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
||||
constructor(view) {
|
||||
this.view = view;
|
||||
this.debounceUpdate = -1;
|
||||
this.running = [];
|
||||
this.debounceAccept = -1;
|
||||
this.composing = 0 /* None */;
|
||||
this.pendingStart = false;
|
||||
this.composing = 0 /* CompositionState.None */;
|
||||
for (let active of view.state.field(completionState).active)
|
||||
if (active.state == 1 /* Pending */)
|
||||
if (active.state == 1 /* State.Pending */)
|
||||
this.startQuery(active);
|
||||
}
|
||||
update(update) {
|
||||
|
@ -1055,21 +1096,25 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|||
}
|
||||
if (this.debounceUpdate > -1)
|
||||
clearTimeout(this.debounceUpdate);
|
||||
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
|
||||
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
||||
if (this.composing != 0 /* None */)
|
||||
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect))))
|
||||
this.pendingStart = true;
|
||||
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay;
|
||||
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
|
||||
? setTimeout(() => this.startUpdate(), delay) : -1;
|
||||
if (this.composing != 0 /* CompositionState.None */)
|
||||
for (let tr of update.transactions) {
|
||||
if (getUserEvent(tr) == "input")
|
||||
this.composing = 2 /* Changed */;
|
||||
else if (this.composing == 2 /* Changed */ && tr.selection)
|
||||
this.composing = 3 /* ChangedAndMoved */;
|
||||
this.composing = 2 /* CompositionState.Changed */;
|
||||
else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
|
||||
this.composing = 3 /* CompositionState.ChangedAndMoved */;
|
||||
}
|
||||
}
|
||||
startUpdate() {
|
||||
this.debounceUpdate = -1;
|
||||
this.pendingStart = false;
|
||||
let { state } = this.view, cState = state.field(completionState);
|
||||
for (let active of cState.active) {
|
||||
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
|
||||
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
|
||||
this.startQuery(active);
|
||||
}
|
||||
}
|
||||
|
@ -1092,7 +1137,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|||
if (this.running.every(q => q.done !== undefined))
|
||||
this.accept();
|
||||
else if (this.debounceAccept < 0)
|
||||
this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
|
||||
this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
|
||||
}
|
||||
// For each finished query in this.running, try to create a result
|
||||
// or, if appropriate, restart the query.
|
||||
|
@ -1120,14 +1165,14 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|||
}
|
||||
}
|
||||
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
||||
if (current && current.state == 1 /* Pending */) {
|
||||
if (current && current.state == 1 /* State.Pending */) {
|
||||
if (query.done == null) {
|
||||
// Explicitly failed. Should clear the pending status if it
|
||||
// hasn't been re-set in the meantime.
|
||||
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
|
||||
let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
|
||||
for (let tr of query.updates)
|
||||
active = active.update(tr, conf);
|
||||
if (active.state != 1 /* Pending */)
|
||||
if (active.state != 1 /* State.Pending */)
|
||||
updated.push(active);
|
||||
}
|
||||
else {
|
||||
|
@ -1146,22 +1191,37 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|||
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
||||
let dialog = state.open && getTooltip(this.view, state.open.tooltip);
|
||||
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
||||
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
||||
setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
|
||||
}
|
||||
},
|
||||
compositionstart() {
|
||||
this.composing = 1 /* Started */;
|
||||
this.composing = 1 /* CompositionState.Started */;
|
||||
},
|
||||
compositionend() {
|
||||
if (this.composing == 3 /* ChangedAndMoved */) {
|
||||
if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
|
||||
// Safari fires compositionend events synchronously, possibly
|
||||
// from inside an update, so dispatch asynchronously to avoid reentrancy
|
||||
setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
|
||||
}
|
||||
this.composing = 0 /* None */;
|
||||
this.composing = 0 /* CompositionState.None */;
|
||||
}
|
||||
}
|
||||
});
|
||||
const windows = typeof navigator == "object" && /*@__PURE__*//Win/.test(navigator.platform);
|
||||
const commitCharacters = /*@__PURE__*/Prec.highest(/*@__PURE__*/EditorView.domEventHandlers({
|
||||
keydown(event, view) {
|
||||
let field = view.state.field(completionState, false);
|
||||
if (!field || !field.open || field.open.disabled || field.open.selected < 0 ||
|
||||
event.key.length > 1 || event.ctrlKey && !(windows && event.altKey) || event.metaKey)
|
||||
return false;
|
||||
let option = field.open.options[field.open.selected];
|
||||
let result = field.active.find(a => a.source == option.source);
|
||||
let commitChars = option.completion.commitCharacters || result.result.commitCharacters;
|
||||
if (commitChars && commitChars.indexOf(event.key) > -1)
|
||||
applyCompletion(view, option);
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
||||
".cm-tooltip.cm-tooltip-autocomplete": {
|
||||
|
@ -1218,13 +1278,13 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
|||
position: "absolute",
|
||||
padding: "3px 9px",
|
||||
width: "max-content",
|
||||
maxWidth: `${400 /* Width */}px`,
|
||||
maxWidth: `${400 /* Info.Width */}px`,
|
||||
boxSizing: "border-box"
|
||||
},
|
||||
".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
|
||||
".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
|
||||
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
|
||||
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
|
||||
"&light .cm-snippetField": { backgroundColor: "#00000022" },
|
||||
"&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
|
||||
".cm-snippetFieldPosition": {
|
||||
|
@ -1454,11 +1514,11 @@ function snippet(template) {
|
|||
let spec = {
|
||||
changes: { from, to, insert: Text.of(text) },
|
||||
scrollIntoView: true,
|
||||
annotations: completion ? pickedCompletion.of(completion) : undefined
|
||||
annotations: completion ? [pickedCompletion.of(completion), Transaction.userEvent.of("input.complete")] : undefined
|
||||
};
|
||||
if (ranges.length)
|
||||
spec.selection = fieldSelection(ranges, 0);
|
||||
if (ranges.length > 1) {
|
||||
if (ranges.some(r => r.field > 0)) {
|
||||
let active = new ActiveSnippet(ranges, 0);
|
||||
let effects = spec.effects = [setActive.of(active)];
|
||||
if (editor.state.field(snippetState, false) === undefined)
|
||||
|
@ -1475,7 +1535,8 @@ function moveField(dir) {
|
|||
let next = active.active + dir, last = dir > 0 && !active.ranges.some(r => r.field == next + dir);
|
||||
dispatch(state.update({
|
||||
selection: fieldSelection(active.ranges, next),
|
||||
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next))
|
||||
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next)),
|
||||
scrollIntoView: true
|
||||
}));
|
||||
return true;
|
||||
};
|
||||
|
@ -1547,14 +1608,16 @@ const snippetPointerHandler = /*@__PURE__*/EditorView.domEventHandlers({
|
|||
return false;
|
||||
view.dispatch({
|
||||
selection: fieldSelection(active.ranges, match.field),
|
||||
effects: setActive.of(active.ranges.some(r => r.field > match.field) ? new ActiveSnippet(active.ranges, match.field) : null)
|
||||
effects: setActive.of(active.ranges.some(r => r.field > match.field)
|
||||
? new ActiveSnippet(active.ranges, match.field) : null),
|
||||
scrollIntoView: true
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
function wordRE(wordChars) {
|
||||
let escaped = wordChars.replace(/[\\[.+*?(){|^$]/g, "\\$&");
|
||||
let escaped = wordChars.replace(/[\]\-\\]/g, "\\$&");
|
||||
try {
|
||||
return new RegExp(`[\\p{Alphabetic}\\p{Number}_${escaped}]+`, "ug");
|
||||
}
|
||||
|
@ -1577,7 +1640,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|||
if (!seen[m[0]] && pos + m.index != ignoreAt) {
|
||||
result.push({ type: "text", label: m[0] });
|
||||
seen[m[0]] = true;
|
||||
if (result.length >= 2000 /* MaxList */)
|
||||
if (result.length >= 2000 /* C.MaxList */)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1585,7 +1648,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|||
}
|
||||
}
|
||||
function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
||||
let big = doc.length >= 1000 /* MinCacheLen */;
|
||||
let big = doc.length >= 1000 /* C.MinCacheLen */;
|
||||
let cached = big && cache.get(doc);
|
||||
if (cached)
|
||||
return cached;
|
||||
|
@ -1593,7 +1656,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|||
if (doc.children) {
|
||||
let pos = 0;
|
||||
for (let ch of doc.children) {
|
||||
if (ch.length >= 1000 /* MinCacheLen */) {
|
||||
if (ch.length >= 1000 /* C.MinCacheLen */) {
|
||||
for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
|
||||
if (!seen[c.label]) {
|
||||
seen[c.label] = true;
|
||||
|
@ -1610,7 +1673,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|||
else {
|
||||
storeWords(doc, wordRE, result, seen, ignoreAt);
|
||||
}
|
||||
if (big && result.length < 2000 /* MaxList */)
|
||||
if (big && result.length < 2000 /* C.MaxList */)
|
||||
cache.set(doc, result);
|
||||
return result;
|
||||
}
|
||||
|
@ -1626,7 +1689,7 @@ const completeAnyWord = context => {
|
|||
if (!token && !context.explicit)
|
||||
return null;
|
||||
let from = token ? token.from : context.pos;
|
||||
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
|
||||
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from);
|
||||
return { from, options, validFor: mapRE(re, s => "^" + s) };
|
||||
};
|
||||
|
||||
|
@ -1648,13 +1711,11 @@ closedBracket.endSide = -1;
|
|||
const bracketState = /*@__PURE__*/StateField.define({
|
||||
create() { return RangeSet.empty; },
|
||||
update(value, tr) {
|
||||
if (tr.selection) {
|
||||
let lineStart = tr.state.doc.lineAt(tr.selection.main.head).from;
|
||||
let prevLineStart = tr.startState.doc.lineAt(tr.startState.selection.main.head).from;
|
||||
if (lineStart != tr.changes.mapPos(prevLineStart, -1))
|
||||
value = RangeSet.empty;
|
||||
}
|
||||
value = value.map(tr.changes);
|
||||
if (tr.selection) {
|
||||
let line = tr.state.doc.lineAt(tr.selection.main.head);
|
||||
value = value.update({ filter: from => from >= line.from && from <= line.to });
|
||||
}
|
||||
for (let effect of tr.effects)
|
||||
if (effect.is(closeBracketEffect))
|
||||
value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
|
||||
|
@ -1882,6 +1943,7 @@ Returns an extension that enables autocompletion.
|
|||
*/
|
||||
function autocompletion(config = {}) {
|
||||
return [
|
||||
commitCharacters,
|
||||
completionState,
|
||||
completionConfig.of(config),
|
||||
completionPlugin,
|
||||
|
@ -1918,8 +1980,8 @@ returns `null`.
|
|||
*/
|
||||
function completionStatus(state) {
|
||||
let cState = state.field(completionState, false);
|
||||
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
|
||||
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
|
||||
return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending"
|
||||
: cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null;
|
||||
}
|
||||
const completionArrayCache = /*@__PURE__*/new WeakMap;
|
||||
/**
|
||||
|
|
4
node_modules/@codemirror/autocomplete/package.json
generated
vendored
4
node_modules/@codemirror/autocomplete/package.json
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@codemirror/autocomplete",
|
||||
"version": "6.9.0",
|
||||
"version": "6.15.0",
|
||||
"description": "Autocompletion for the CodeMirror code editor",
|
||||
"scripts": {
|
||||
"test": "cm-runtests",
|
||||
|
@ -28,7 +28,7 @@
|
|||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.6.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue