@uiw/react-codemirror 4.21.3 → 4.21.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codemirror.js +333 -291
- package/dist/codemirror.min.js +1 -1
- package/package.json +2 -2
package/dist/codemirror.js
CHANGED
|
@@ -1652,7 +1652,7 @@ class FuzzyMatcher {
|
|
|
1652
1652
|
// is. See `Penalty` above.
|
|
1653
1653
|
match(word) {
|
|
1654
1654
|
if (this.pattern.length == 0)
|
|
1655
|
-
return [-100 /*
|
|
1655
|
+
return [-100 /* NotFull */];
|
|
1656
1656
|
if (word.length < this.pattern.length)
|
|
1657
1657
|
return null;
|
|
1658
1658
|
let { chars, folded, any, precise, byWord } = this;
|
|
@@ -1660,17 +1660,17 @@ class FuzzyMatcher {
|
|
|
1660
1660
|
// at the start
|
|
1661
1661
|
if (chars.length == 1) {
|
|
1662
1662
|
let first = (0,state_.codePointAt)(word, 0), firstSize = (0,state_.codePointSize)(first);
|
|
1663
|
-
let score = firstSize == word.length ? 0 : -100 /*
|
|
1663
|
+
let score = firstSize == word.length ? 0 : -100 /* NotFull */;
|
|
1664
1664
|
if (first == chars[0]) ;
|
|
1665
1665
|
else if (first == folded[0])
|
|
1666
|
-
score += -200 /*
|
|
1666
|
+
score += -200 /* CaseFold */;
|
|
1667
1667
|
else
|
|
1668
1668
|
return null;
|
|
1669
1669
|
return [score, 0, firstSize];
|
|
1670
1670
|
}
|
|
1671
1671
|
let direct = word.indexOf(this.pattern);
|
|
1672
1672
|
if (direct == 0)
|
|
1673
|
-
return [word.length == this.pattern.length ? 0 : -100 /*
|
|
1673
|
+
return [word.length == this.pattern.length ? 0 : -100 /* NotFull */, 0, this.pattern.length];
|
|
1674
1674
|
let len = chars.length, anyTo = 0;
|
|
1675
1675
|
if (direct < 0) {
|
|
1676
1676
|
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
|
|
@@ -1694,7 +1694,7 @@ class FuzzyMatcher {
|
|
|
1694
1694
|
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
|
|
1695
1695
|
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
|
|
1696
1696
|
// Go over the option's text, scanning for the various kinds of matches
|
|
1697
|
-
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /*
|
|
1697
|
+
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
|
|
1698
1698
|
let next = (0,state_.codePointAt)(word, i);
|
|
1699
1699
|
if (direct < 0) {
|
|
1700
1700
|
if (preciseTo < len && next == chars[preciseTo])
|
|
@@ -1712,9 +1712,9 @@ class FuzzyMatcher {
|
|
|
1712
1712
|
}
|
|
1713
1713
|
}
|
|
1714
1714
|
let ch, type = next < 0xff
|
|
1715
|
-
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /*
|
|
1716
|
-
: ((ch = (0,state_.fromCodePoint)(next)) != ch.toLowerCase() ? 1 /*
|
|
1717
|
-
if (!i || type == 1 /*
|
|
1715
|
+
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
|
|
1716
|
+
: ((ch = (0,state_.fromCodePoint)(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
|
|
1717
|
+
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
|
|
1718
1718
|
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
|
|
1719
1719
|
byWord[byWordTo++] = i;
|
|
1720
1720
|
else if (byWord.length)
|
|
@@ -1724,17 +1724,17 @@ class FuzzyMatcher {
|
|
|
1724
1724
|
i += (0,state_.codePointSize)(next);
|
|
1725
1725
|
}
|
|
1726
1726
|
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
|
|
1727
|
-
return this.result(-100 /*
|
|
1727
|
+
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
|
|
1728
1728
|
if (adjacentTo == len && adjacentStart == 0)
|
|
1729
|
-
return [-200 /*
|
|
1729
|
+
return [-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), 0, adjacentEnd];
|
|
1730
1730
|
if (direct > -1)
|
|
1731
|
-
return [-700 /*
|
|
1731
|
+
return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
|
|
1732
1732
|
if (adjacentTo == len)
|
|
1733
|
-
return [-200 /*
|
|
1733
|
+
return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
|
|
1734
1734
|
if (byWordTo == len)
|
|
1735
|
-
return this.result(-100 /*
|
|
1736
|
-
(wordAdjacent ? 0 : -1100 /*
|
|
1737
|
-
return chars.length == 2 ? null : this.result((any[0] ? -700 /*
|
|
1735
|
+
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
|
|
1736
|
+
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
|
|
1737
|
+
return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
|
|
1738
1738
|
}
|
|
1739
1739
|
result(score, positions, word) {
|
|
1740
1740
|
let result = [score - word.length], i = 1;
|
|
@@ -1792,11 +1792,11 @@ function defaultPositionInfo(view, list, option, info, space) {
|
|
|
1792
1792
|
left = true;
|
|
1793
1793
|
if (infoWidth <= (left ? spaceLeft : spaceRight)) {
|
|
1794
1794
|
offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
|
|
1795
|
-
maxWidth = Math.min(400 /*
|
|
1795
|
+
maxWidth = Math.min(400 /* Width */, left ? spaceLeft : spaceRight);
|
|
1796
1796
|
}
|
|
1797
1797
|
else {
|
|
1798
1798
|
narrow = true;
|
|
1799
|
-
maxWidth = Math.min(400 /*
|
|
1799
|
+
maxWidth = Math.min(400 /* Width */, (rtl ? list.right : space.right - list.left) - 30 /* Margin */);
|
|
1800
1800
|
let spaceBelow = space.bottom - list.bottom;
|
|
1801
1801
|
if (spaceBelow >= infoHeight || spaceBelow > list.top) { // Below the completion
|
|
1802
1802
|
offset = option.bottom - list.top;
|
|
@@ -1812,232 +1812,6 @@ function defaultPositionInfo(view, list, option, info, space) {
|
|
|
1812
1812
|
};
|
|
1813
1813
|
}
|
|
1814
1814
|
|
|
1815
|
-
/**
|
|
1816
|
-
Returns a command that moves the completion selection forward or
|
|
1817
|
-
backward by the given amount.
|
|
1818
|
-
*/
|
|
1819
|
-
function moveCompletionSelection(forward, by = "option") {
|
|
1820
|
-
return (view) => {
|
|
1821
|
-
let cState = view.state.field(completionState, false);
|
|
1822
|
-
if (!cState || !cState.open || cState.open.disabled ||
|
|
1823
|
-
Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
|
|
1824
|
-
return false;
|
|
1825
|
-
let step = 1, tooltip;
|
|
1826
|
-
if (by == "page" && (tooltip = (0,view_.getTooltip)(view, cState.open.tooltip)))
|
|
1827
|
-
step = Math.max(2, Math.floor(tooltip.dom.offsetHeight /
|
|
1828
|
-
tooltip.dom.querySelector("li").offsetHeight) - 1);
|
|
1829
|
-
let { length } = cState.open.options;
|
|
1830
|
-
let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length - 1;
|
|
1831
|
-
if (selected < 0)
|
|
1832
|
-
selected = by == "page" ? 0 : length - 1;
|
|
1833
|
-
else if (selected >= length)
|
|
1834
|
-
selected = by == "page" ? length - 1 : 0;
|
|
1835
|
-
view.dispatch({ effects: setSelectedEffect.of(selected) });
|
|
1836
|
-
return true;
|
|
1837
|
-
};
|
|
1838
|
-
}
|
|
1839
|
-
/**
|
|
1840
|
-
Accept the current completion.
|
|
1841
|
-
*/
|
|
1842
|
-
const acceptCompletion = (view) => {
|
|
1843
|
-
let cState = view.state.field(completionState, false);
|
|
1844
|
-
if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 ||
|
|
1845
|
-
Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
|
|
1846
|
-
return false;
|
|
1847
|
-
if (!cState.open.disabled)
|
|
1848
|
-
return applyCompletion(view, cState.open.options[cState.open.selected]);
|
|
1849
|
-
return true;
|
|
1850
|
-
};
|
|
1851
|
-
/**
|
|
1852
|
-
Explicitly start autocompletion.
|
|
1853
|
-
*/
|
|
1854
|
-
const startCompletion = (view) => {
|
|
1855
|
-
let cState = view.state.field(completionState, false);
|
|
1856
|
-
if (!cState)
|
|
1857
|
-
return false;
|
|
1858
|
-
view.dispatch({ effects: startCompletionEffect.of(true) });
|
|
1859
|
-
return true;
|
|
1860
|
-
};
|
|
1861
|
-
/**
|
|
1862
|
-
Close the currently active completion.
|
|
1863
|
-
*/
|
|
1864
|
-
const closeCompletion = (view) => {
|
|
1865
|
-
let cState = view.state.field(completionState, false);
|
|
1866
|
-
if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
|
|
1867
|
-
return false;
|
|
1868
|
-
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
1869
|
-
return true;
|
|
1870
|
-
};
|
|
1871
|
-
class RunningQuery {
|
|
1872
|
-
constructor(active, context) {
|
|
1873
|
-
this.active = active;
|
|
1874
|
-
this.context = context;
|
|
1875
|
-
this.time = Date.now();
|
|
1876
|
-
this.updates = [];
|
|
1877
|
-
// Note that 'undefined' means 'not done yet', whereas 'null' means
|
|
1878
|
-
// 'query returned null'.
|
|
1879
|
-
this.done = undefined;
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
|
|
1883
|
-
const completionPlugin = /*@__PURE__*/view_.ViewPlugin.fromClass(class {
|
|
1884
|
-
constructor(view) {
|
|
1885
|
-
this.view = view;
|
|
1886
|
-
this.debounceUpdate = -1;
|
|
1887
|
-
this.running = [];
|
|
1888
|
-
this.debounceAccept = -1;
|
|
1889
|
-
this.composing = 0 /* CompositionState.None */;
|
|
1890
|
-
for (let active of view.state.field(completionState).active)
|
|
1891
|
-
if (active.state == 1 /* State.Pending */)
|
|
1892
|
-
this.startQuery(active);
|
|
1893
|
-
}
|
|
1894
|
-
update(update) {
|
|
1895
|
-
let cState = update.state.field(completionState);
|
|
1896
|
-
if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
|
|
1897
|
-
return;
|
|
1898
|
-
let doesReset = update.transactions.some(tr => {
|
|
1899
|
-
return (tr.selection || tr.docChanged) && !getUserEvent(tr);
|
|
1900
|
-
});
|
|
1901
|
-
for (let i = 0; i < this.running.length; i++) {
|
|
1902
|
-
let query = this.running[i];
|
|
1903
|
-
if (doesReset ||
|
|
1904
|
-
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
1905
|
-
for (let handler of query.context.abortListeners) {
|
|
1906
|
-
try {
|
|
1907
|
-
handler();
|
|
1908
|
-
}
|
|
1909
|
-
catch (e) {
|
|
1910
|
-
(0,view_.logException)(this.view.state, e);
|
|
1911
|
-
}
|
|
1912
|
-
}
|
|
1913
|
-
query.context.abortListeners = null;
|
|
1914
|
-
this.running.splice(i--, 1);
|
|
1915
|
-
}
|
|
1916
|
-
else {
|
|
1917
|
-
query.updates.push(...update.transactions);
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
if (this.debounceUpdate > -1)
|
|
1921
|
-
clearTimeout(this.debounceUpdate);
|
|
1922
|
-
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
1923
|
-
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
|
1924
|
-
if (this.composing != 0 /* CompositionState.None */)
|
|
1925
|
-
for (let tr of update.transactions) {
|
|
1926
|
-
if (getUserEvent(tr) == "input")
|
|
1927
|
-
this.composing = 2 /* CompositionState.Changed */;
|
|
1928
|
-
else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
|
|
1929
|
-
this.composing = 3 /* CompositionState.ChangedAndMoved */;
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
startUpdate() {
|
|
1933
|
-
this.debounceUpdate = -1;
|
|
1934
|
-
let { state } = this.view, cState = state.field(completionState);
|
|
1935
|
-
for (let active of cState.active) {
|
|
1936
|
-
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
1937
|
-
this.startQuery(active);
|
|
1938
|
-
}
|
|
1939
|
-
}
|
|
1940
|
-
startQuery(active) {
|
|
1941
|
-
let { state } = this.view, pos = cur(state);
|
|
1942
|
-
let context = new CompletionContext(state, pos, active.explicitPos == pos);
|
|
1943
|
-
let pending = new RunningQuery(active, context);
|
|
1944
|
-
this.running.push(pending);
|
|
1945
|
-
Promise.resolve(active.source(context)).then(result => {
|
|
1946
|
-
if (!pending.context.aborted) {
|
|
1947
|
-
pending.done = result || null;
|
|
1948
|
-
this.scheduleAccept();
|
|
1949
|
-
}
|
|
1950
|
-
}, err => {
|
|
1951
|
-
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
1952
|
-
(0,view_.logException)(this.view.state, err);
|
|
1953
|
-
});
|
|
1954
|
-
}
|
|
1955
|
-
scheduleAccept() {
|
|
1956
|
-
if (this.running.every(q => q.done !== undefined))
|
|
1957
|
-
this.accept();
|
|
1958
|
-
else if (this.debounceAccept < 0)
|
|
1959
|
-
this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
|
|
1960
|
-
}
|
|
1961
|
-
// For each finished query in this.running, try to create a result
|
|
1962
|
-
// or, if appropriate, restart the query.
|
|
1963
|
-
accept() {
|
|
1964
|
-
var _a;
|
|
1965
|
-
if (this.debounceAccept > -1)
|
|
1966
|
-
clearTimeout(this.debounceAccept);
|
|
1967
|
-
this.debounceAccept = -1;
|
|
1968
|
-
let updated = [];
|
|
1969
|
-
let conf = this.view.state.facet(completionConfig);
|
|
1970
|
-
for (let i = 0; i < this.running.length; i++) {
|
|
1971
|
-
let query = this.running[i];
|
|
1972
|
-
if (query.done === undefined)
|
|
1973
|
-
continue;
|
|
1974
|
-
this.running.splice(i--, 1);
|
|
1975
|
-
if (query.done) {
|
|
1976
|
-
let active = new ActiveResult(query.active.source, query.active.explicitPos, query.done, query.done.from, (_a = query.done.to) !== null && _a !== void 0 ? _a : cur(query.updates.length ? query.updates[0].startState : this.view.state));
|
|
1977
|
-
// Replay the transactions that happened since the start of
|
|
1978
|
-
// the request and see if that preserves the result
|
|
1979
|
-
for (let tr of query.updates)
|
|
1980
|
-
active = active.update(tr, conf);
|
|
1981
|
-
if (active.hasResult()) {
|
|
1982
|
-
updated.push(active);
|
|
1983
|
-
continue;
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
|
1987
|
-
if (current && current.state == 1 /* State.Pending */) {
|
|
1988
|
-
if (query.done == null) {
|
|
1989
|
-
// Explicitly failed. Should clear the pending status if it
|
|
1990
|
-
// hasn't been re-set in the meantime.
|
|
1991
|
-
let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
|
|
1992
|
-
for (let tr of query.updates)
|
|
1993
|
-
active = active.update(tr, conf);
|
|
1994
|
-
if (active.state != 1 /* State.Pending */)
|
|
1995
|
-
updated.push(active);
|
|
1996
|
-
}
|
|
1997
|
-
else {
|
|
1998
|
-
// Cleared by subsequent transactions. Restart.
|
|
1999
|
-
this.startQuery(current);
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
if (updated.length)
|
|
2004
|
-
this.view.dispatch({ effects: setActiveEffect.of(updated) });
|
|
2005
|
-
}
|
|
2006
|
-
}, {
|
|
2007
|
-
eventHandlers: {
|
|
2008
|
-
blur(event) {
|
|
2009
|
-
let state = this.view.state.field(completionState, false);
|
|
2010
|
-
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
|
2011
|
-
let dialog = state.open && (0,view_.getTooltip)(this.view, state.open.tooltip);
|
|
2012
|
-
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
|
2013
|
-
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
2014
|
-
}
|
|
2015
|
-
},
|
|
2016
|
-
compositionstart() {
|
|
2017
|
-
this.composing = 1 /* CompositionState.Started */;
|
|
2018
|
-
},
|
|
2019
|
-
compositionend() {
|
|
2020
|
-
if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
|
|
2021
|
-
// Safari fires compositionend events synchronously, possibly
|
|
2022
|
-
// from inside an update, so dispatch asynchronously to avoid reentrancy
|
|
2023
|
-
setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
|
|
2024
|
-
}
|
|
2025
|
-
this.composing = 0 /* CompositionState.None */;
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
});
|
|
2029
|
-
function applyCompletion(view, option) {
|
|
2030
|
-
const apply = option.completion.apply || option.completion.label;
|
|
2031
|
-
let result = view.state.field(completionState).active.find(a => a.source == option.source);
|
|
2032
|
-
if (!(result instanceof ActiveResult))
|
|
2033
|
-
return false;
|
|
2034
|
-
if (typeof apply == "string")
|
|
2035
|
-
view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
|
|
2036
|
-
else
|
|
2037
|
-
apply(view, option.completion, result.from, result.to);
|
|
2038
|
-
return true;
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
1815
|
function optionContent(config) {
|
|
2042
1816
|
let content = config.addToOptions.slice();
|
|
2043
1817
|
if (config.icons)
|
|
@@ -2097,10 +1871,12 @@ function rangeAroundSelected(total, selected, max) {
|
|
|
2097
1871
|
return { from: total - (off + 1) * max, to: total - off * max };
|
|
2098
1872
|
}
|
|
2099
1873
|
class CompletionTooltip {
|
|
2100
|
-
constructor(view, stateField) {
|
|
1874
|
+
constructor(view, stateField, applyCompletion) {
|
|
2101
1875
|
this.view = view;
|
|
2102
1876
|
this.stateField = stateField;
|
|
1877
|
+
this.applyCompletion = applyCompletion;
|
|
2103
1878
|
this.info = null;
|
|
1879
|
+
this.infoDestroy = null;
|
|
2104
1880
|
this.placeInfoReq = {
|
|
2105
1881
|
read: () => this.measureInfo(),
|
|
2106
1882
|
write: (pos) => this.placeInfo(pos),
|
|
@@ -2121,7 +1897,7 @@ class CompletionTooltip {
|
|
|
2121
1897
|
this.dom.addEventListener("mousedown", (e) => {
|
|
2122
1898
|
for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
|
|
2123
1899
|
if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
|
|
2124
|
-
applyCompletion(view, options[+match[1]]);
|
|
1900
|
+
this.applyCompletion(view, options[+match[1]]);
|
|
2125
1901
|
e.preventDefault();
|
|
2126
1902
|
return;
|
|
2127
1903
|
}
|
|
@@ -2180,33 +1956,39 @@ class CompletionTooltip {
|
|
|
2180
1956
|
});
|
|
2181
1957
|
}
|
|
2182
1958
|
if (this.updateSelectedOption(open.selected)) {
|
|
2183
|
-
|
|
2184
|
-
this.info.remove();
|
|
2185
|
-
this.info = null;
|
|
2186
|
-
}
|
|
1959
|
+
this.destroyInfo();
|
|
2187
1960
|
let { completion } = open.options[open.selected];
|
|
2188
1961
|
let { info } = completion;
|
|
2189
1962
|
if (!info)
|
|
2190
1963
|
return;
|
|
2191
|
-
let infoResult = typeof info ===
|
|
1964
|
+
let infoResult = typeof info === "string" ? document.createTextNode(info) : info(completion);
|
|
2192
1965
|
if (!infoResult)
|
|
2193
1966
|
return;
|
|
2194
|
-
if (
|
|
2195
|
-
infoResult.then(
|
|
2196
|
-
if (
|
|
2197
|
-
this.addInfoPane(
|
|
1967
|
+
if ("then" in infoResult) {
|
|
1968
|
+
infoResult.then(obj => {
|
|
1969
|
+
if (obj && this.view.state.field(this.stateField, false) == cState)
|
|
1970
|
+
this.addInfoPane(obj, completion);
|
|
2198
1971
|
}).catch(e => (0,view_.logException)(this.view.state, e, "completion info"));
|
|
2199
1972
|
}
|
|
2200
1973
|
else {
|
|
2201
|
-
this.addInfoPane(infoResult);
|
|
1974
|
+
this.addInfoPane(infoResult, completion);
|
|
2202
1975
|
}
|
|
2203
1976
|
}
|
|
2204
1977
|
}
|
|
2205
|
-
addInfoPane(content) {
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
1978
|
+
addInfoPane(content, completion) {
|
|
1979
|
+
this.destroyInfo();
|
|
1980
|
+
let wrap = this.info = document.createElement("div");
|
|
1981
|
+
wrap.className = "cm-tooltip cm-completionInfo";
|
|
1982
|
+
if (content.nodeType != null) {
|
|
1983
|
+
wrap.appendChild(content);
|
|
1984
|
+
this.infoDestroy = null;
|
|
1985
|
+
}
|
|
1986
|
+
else {
|
|
1987
|
+
let { dom, destroy } = content;
|
|
1988
|
+
wrap.appendChild(dom);
|
|
1989
|
+
this.infoDestroy = destroy || null;
|
|
1990
|
+
}
|
|
1991
|
+
this.dom.appendChild(wrap);
|
|
2210
1992
|
this.view.requestMeasure(this.placeInfoReq);
|
|
2211
1993
|
}
|
|
2212
1994
|
updateSelectedOption(selected) {
|
|
@@ -2299,11 +2081,22 @@ class CompletionTooltip {
|
|
|
2299
2081
|
ul.classList.add("cm-completionListIncompleteBottom");
|
|
2300
2082
|
return ul;
|
|
2301
2083
|
}
|
|
2084
|
+
destroyInfo() {
|
|
2085
|
+
if (this.info) {
|
|
2086
|
+
if (this.infoDestroy)
|
|
2087
|
+
this.infoDestroy();
|
|
2088
|
+
this.info.remove();
|
|
2089
|
+
this.info = null;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
destroy() {
|
|
2093
|
+
this.destroyInfo();
|
|
2094
|
+
}
|
|
2302
2095
|
}
|
|
2303
2096
|
// We allocate a new function instance every time the completion
|
|
2304
2097
|
// changes to force redrawing/repositioning of the tooltip
|
|
2305
|
-
function completionTooltip(stateField) {
|
|
2306
|
-
return (view) => new CompletionTooltip(view, stateField);
|
|
2098
|
+
function completionTooltip(stateField, applyCompletion) {
|
|
2099
|
+
return (view) => new CompletionTooltip(view, stateField, applyCompletion);
|
|
2307
2100
|
}
|
|
2308
2101
|
function scrollIntoView(container, element) {
|
|
2309
2102
|
let parent = container.getBoundingClientRect();
|
|
@@ -2370,9 +2163,10 @@ function sortOptions(active, state) {
|
|
|
2370
2163
|
let result = [], prev = null;
|
|
2371
2164
|
let compare = state.facet(completionConfig).compareCompletions;
|
|
2372
2165
|
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
prev.
|
|
2166
|
+
let cur = opt.completion;
|
|
2167
|
+
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
|
|
2168
|
+
(prev.type != null && cur.type != null && prev.type != cur.type) ||
|
|
2169
|
+
prev.apply != cur.apply || prev.boost != cur.boost)
|
|
2376
2170
|
result.push(opt);
|
|
2377
2171
|
else if (score(opt.completion) > score(prev))
|
|
2378
2172
|
result[result.length - 1] = opt;
|
|
@@ -2396,7 +2190,7 @@ class CompletionDialog {
|
|
|
2396
2190
|
static build(active, state, id, prev, conf) {
|
|
2397
2191
|
let options = sortOptions(active, state);
|
|
2398
2192
|
if (!options.length) {
|
|
2399
|
-
return prev && active.some(a => a.state == 1 /*
|
|
2193
|
+
return prev && active.some(a => a.state == 1 /* Pending */) ?
|
|
2400
2194
|
new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
|
|
2401
2195
|
}
|
|
2402
2196
|
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
|
|
@@ -2410,7 +2204,7 @@ class CompletionDialog {
|
|
|
2410
2204
|
}
|
|
2411
2205
|
return new CompletionDialog(options, makeAttrs(id, selected), {
|
|
2412
2206
|
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
2413
|
-
create: completionTooltip(completionState),
|
|
2207
|
+
create: completionTooltip(completionState, applyCompletion),
|
|
2414
2208
|
above: conf.aboveCursor,
|
|
2415
2209
|
}, prev ? prev.timestamp : Date.now(), selected, false);
|
|
2416
2210
|
}
|
|
@@ -2433,7 +2227,7 @@ class CompletionState {
|
|
|
2433
2227
|
state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
|
2434
2228
|
let active = sources.map(source => {
|
|
2435
2229
|
let value = this.active.find(s => s.source == source) ||
|
|
2436
|
-
new ActiveSource(source, this.active.some(a => a.state != 0 /*
|
|
2230
|
+
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
|
|
2437
2231
|
return value.update(tr, conf);
|
|
2438
2232
|
});
|
|
2439
2233
|
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
|
|
@@ -2444,10 +2238,10 @@ class CompletionState {
|
|
|
2444
2238
|
if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
|
|
2445
2239
|
!sameResults(active, this.active))
|
|
2446
2240
|
open = CompletionDialog.build(active, state, this.id, open, conf);
|
|
2447
|
-
else if (open && open.disabled && !active.some(a => a.state == 1 /*
|
|
2241
|
+
else if (open && open.disabled && !active.some(a => a.state == 1 /* Pending */))
|
|
2448
2242
|
open = null;
|
|
2449
|
-
if (!open && active.every(a => a.state != 1 /*
|
|
2450
|
-
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /*
|
|
2243
|
+
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
|
|
2244
|
+
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
|
|
2451
2245
|
for (let effect of tr.effects)
|
|
2452
2246
|
if (effect.is(setSelectedEffect))
|
|
2453
2247
|
open = open && open.setSelected(effect.value, this.id);
|
|
@@ -2501,13 +2295,13 @@ class ActiveSource {
|
|
|
2501
2295
|
value = value.handleUserEvent(tr, event, conf);
|
|
2502
2296
|
else if (tr.docChanged)
|
|
2503
2297
|
value = value.handleChange(tr);
|
|
2504
|
-
else if (tr.selection && value.state != 0 /*
|
|
2505
|
-
value = new ActiveSource(value.source, 0 /*
|
|
2298
|
+
else if (tr.selection && value.state != 0 /* Inactive */)
|
|
2299
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
2506
2300
|
for (let effect of tr.effects) {
|
|
2507
2301
|
if (effect.is(startCompletionEffect))
|
|
2508
|
-
value = new ActiveSource(value.source, 1 /*
|
|
2302
|
+
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
|
|
2509
2303
|
else if (effect.is(closeCompletionEffect))
|
|
2510
|
-
value = new ActiveSource(value.source, 0 /*
|
|
2304
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
2511
2305
|
else if (effect.is(setActiveEffect))
|
|
2512
2306
|
for (let active of effect.value)
|
|
2513
2307
|
if (active.source == value.source)
|
|
@@ -2516,10 +2310,10 @@ class ActiveSource {
|
|
|
2516
2310
|
return value;
|
|
2517
2311
|
}
|
|
2518
2312
|
handleUserEvent(tr, type, conf) {
|
|
2519
|
-
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /*
|
|
2313
|
+
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
|
|
2520
2314
|
}
|
|
2521
2315
|
handleChange(tr) {
|
|
2522
|
-
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /*
|
|
2316
|
+
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
2523
2317
|
}
|
|
2524
2318
|
map(changes) {
|
|
2525
2319
|
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
|
|
@@ -2527,7 +2321,7 @@ class ActiveSource {
|
|
|
2527
2321
|
}
|
|
2528
2322
|
class ActiveResult extends ActiveSource {
|
|
2529
2323
|
constructor(source, explicitPos, result, from, to) {
|
|
2530
|
-
super(source, 2 /*
|
|
2324
|
+
super(source, 2 /* Result */, explicitPos);
|
|
2531
2325
|
this.result = result;
|
|
2532
2326
|
this.from = from;
|
|
2533
2327
|
this.to = to;
|
|
@@ -2540,17 +2334,17 @@ class ActiveResult extends ActiveSource {
|
|
|
2540
2334
|
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
|
2541
2335
|
pos > to ||
|
|
2542
2336
|
type == "delete" && cur(tr.startState) == this.from)
|
|
2543
|
-
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /*
|
|
2337
|
+
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
2544
2338
|
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
|
|
2545
2339
|
if (checkValid(this.result.validFor, tr.state, from, to))
|
|
2546
2340
|
return new ActiveResult(this.source, explicitPos, this.result, from, to);
|
|
2547
2341
|
if (this.result.update &&
|
|
2548
2342
|
(updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
|
|
2549
2343
|
return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
|
|
2550
|
-
return new ActiveSource(this.source, 1 /*
|
|
2344
|
+
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
|
|
2551
2345
|
}
|
|
2552
2346
|
handleChange(tr) {
|
|
2553
|
-
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /*
|
|
2347
|
+
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
2554
2348
|
}
|
|
2555
2349
|
map(mapping) {
|
|
2556
2350
|
return mapping.empty ? this :
|
|
@@ -2575,6 +2369,230 @@ const completionState = /*@__PURE__*/state_.StateField.define({
|
|
|
2575
2369
|
view_.EditorView.contentAttributes.from(f, state => state.attrs)
|
|
2576
2370
|
]
|
|
2577
2371
|
});
|
|
2372
|
+
function applyCompletion(view, option) {
|
|
2373
|
+
const apply = option.completion.apply || option.completion.label;
|
|
2374
|
+
let result = view.state.field(completionState).active.find(a => a.source == option.source);
|
|
2375
|
+
if (!(result instanceof ActiveResult))
|
|
2376
|
+
return false;
|
|
2377
|
+
if (typeof apply == "string")
|
|
2378
|
+
view.dispatch(Object.assign(Object.assign({}, insertCompletionText(view.state, apply, result.from, result.to)), { annotations: pickedCompletion.of(option.completion) }));
|
|
2379
|
+
else
|
|
2380
|
+
apply(view, option.completion, result.from, result.to);
|
|
2381
|
+
return true;
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
/**
|
|
2385
|
+
Returns a command that moves the completion selection forward or
|
|
2386
|
+
backward by the given amount.
|
|
2387
|
+
*/
|
|
2388
|
+
function moveCompletionSelection(forward, by = "option") {
|
|
2389
|
+
return (view) => {
|
|
2390
|
+
let cState = view.state.field(completionState, false);
|
|
2391
|
+
if (!cState || !cState.open || cState.open.disabled ||
|
|
2392
|
+
Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
|
|
2393
|
+
return false;
|
|
2394
|
+
let step = 1, tooltip;
|
|
2395
|
+
if (by == "page" && (tooltip = (0,view_.getTooltip)(view, cState.open.tooltip)))
|
|
2396
|
+
step = Math.max(2, Math.floor(tooltip.dom.offsetHeight /
|
|
2397
|
+
tooltip.dom.querySelector("li").offsetHeight) - 1);
|
|
2398
|
+
let { length } = cState.open.options;
|
|
2399
|
+
let selected = cState.open.selected > -1 ? cState.open.selected + step * (forward ? 1 : -1) : forward ? 0 : length - 1;
|
|
2400
|
+
if (selected < 0)
|
|
2401
|
+
selected = by == "page" ? 0 : length - 1;
|
|
2402
|
+
else if (selected >= length)
|
|
2403
|
+
selected = by == "page" ? length - 1 : 0;
|
|
2404
|
+
view.dispatch({ effects: setSelectedEffect.of(selected) });
|
|
2405
|
+
return true;
|
|
2406
|
+
};
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
Accept the current completion.
|
|
2410
|
+
*/
|
|
2411
|
+
const acceptCompletion = (view) => {
|
|
2412
|
+
let cState = view.state.field(completionState, false);
|
|
2413
|
+
if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 || cState.open.disabled ||
|
|
2414
|
+
Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
|
|
2415
|
+
return false;
|
|
2416
|
+
return applyCompletion(view, cState.open.options[cState.open.selected]);
|
|
2417
|
+
};
|
|
2418
|
+
/**
|
|
2419
|
+
Explicitly start autocompletion.
|
|
2420
|
+
*/
|
|
2421
|
+
const startCompletion = (view) => {
|
|
2422
|
+
let cState = view.state.field(completionState, false);
|
|
2423
|
+
if (!cState)
|
|
2424
|
+
return false;
|
|
2425
|
+
view.dispatch({ effects: startCompletionEffect.of(true) });
|
|
2426
|
+
return true;
|
|
2427
|
+
};
|
|
2428
|
+
/**
|
|
2429
|
+
Close the currently active completion.
|
|
2430
|
+
*/
|
|
2431
|
+
const closeCompletion = (view) => {
|
|
2432
|
+
let cState = view.state.field(completionState, false);
|
|
2433
|
+
if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
|
|
2434
|
+
return false;
|
|
2435
|
+
view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
2436
|
+
return true;
|
|
2437
|
+
};
|
|
2438
|
+
class RunningQuery {
|
|
2439
|
+
constructor(active, context) {
|
|
2440
|
+
this.active = active;
|
|
2441
|
+
this.context = context;
|
|
2442
|
+
this.time = Date.now();
|
|
2443
|
+
this.updates = [];
|
|
2444
|
+
// Note that 'undefined' means 'not done yet', whereas 'null' means
|
|
2445
|
+
// 'query returned null'.
|
|
2446
|
+
this.done = undefined;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
|
|
2450
|
+
const completionPlugin = /*@__PURE__*/view_.ViewPlugin.fromClass(class {
|
|
2451
|
+
constructor(view) {
|
|
2452
|
+
this.view = view;
|
|
2453
|
+
this.debounceUpdate = -1;
|
|
2454
|
+
this.running = [];
|
|
2455
|
+
this.debounceAccept = -1;
|
|
2456
|
+
this.composing = 0 /* None */;
|
|
2457
|
+
for (let active of view.state.field(completionState).active)
|
|
2458
|
+
if (active.state == 1 /* Pending */)
|
|
2459
|
+
this.startQuery(active);
|
|
2460
|
+
}
|
|
2461
|
+
update(update) {
|
|
2462
|
+
let cState = update.state.field(completionState);
|
|
2463
|
+
if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
|
|
2464
|
+
return;
|
|
2465
|
+
let doesReset = update.transactions.some(tr => {
|
|
2466
|
+
return (tr.selection || tr.docChanged) && !getUserEvent(tr);
|
|
2467
|
+
});
|
|
2468
|
+
for (let i = 0; i < this.running.length; i++) {
|
|
2469
|
+
let query = this.running[i];
|
|
2470
|
+
if (doesReset ||
|
|
2471
|
+
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
2472
|
+
for (let handler of query.context.abortListeners) {
|
|
2473
|
+
try {
|
|
2474
|
+
handler();
|
|
2475
|
+
}
|
|
2476
|
+
catch (e) {
|
|
2477
|
+
(0,view_.logException)(this.view.state, e);
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
query.context.abortListeners = null;
|
|
2481
|
+
this.running.splice(i--, 1);
|
|
2482
|
+
}
|
|
2483
|
+
else {
|
|
2484
|
+
query.updates.push(...update.transactions);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
if (this.debounceUpdate > -1)
|
|
2488
|
+
clearTimeout(this.debounceUpdate);
|
|
2489
|
+
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
2490
|
+
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
|
2491
|
+
if (this.composing != 0 /* None */)
|
|
2492
|
+
for (let tr of update.transactions) {
|
|
2493
|
+
if (getUserEvent(tr) == "input")
|
|
2494
|
+
this.composing = 2 /* Changed */;
|
|
2495
|
+
else if (this.composing == 2 /* Changed */ && tr.selection)
|
|
2496
|
+
this.composing = 3 /* ChangedAndMoved */;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
startUpdate() {
|
|
2500
|
+
this.debounceUpdate = -1;
|
|
2501
|
+
let { state } = this.view, cState = state.field(completionState);
|
|
2502
|
+
for (let active of cState.active) {
|
|
2503
|
+
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
2504
|
+
this.startQuery(active);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
startQuery(active) {
|
|
2508
|
+
let { state } = this.view, pos = cur(state);
|
|
2509
|
+
let context = new CompletionContext(state, pos, active.explicitPos == pos);
|
|
2510
|
+
let pending = new RunningQuery(active, context);
|
|
2511
|
+
this.running.push(pending);
|
|
2512
|
+
Promise.resolve(active.source(context)).then(result => {
|
|
2513
|
+
if (!pending.context.aborted) {
|
|
2514
|
+
pending.done = result || null;
|
|
2515
|
+
this.scheduleAccept();
|
|
2516
|
+
}
|
|
2517
|
+
}, err => {
|
|
2518
|
+
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
2519
|
+
(0,view_.logException)(this.view.state, err);
|
|
2520
|
+
});
|
|
2521
|
+
}
|
|
2522
|
+
scheduleAccept() {
|
|
2523
|
+
if (this.running.every(q => q.done !== undefined))
|
|
2524
|
+
this.accept();
|
|
2525
|
+
else if (this.debounceAccept < 0)
|
|
2526
|
+
this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
|
|
2527
|
+
}
|
|
2528
|
+
// For each finished query in this.running, try to create a result
|
|
2529
|
+
// or, if appropriate, restart the query.
|
|
2530
|
+
accept() {
|
|
2531
|
+
var _a;
|
|
2532
|
+
if (this.debounceAccept > -1)
|
|
2533
|
+
clearTimeout(this.debounceAccept);
|
|
2534
|
+
this.debounceAccept = -1;
|
|
2535
|
+
let updated = [];
|
|
2536
|
+
let conf = this.view.state.facet(completionConfig);
|
|
2537
|
+
for (let i = 0; i < this.running.length; i++) {
|
|
2538
|
+
let query = this.running[i];
|
|
2539
|
+
if (query.done === undefined)
|
|
2540
|
+
continue;
|
|
2541
|
+
this.running.splice(i--, 1);
|
|
2542
|
+
if (query.done) {
|
|
2543
|
+
let active = new ActiveResult(query.active.source, query.active.explicitPos, query.done, query.done.from, (_a = query.done.to) !== null && _a !== void 0 ? _a : cur(query.updates.length ? query.updates[0].startState : this.view.state));
|
|
2544
|
+
// Replay the transactions that happened since the start of
|
|
2545
|
+
// the request and see if that preserves the result
|
|
2546
|
+
for (let tr of query.updates)
|
|
2547
|
+
active = active.update(tr, conf);
|
|
2548
|
+
if (active.hasResult()) {
|
|
2549
|
+
updated.push(active);
|
|
2550
|
+
continue;
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
|
2554
|
+
if (current && current.state == 1 /* Pending */) {
|
|
2555
|
+
if (query.done == null) {
|
|
2556
|
+
// Explicitly failed. Should clear the pending status if it
|
|
2557
|
+
// hasn't been re-set in the meantime.
|
|
2558
|
+
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
|
|
2559
|
+
for (let tr of query.updates)
|
|
2560
|
+
active = active.update(tr, conf);
|
|
2561
|
+
if (active.state != 1 /* Pending */)
|
|
2562
|
+
updated.push(active);
|
|
2563
|
+
}
|
|
2564
|
+
else {
|
|
2565
|
+
// Cleared by subsequent transactions. Restart.
|
|
2566
|
+
this.startQuery(current);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
if (updated.length)
|
|
2571
|
+
this.view.dispatch({ effects: setActiveEffect.of(updated) });
|
|
2572
|
+
}
|
|
2573
|
+
}, {
|
|
2574
|
+
eventHandlers: {
|
|
2575
|
+
blur(event) {
|
|
2576
|
+
let state = this.view.state.field(completionState, false);
|
|
2577
|
+
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
|
2578
|
+
let dialog = state.open && (0,view_.getTooltip)(this.view, state.open.tooltip);
|
|
2579
|
+
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
|
2580
|
+
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
2581
|
+
}
|
|
2582
|
+
},
|
|
2583
|
+
compositionstart() {
|
|
2584
|
+
this.composing = 1 /* Started */;
|
|
2585
|
+
},
|
|
2586
|
+
compositionend() {
|
|
2587
|
+
if (this.composing == 3 /* ChangedAndMoved */) {
|
|
2588
|
+
// Safari fires compositionend events synchronously, possibly
|
|
2589
|
+
// from inside an update, so dispatch asynchronously to avoid reentrancy
|
|
2590
|
+
setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
|
|
2591
|
+
}
|
|
2592
|
+
this.composing = 0 /* None */;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
});
|
|
2578
2596
|
|
|
2579
2597
|
const dist_baseTheme = /*@__PURE__*/view_.EditorView.baseTheme({
|
|
2580
2598
|
".cm-tooltip.cm-tooltip-autocomplete": {
|
|
@@ -2631,13 +2649,13 @@ const dist_baseTheme = /*@__PURE__*/view_.EditorView.baseTheme({
|
|
|
2631
2649
|
position: "absolute",
|
|
2632
2650
|
padding: "3px 9px",
|
|
2633
2651
|
width: "max-content",
|
|
2634
|
-
maxWidth: `${400 /*
|
|
2652
|
+
maxWidth: `${400 /* Width */}px`,
|
|
2635
2653
|
boxSizing: "border-box"
|
|
2636
2654
|
},
|
|
2637
2655
|
".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
|
|
2638
2656
|
".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
|
|
2639
|
-
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /*
|
|
2640
|
-
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /*
|
|
2657
|
+
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Margin */}px` },
|
|
2658
|
+
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Margin */}px` },
|
|
2641
2659
|
"&light .cm-snippetField": { backgroundColor: "#00000022" },
|
|
2642
2660
|
"&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
|
|
2643
2661
|
".cm-snippetFieldPosition": {
|
|
@@ -2990,7 +3008,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|
|
2990
3008
|
if (!seen[m[0]] && pos + m.index != ignoreAt) {
|
|
2991
3009
|
result.push({ type: "text", label: m[0] });
|
|
2992
3010
|
seen[m[0]] = true;
|
|
2993
|
-
if (result.length >= 2000 /*
|
|
3011
|
+
if (result.length >= 2000 /* MaxList */)
|
|
2994
3012
|
return;
|
|
2995
3013
|
}
|
|
2996
3014
|
}
|
|
@@ -2998,7 +3016,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
|
|
|
2998
3016
|
}
|
|
2999
3017
|
}
|
|
3000
3018
|
function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|
3001
|
-
let big = doc.length >= 1000 /*
|
|
3019
|
+
let big = doc.length >= 1000 /* MinCacheLen */;
|
|
3002
3020
|
let cached = big && cache.get(doc);
|
|
3003
3021
|
if (cached)
|
|
3004
3022
|
return cached;
|
|
@@ -3006,7 +3024,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|
|
3006
3024
|
if (doc.children) {
|
|
3007
3025
|
let pos = 0;
|
|
3008
3026
|
for (let ch of doc.children) {
|
|
3009
|
-
if (ch.length >= 1000 /*
|
|
3027
|
+
if (ch.length >= 1000 /* MinCacheLen */) {
|
|
3010
3028
|
for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
|
|
3011
3029
|
if (!seen[c.label]) {
|
|
3012
3030
|
seen[c.label] = true;
|
|
@@ -3023,7 +3041,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
|
|
|
3023
3041
|
else {
|
|
3024
3042
|
storeWords(doc, wordRE, result, seen, ignoreAt);
|
|
3025
3043
|
}
|
|
3026
|
-
if (big && result.length < 2000 /*
|
|
3044
|
+
if (big && result.length < 2000 /* MaxList */)
|
|
3027
3045
|
cache.set(doc, result);
|
|
3028
3046
|
return result;
|
|
3029
3047
|
}
|
|
@@ -3039,7 +3057,7 @@ const completeAnyWord = context => {
|
|
|
3039
3057
|
if (!token && !context.explicit)
|
|
3040
3058
|
return null;
|
|
3041
3059
|
let from = token ? token.from : context.pos;
|
|
3042
|
-
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /*
|
|
3060
|
+
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
|
|
3043
3061
|
return { from, options, validFor: mapRE(re, s => "^" + s) };
|
|
3044
3062
|
};
|
|
3045
3063
|
|
|
@@ -3331,8 +3349,8 @@ returns `null`.
|
|
|
3331
3349
|
*/
|
|
3332
3350
|
function completionStatus(state) {
|
|
3333
3351
|
let cState = state.field(completionState, false);
|
|
3334
|
-
return cState && cState.active.some(a => a.state == 1 /*
|
|
3335
|
-
: cState && cState.active.some(a => a.state != 0 /*
|
|
3352
|
+
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
|
|
3353
|
+
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
|
|
3336
3354
|
}
|
|
3337
3355
|
const completionArrayCache = /*@__PURE__*/new WeakMap;
|
|
3338
3356
|
/**
|
|
@@ -3552,6 +3570,30 @@ const nextDiagnostic = (view) => {
|
|
|
3552
3570
|
return true;
|
|
3553
3571
|
};
|
|
3554
3572
|
/**
|
|
3573
|
+
Move the selection to the previous diagnostic.
|
|
3574
|
+
*/
|
|
3575
|
+
const previousDiagnostic = (view) => {
|
|
3576
|
+
let { state } = view, field = state.field(lintState, false);
|
|
3577
|
+
if (!field)
|
|
3578
|
+
return false;
|
|
3579
|
+
let sel = state.selection.main;
|
|
3580
|
+
let prevFrom, prevTo, lastFrom, lastTo;
|
|
3581
|
+
field.diagnostics.between(0, state.doc.length, (from, to) => {
|
|
3582
|
+
if (to < sel.to && (prevFrom == null || prevFrom < from)) {
|
|
3583
|
+
prevFrom = from;
|
|
3584
|
+
prevTo = to;
|
|
3585
|
+
}
|
|
3586
|
+
if (lastFrom == null || from > lastFrom) {
|
|
3587
|
+
lastFrom = from;
|
|
3588
|
+
lastTo = to;
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
if (lastFrom == null || prevFrom == null && lastFrom == sel.from)
|
|
3592
|
+
return false;
|
|
3593
|
+
view.dispatch({ selection: { anchor: prevFrom !== null && prevFrom !== void 0 ? prevFrom : lastFrom, head: prevTo !== null && prevTo !== void 0 ? prevTo : lastTo }, scrollIntoView: true });
|
|
3594
|
+
return true;
|
|
3595
|
+
};
|
|
3596
|
+
/**
|
|
3555
3597
|
A set of default key bindings for the lint functionality.
|
|
3556
3598
|
|
|
3557
3599
|
- Ctrl-Shift-m (Cmd-Shift-m on macOS): [`openLintPanel`](https://codemirror.net/6/docs/ref/#lint.openLintPanel)
|