@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 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
- let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
595
- for (let option of a.result.options)
596
- if (match = matcher.match(option.label)) {
597
- if (option.boost != null)
598
- match[0] += option.boost;
599
- options.push(new Option(option, a, match));
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 */, false);
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 */, false) : a);
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, explicit) {
730
+ constructor(source, state, explicitPos = -1) {
713
731
  this.source = source;
714
732
  this.state = state;
715
- this.explicit = explicit;
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 */, false);
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 */, false);
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(_tr, type, conf) {
740
- return type == "delete" || !conf.activateOnTyping ? this : new ActiveSource(this.source, 1 /* Pending */, false);
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 */, false) : this;
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 > -1);
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.explicit ? pos < from : pos <= from) || pos > to)
764
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */, false);
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, this.mapExplicit(tr.changes), this.result, from, to, this.span);
767
- return new ActiveSource(this.source, 1 /* Pending */, false);
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 */, false) : this.map(tr.changes);
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 new ActiveResult(this.source, this.mapExplicit(mapping), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1), this.span);
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.hasResult() && !mapping.empty ? s.map(mapping) : 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(source, context) {
845
- this.source = source;
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.explicitAt(pos));
916
- let pending = new RunningQuery(active.source, context);
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.context.explicit ? query.context.pos : -1, 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 ? ensureAnchor(query.done.span, true) : null);
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 */, false);
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: number;
125
+ from: any;
127
126
  to: number;
128
127
  text: string;
129
- type: lezer_tree.NodeType;
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
- let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to)), match;
591
- for (let option of a.result.options)
592
- if (match = matcher.match(option.label)) {
593
- if (option.boost != null)
594
- match[0] += option.boost;
595
- options.push(new Option(option, a, match));
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 */, false);
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 */, false) : a);
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, explicit) {
726
+ constructor(source, state, explicitPos = -1) {
709
727
  this.source = source;
710
728
  this.state = state;
711
- this.explicit = explicit;
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 */, false);
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 */, false);
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(_tr, type, conf) {
736
- return type == "delete" || !conf.activateOnTyping ? this : new ActiveSource(this.source, 1 /* Pending */, false);
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 */, false) : this;
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 > -1);
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.explicit ? pos < from : pos <= from) || pos > to)
760
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */, false);
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, this.mapExplicit(tr.changes), this.result, from, to, this.span);
763
- return new ActiveSource(this.source, 1 /* Pending */, false);
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 */, false) : this.map(tr.changes);
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 new ActiveResult(this.source, this.mapExplicit(mapping), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1), this.span);
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.hasResult() && !mapping.empty ? s.map(mapping) : 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(source, context) {
841
- this.source = source;
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.explicitAt(pos));
912
- let pending = new RunningQuery(active.source, context);
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.context.explicit ? query.context.pos : -1, 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 ? ensureAnchor(query.done.span, true) : null);
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 */, false);
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "0.18.7",
3
+ "version": "0.18.8",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",