@codemirror/autocomplete 0.18.7 → 0.18.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.cjs +59 -41
- package/dist/index.d.ts +17 -4
- package/dist/index.js +59 -42
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.18.8 (2021-06-30)
|
|
2
|
+
|
|
3
|
+
### New features
|
|
4
|
+
|
|
5
|
+
Add an `ifIn` helper function that constrains a completion source to only fire when in a given syntax node. Add support for unfiltered completions
|
|
6
|
+
|
|
7
|
+
A completion result can now set a `filter: false` property to disable filtering and sorting of completions, when it already did so itself.
|
|
8
|
+
|
|
1
9
|
## 0.18.7 (2021-06-14)
|
|
2
10
|
|
|
3
11
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -109,6 +109,18 @@ function completeFromList(list) {
|
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
+
Wrap the given completion source so that it will only fire when the
|
|
113
|
+
cursor is in a syntax node with one of the given names.
|
|
114
|
+
*/
|
|
115
|
+
function ifIn(nodes, source) {
|
|
116
|
+
return (context) => {
|
|
117
|
+
for (let pos = language.syntaxTree(context.state).resolve(context.pos, -1); pos; pos = pos.parent)
|
|
118
|
+
if (nodes.indexOf(pos.name) > -1)
|
|
119
|
+
return source(context);
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
112
124
|
Wrap the given completion source so that it will not fire when the
|
|
113
125
|
cursor is in a syntax node with one of the given names.
|
|
114
126
|
*/
|
|
@@ -588,16 +600,22 @@ function score(option) {
|
|
|
588
600
|
(option.type ? 1 : 0);
|
|
589
601
|
}
|
|
590
602
|
function sortOptions(active, state) {
|
|
591
|
-
let options = [];
|
|
603
|
+
let options = [], i = 0;
|
|
592
604
|
for (let a of active)
|
|
593
605
|
if (a.hasResult()) {
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
606
|
+
if (a.result.filter === false) {
|
|
607
|
+
for (let option of a.result.options)
|
|
608
|
+
options.push(new Option(option, a, [1e9 - i++]));
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
|
|
612
|
+
for (let option of a.result.options)
|
|
613
|
+
if (match = matcher.match(option.label)) {
|
|
614
|
+
if (option.boost != null)
|
|
615
|
+
match[0] += option.boost;
|
|
616
|
+
options.push(new Option(option, a, match));
|
|
617
|
+
}
|
|
618
|
+
}
|
|
601
619
|
}
|
|
602
620
|
options.sort(cmpOption);
|
|
603
621
|
let result = [], prev = null;
|
|
@@ -660,7 +678,7 @@ class CompletionState {
|
|
|
660
678
|
state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
|
661
679
|
let active = sources.map(source => {
|
|
662
680
|
let value = this.active.find(s => s.source == source) ||
|
|
663
|
-
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive
|
|
681
|
+
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
|
|
664
682
|
return value.update(tr, conf);
|
|
665
683
|
});
|
|
666
684
|
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
|
|
@@ -669,7 +687,7 @@ class CompletionState {
|
|
|
669
687
|
!sameResults(active, this.active) ? CompletionDialog.build(active, state, this.id, this.open)
|
|
670
688
|
: this.open && tr.docChanged ? this.open.map(tr.changes) : this.open;
|
|
671
689
|
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
|
|
672
|
-
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive
|
|
690
|
+
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
|
|
673
691
|
for (let effect of tr.effects)
|
|
674
692
|
if (effect.is(setSelectedEffect))
|
|
675
693
|
open = open && open.setSelected(effect.value, this.id);
|
|
@@ -709,13 +727,12 @@ function cmpOption(a, b) {
|
|
|
709
727
|
return lA < lB ? -1 : lA == lB ? 0 : 1;
|
|
710
728
|
}
|
|
711
729
|
class ActiveSource {
|
|
712
|
-
constructor(source, state,
|
|
730
|
+
constructor(source, state, explicitPos = -1) {
|
|
713
731
|
this.source = source;
|
|
714
732
|
this.state = state;
|
|
715
|
-
this.
|
|
733
|
+
this.explicitPos = explicitPos;
|
|
716
734
|
}
|
|
717
735
|
hasResult() { return false; }
|
|
718
|
-
explicitAt(_pos) { return this.explicit; }
|
|
719
736
|
update(tr, conf) {
|
|
720
737
|
let event = tr.annotation(state.Transaction.userEvent), value = this;
|
|
721
738
|
if (event == "input" || event == "delete")
|
|
@@ -723,12 +740,12 @@ class ActiveSource {
|
|
|
723
740
|
else if (tr.docChanged)
|
|
724
741
|
value = value.handleChange(tr);
|
|
725
742
|
else if (tr.selection && value.state != 0 /* Inactive */)
|
|
726
|
-
value = new ActiveSource(value.source, 0 /* Inactive
|
|
743
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
727
744
|
for (let effect of tr.effects) {
|
|
728
745
|
if (effect.is(startCompletionEffect))
|
|
729
|
-
value = new ActiveSource(value.source, 1 /* Pending */, effect.value);
|
|
746
|
+
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
|
|
730
747
|
else if (effect.is(closeCompletionEffect))
|
|
731
|
-
value = new ActiveSource(value.source, 0 /* Inactive
|
|
748
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
732
749
|
else if (effect.is(setActiveEffect))
|
|
733
750
|
for (let active of effect.value)
|
|
734
751
|
if (active.source == value.source)
|
|
@@ -736,47 +753,47 @@ class ActiveSource {
|
|
|
736
753
|
}
|
|
737
754
|
return value;
|
|
738
755
|
}
|
|
739
|
-
handleUserEvent(
|
|
740
|
-
return type == "delete" || !conf.activateOnTyping ? this : new ActiveSource(this.source, 1 /* Pending
|
|
756
|
+
handleUserEvent(tr, type, conf) {
|
|
757
|
+
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
|
|
741
758
|
}
|
|
742
759
|
handleChange(tr) {
|
|
743
|
-
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive
|
|
760
|
+
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
761
|
+
}
|
|
762
|
+
map(changes) {
|
|
763
|
+
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
|
|
744
764
|
}
|
|
745
765
|
}
|
|
746
766
|
class ActiveResult extends ActiveSource {
|
|
747
767
|
constructor(source, explicitPos, result, from, to, span) {
|
|
748
|
-
super(source, 2 /* Result */, explicitPos
|
|
749
|
-
this.explicitPos = explicitPos;
|
|
768
|
+
super(source, 2 /* Result */, explicitPos);
|
|
750
769
|
this.result = result;
|
|
751
770
|
this.from = from;
|
|
752
771
|
this.to = to;
|
|
753
772
|
this.span = span;
|
|
754
773
|
}
|
|
755
774
|
hasResult() { return true; }
|
|
756
|
-
explicitAt(pos) { return this.explicitPos == pos; }
|
|
757
|
-
mapExplicit(mapping) {
|
|
758
|
-
return this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos);
|
|
759
|
-
}
|
|
760
775
|
handleUserEvent(tr, type, conf) {
|
|
761
776
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
762
777
|
let pos = cur(tr.state);
|
|
763
|
-
if ((this.
|
|
764
|
-
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive
|
|
778
|
+
if ((this.explicitPos > -1 ? pos < from : pos <= from) || pos > to)
|
|
779
|
+
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
780
|
+
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
765
781
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
766
|
-
return new ActiveResult(this.source,
|
|
767
|
-
return new ActiveSource(this.source, 1 /* Pending */,
|
|
782
|
+
return new ActiveResult(this.source, explicitPos, this.result, from, to, this.span);
|
|
783
|
+
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
|
|
768
784
|
}
|
|
769
785
|
handleChange(tr) {
|
|
770
|
-
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive
|
|
786
|
+
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
771
787
|
}
|
|
772
788
|
map(mapping) {
|
|
773
|
-
return
|
|
789
|
+
return mapping.empty ? this :
|
|
790
|
+
new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1), this.span);
|
|
774
791
|
}
|
|
775
792
|
}
|
|
776
793
|
const startCompletionEffect = state.StateEffect.define();
|
|
777
794
|
const closeCompletionEffect = state.StateEffect.define();
|
|
778
795
|
const setActiveEffect = state.StateEffect.define({
|
|
779
|
-
map(sources, mapping) { return sources.map(s => s.
|
|
796
|
+
map(sources, mapping) { return sources.map(s => s.map(mapping)); }
|
|
780
797
|
});
|
|
781
798
|
const setSelectedEffect = state.StateEffect.define();
|
|
782
799
|
const completionState = state.StateField.define({
|
|
@@ -841,8 +858,8 @@ const closeCompletion = (view) => {
|
|
|
841
858
|
return true;
|
|
842
859
|
};
|
|
843
860
|
class RunningQuery {
|
|
844
|
-
constructor(
|
|
845
|
-
this.
|
|
861
|
+
constructor(active, context) {
|
|
862
|
+
this.active = active;
|
|
846
863
|
this.context = context;
|
|
847
864
|
this.time = Date.now();
|
|
848
865
|
this.updates = [];
|
|
@@ -892,7 +909,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
892
909
|
}
|
|
893
910
|
if (this.debounceUpdate > -1)
|
|
894
911
|
clearTimeout(this.debounceUpdate);
|
|
895
|
-
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.source == a.source))
|
|
912
|
+
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
896
913
|
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
|
897
914
|
if (this.composing != 0 /* None */)
|
|
898
915
|
for (let tr of update.transactions) {
|
|
@@ -906,14 +923,14 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
906
923
|
this.debounceUpdate = -1;
|
|
907
924
|
let { state } = this.view, cState = state.field(completionState);
|
|
908
925
|
for (let active of cState.active) {
|
|
909
|
-
if (active.state == 1 /* Pending */ && !this.running.some(r => r.source == active.source))
|
|
926
|
+
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
910
927
|
this.startQuery(active);
|
|
911
928
|
}
|
|
912
929
|
}
|
|
913
930
|
startQuery(active) {
|
|
914
931
|
let { state } = this.view, pos = cur(state);
|
|
915
|
-
let context = new CompletionContext(state, pos, active.
|
|
916
|
-
let pending = new RunningQuery(active
|
|
932
|
+
let context = new CompletionContext(state, pos, active.explicitPos == pos);
|
|
933
|
+
let pending = new RunningQuery(active, context);
|
|
917
934
|
this.running.push(pending);
|
|
918
935
|
Promise.resolve(active.source(context)).then(result => {
|
|
919
936
|
if (!pending.context.aborted) {
|
|
@@ -946,7 +963,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
946
963
|
continue;
|
|
947
964
|
this.running.splice(i--, 1);
|
|
948
965
|
if (query.done) {
|
|
949
|
-
let active = new ActiveResult(query.source, query.
|
|
966
|
+
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), query.done.span && query.done.filter !== false ? ensureAnchor(query.done.span, true) : null);
|
|
950
967
|
// Replay the transactions that happened since the start of
|
|
951
968
|
// the request and see if that preserves the result
|
|
952
969
|
for (let tr of query.updates)
|
|
@@ -956,12 +973,12 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
956
973
|
continue;
|
|
957
974
|
}
|
|
958
975
|
}
|
|
959
|
-
let current = this.view.state.field(completionState).active.find(a => a.source == query.source);
|
|
976
|
+
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
|
960
977
|
if (current && current.state == 1 /* Pending */) {
|
|
961
978
|
if (query.done == null) {
|
|
962
979
|
// Explicitly failed. Should clear the pending status if it
|
|
963
980
|
// hasn't been re-set in the meantime.
|
|
964
|
-
let active = new ActiveSource(query.source, 0 /* Inactive
|
|
981
|
+
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
|
|
965
982
|
for (let tr of query.updates)
|
|
966
983
|
active = active.update(tr, conf);
|
|
967
984
|
if (active.state != 1 /* Pending */)
|
|
@@ -1319,6 +1336,7 @@ exports.completeFromList = completeFromList;
|
|
|
1319
1336
|
exports.completionKeymap = completionKeymap;
|
|
1320
1337
|
exports.completionStatus = completionStatus;
|
|
1321
1338
|
exports.currentCompletions = currentCompletions;
|
|
1339
|
+
exports.ifIn = ifIn;
|
|
1322
1340
|
exports.ifNotIn = ifNotIn;
|
|
1323
1341
|
exports.moveCompletionSelection = moveCompletionSelection;
|
|
1324
1342
|
exports.nextSnippetField = nextSnippetField;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { EditorState, Transaction, StateCommand, Facet, Extension } from '@codemirror/state';
|
|
2
2
|
import { EditorView, KeyBinding, Command } from '@codemirror/view';
|
|
3
|
-
import * as lezer_tree from 'lezer-tree';
|
|
4
3
|
|
|
5
4
|
interface CompletionConfig {
|
|
6
5
|
/**
|
|
@@ -123,10 +122,10 @@ declare class CompletionContext {
|
|
|
123
122
|
token before `this.pos`.
|
|
124
123
|
*/
|
|
125
124
|
tokenBefore(types: readonly string[]): {
|
|
126
|
-
from:
|
|
125
|
+
from: any;
|
|
127
126
|
to: number;
|
|
128
127
|
text: string;
|
|
129
|
-
type:
|
|
128
|
+
type: any;
|
|
130
129
|
} | null;
|
|
131
130
|
/**
|
|
132
131
|
Get the match of the given expression directly before the
|
|
@@ -155,6 +154,11 @@ completes them.
|
|
|
155
154
|
*/
|
|
156
155
|
declare function completeFromList(list: readonly (string | Completion)[]): CompletionSource;
|
|
157
156
|
/**
|
|
157
|
+
Wrap the given completion source so that it will only fire when the
|
|
158
|
+
cursor is in a syntax node with one of the given names.
|
|
159
|
+
*/
|
|
160
|
+
declare function ifIn(nodes: readonly string[], source: CompletionSource): CompletionSource;
|
|
161
|
+
/**
|
|
158
162
|
Wrap the given completion source so that it will not fire when the
|
|
159
163
|
cursor is in a syntax node with one of the given names.
|
|
160
164
|
*/
|
|
@@ -195,6 +199,15 @@ interface CompletionResult {
|
|
|
195
199
|
list to be updated synchronously.
|
|
196
200
|
*/
|
|
197
201
|
span?: RegExp;
|
|
202
|
+
/**
|
|
203
|
+
By default, the library filters and scores completions. Set
|
|
204
|
+
`filter` to `false` to disable this, and cause your completions
|
|
205
|
+
to all be included, in the order they were given. When there are
|
|
206
|
+
other sources, unfiltered completions appear at the top of the
|
|
207
|
+
list of completions. `span` must not be given `filter` is
|
|
208
|
+
`false`, because it only works when filtering.
|
|
209
|
+
*/
|
|
210
|
+
filter?: boolean;
|
|
198
211
|
}
|
|
199
212
|
|
|
200
213
|
/**
|
|
@@ -306,4 +319,4 @@ Returns the available completions as an array.
|
|
|
306
319
|
*/
|
|
307
320
|
declare function currentCompletions(state: EditorState): readonly Completion[];
|
|
308
321
|
|
|
309
|
-
export { Completion, CompletionContext, CompletionResult, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifNotIn, moveCompletionSelection, nextSnippetField, prevSnippetField, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
322
|
+
export { Completion, CompletionContext, CompletionResult, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, prevSnippetField, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
package/dist/index.js
CHANGED
|
@@ -105,6 +105,18 @@ function completeFromList(list) {
|
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
|
+
Wrap the given completion source so that it will only fire when the
|
|
109
|
+
cursor is in a syntax node with one of the given names.
|
|
110
|
+
*/
|
|
111
|
+
function ifIn(nodes, source) {
|
|
112
|
+
return (context) => {
|
|
113
|
+
for (let pos = syntaxTree(context.state).resolve(context.pos, -1); pos; pos = pos.parent)
|
|
114
|
+
if (nodes.indexOf(pos.name) > -1)
|
|
115
|
+
return source(context);
|
|
116
|
+
return null;
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
108
120
|
Wrap the given completion source so that it will not fire when the
|
|
109
121
|
cursor is in a syntax node with one of the given names.
|
|
110
122
|
*/
|
|
@@ -584,16 +596,22 @@ function score(option) {
|
|
|
584
596
|
(option.type ? 1 : 0);
|
|
585
597
|
}
|
|
586
598
|
function sortOptions(active, state) {
|
|
587
|
-
let options = [];
|
|
599
|
+
let options = [], i = 0;
|
|
588
600
|
for (let a of active)
|
|
589
601
|
if (a.hasResult()) {
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
602
|
+
if (a.result.filter === false) {
|
|
603
|
+
for (let option of a.result.options)
|
|
604
|
+
options.push(new Option(option, a, [1e9 - i++]));
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
|
|
608
|
+
for (let option of a.result.options)
|
|
609
|
+
if (match = matcher.match(option.label)) {
|
|
610
|
+
if (option.boost != null)
|
|
611
|
+
match[0] += option.boost;
|
|
612
|
+
options.push(new Option(option, a, match));
|
|
613
|
+
}
|
|
614
|
+
}
|
|
597
615
|
}
|
|
598
616
|
options.sort(cmpOption);
|
|
599
617
|
let result = [], prev = null;
|
|
@@ -656,7 +674,7 @@ class CompletionState {
|
|
|
656
674
|
state.languageDataAt("autocomplete", cur(state)).map(asSource);
|
|
657
675
|
let active = sources.map(source => {
|
|
658
676
|
let value = this.active.find(s => s.source == source) ||
|
|
659
|
-
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive
|
|
677
|
+
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
|
|
660
678
|
return value.update(tr, conf);
|
|
661
679
|
});
|
|
662
680
|
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
|
|
@@ -665,7 +683,7 @@ class CompletionState {
|
|
|
665
683
|
!sameResults(active, this.active) ? CompletionDialog.build(active, state, this.id, this.open)
|
|
666
684
|
: this.open && tr.docChanged ? this.open.map(tr.changes) : this.open;
|
|
667
685
|
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
|
|
668
|
-
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive
|
|
686
|
+
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
|
|
669
687
|
for (let effect of tr.effects)
|
|
670
688
|
if (effect.is(setSelectedEffect))
|
|
671
689
|
open = open && open.setSelected(effect.value, this.id);
|
|
@@ -705,13 +723,12 @@ function cmpOption(a, b) {
|
|
|
705
723
|
return lA < lB ? -1 : lA == lB ? 0 : 1;
|
|
706
724
|
}
|
|
707
725
|
class ActiveSource {
|
|
708
|
-
constructor(source, state,
|
|
726
|
+
constructor(source, state, explicitPos = -1) {
|
|
709
727
|
this.source = source;
|
|
710
728
|
this.state = state;
|
|
711
|
-
this.
|
|
729
|
+
this.explicitPos = explicitPos;
|
|
712
730
|
}
|
|
713
731
|
hasResult() { return false; }
|
|
714
|
-
explicitAt(_pos) { return this.explicit; }
|
|
715
732
|
update(tr, conf) {
|
|
716
733
|
let event = tr.annotation(Transaction.userEvent), value = this;
|
|
717
734
|
if (event == "input" || event == "delete")
|
|
@@ -719,12 +736,12 @@ class ActiveSource {
|
|
|
719
736
|
else if (tr.docChanged)
|
|
720
737
|
value = value.handleChange(tr);
|
|
721
738
|
else if (tr.selection && value.state != 0 /* Inactive */)
|
|
722
|
-
value = new ActiveSource(value.source, 0 /* Inactive
|
|
739
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
723
740
|
for (let effect of tr.effects) {
|
|
724
741
|
if (effect.is(startCompletionEffect))
|
|
725
|
-
value = new ActiveSource(value.source, 1 /* Pending */, effect.value);
|
|
742
|
+
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
|
|
726
743
|
else if (effect.is(closeCompletionEffect))
|
|
727
|
-
value = new ActiveSource(value.source, 0 /* Inactive
|
|
744
|
+
value = new ActiveSource(value.source, 0 /* Inactive */);
|
|
728
745
|
else if (effect.is(setActiveEffect))
|
|
729
746
|
for (let active of effect.value)
|
|
730
747
|
if (active.source == value.source)
|
|
@@ -732,47 +749,47 @@ class ActiveSource {
|
|
|
732
749
|
}
|
|
733
750
|
return value;
|
|
734
751
|
}
|
|
735
|
-
handleUserEvent(
|
|
736
|
-
return type == "delete" || !conf.activateOnTyping ? this : new ActiveSource(this.source, 1 /* Pending
|
|
752
|
+
handleUserEvent(tr, type, conf) {
|
|
753
|
+
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
|
|
737
754
|
}
|
|
738
755
|
handleChange(tr) {
|
|
739
|
-
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive
|
|
756
|
+
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
757
|
+
}
|
|
758
|
+
map(changes) {
|
|
759
|
+
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
|
|
740
760
|
}
|
|
741
761
|
}
|
|
742
762
|
class ActiveResult extends ActiveSource {
|
|
743
763
|
constructor(source, explicitPos, result, from, to, span) {
|
|
744
|
-
super(source, 2 /* Result */, explicitPos
|
|
745
|
-
this.explicitPos = explicitPos;
|
|
764
|
+
super(source, 2 /* Result */, explicitPos);
|
|
746
765
|
this.result = result;
|
|
747
766
|
this.from = from;
|
|
748
767
|
this.to = to;
|
|
749
768
|
this.span = span;
|
|
750
769
|
}
|
|
751
770
|
hasResult() { return true; }
|
|
752
|
-
explicitAt(pos) { return this.explicitPos == pos; }
|
|
753
|
-
mapExplicit(mapping) {
|
|
754
|
-
return this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos);
|
|
755
|
-
}
|
|
756
771
|
handleUserEvent(tr, type, conf) {
|
|
757
772
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
758
773
|
let pos = cur(tr.state);
|
|
759
|
-
if ((this.
|
|
760
|
-
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive
|
|
774
|
+
if ((this.explicitPos > -1 ? pos < from : pos <= from) || pos > to)
|
|
775
|
+
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
776
|
+
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
761
777
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
762
|
-
return new ActiveResult(this.source,
|
|
763
|
-
return new ActiveSource(this.source, 1 /* Pending */,
|
|
778
|
+
return new ActiveResult(this.source, explicitPos, this.result, from, to, this.span);
|
|
779
|
+
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
|
|
764
780
|
}
|
|
765
781
|
handleChange(tr) {
|
|
766
|
-
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive
|
|
782
|
+
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
|
|
767
783
|
}
|
|
768
784
|
map(mapping) {
|
|
769
|
-
return
|
|
785
|
+
return mapping.empty ? this :
|
|
786
|
+
new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1), this.span);
|
|
770
787
|
}
|
|
771
788
|
}
|
|
772
789
|
const startCompletionEffect = /*@__PURE__*/StateEffect.define();
|
|
773
790
|
const closeCompletionEffect = /*@__PURE__*/StateEffect.define();
|
|
774
791
|
const setActiveEffect = /*@__PURE__*/StateEffect.define({
|
|
775
|
-
map(sources, mapping) { return sources.map(s => s.
|
|
792
|
+
map(sources, mapping) { return sources.map(s => s.map(mapping)); }
|
|
776
793
|
});
|
|
777
794
|
const setSelectedEffect = /*@__PURE__*/StateEffect.define();
|
|
778
795
|
const completionState = /*@__PURE__*/StateField.define({
|
|
@@ -837,8 +854,8 @@ const closeCompletion = (view) => {
|
|
|
837
854
|
return true;
|
|
838
855
|
};
|
|
839
856
|
class RunningQuery {
|
|
840
|
-
constructor(
|
|
841
|
-
this.
|
|
857
|
+
constructor(active, context) {
|
|
858
|
+
this.active = active;
|
|
842
859
|
this.context = context;
|
|
843
860
|
this.time = Date.now();
|
|
844
861
|
this.updates = [];
|
|
@@ -888,7 +905,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
888
905
|
}
|
|
889
906
|
if (this.debounceUpdate > -1)
|
|
890
907
|
clearTimeout(this.debounceUpdate);
|
|
891
|
-
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.source == a.source))
|
|
908
|
+
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
892
909
|
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
|
|
893
910
|
if (this.composing != 0 /* None */)
|
|
894
911
|
for (let tr of update.transactions) {
|
|
@@ -902,14 +919,14 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
902
919
|
this.debounceUpdate = -1;
|
|
903
920
|
let { state } = this.view, cState = state.field(completionState);
|
|
904
921
|
for (let active of cState.active) {
|
|
905
|
-
if (active.state == 1 /* Pending */ && !this.running.some(r => r.source == active.source))
|
|
922
|
+
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
906
923
|
this.startQuery(active);
|
|
907
924
|
}
|
|
908
925
|
}
|
|
909
926
|
startQuery(active) {
|
|
910
927
|
let { state } = this.view, pos = cur(state);
|
|
911
|
-
let context = new CompletionContext(state, pos, active.
|
|
912
|
-
let pending = new RunningQuery(active
|
|
928
|
+
let context = new CompletionContext(state, pos, active.explicitPos == pos);
|
|
929
|
+
let pending = new RunningQuery(active, context);
|
|
913
930
|
this.running.push(pending);
|
|
914
931
|
Promise.resolve(active.source(context)).then(result => {
|
|
915
932
|
if (!pending.context.aborted) {
|
|
@@ -942,7 +959,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
942
959
|
continue;
|
|
943
960
|
this.running.splice(i--, 1);
|
|
944
961
|
if (query.done) {
|
|
945
|
-
let active = new ActiveResult(query.source, query.
|
|
962
|
+
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), query.done.span && query.done.filter !== false ? ensureAnchor(query.done.span, true) : null);
|
|
946
963
|
// Replay the transactions that happened since the start of
|
|
947
964
|
// the request and see if that preserves the result
|
|
948
965
|
for (let tr of query.updates)
|
|
@@ -952,12 +969,12 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
952
969
|
continue;
|
|
953
970
|
}
|
|
954
971
|
}
|
|
955
|
-
let current = this.view.state.field(completionState).active.find(a => a.source == query.source);
|
|
972
|
+
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
|
|
956
973
|
if (current && current.state == 1 /* Pending */) {
|
|
957
974
|
if (query.done == null) {
|
|
958
975
|
// Explicitly failed. Should clear the pending status if it
|
|
959
976
|
// hasn't been re-set in the meantime.
|
|
960
|
-
let active = new ActiveSource(query.source, 0 /* Inactive
|
|
977
|
+
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
|
|
961
978
|
for (let tr of query.updates)
|
|
962
979
|
active = active.update(tr, conf);
|
|
963
980
|
if (active.state != 1 /* Pending */)
|
|
@@ -1305,4 +1322,4 @@ function currentCompletions(state) {
|
|
|
1305
1322
|
return open ? open.options.map(o => o.completion) : [];
|
|
1306
1323
|
}
|
|
1307
1324
|
|
|
1308
|
-
export { CompletionContext, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifNotIn, moveCompletionSelection, nextSnippetField, prevSnippetField, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
1325
|
+
export { CompletionContext, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, prevSnippetField, snippet, snippetCompletion, snippetKeymap, startCompletion };
|