@codemirror/autocomplete 6.1.0 → 6.2.0

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,17 @@
1
+ ## 6.2.0 (2022-09-13)
2
+
3
+ ### New features
4
+
5
+ Autocompletion now takes an `interactionDelay` option that can be used to control the delay between the time where completion opens and the time where commands like `acceptCompletion` affect it.
6
+
7
+ ## 6.1.1 (2022-09-08)
8
+
9
+ ### Bug fixes
10
+
11
+ Fix a bug that prevented transactions produced by `deleteBracketPair` from being marked as deletion user events.
12
+
13
+ Improve positioning of completion info tooltips so they are less likely to stick out of the screen on small displays.
14
+
1
15
  ## 6.1.0 (2022-07-19)
2
16
 
3
17
  ### New features
package/dist/index.cjs CHANGED
@@ -233,7 +233,7 @@ class FuzzyMatcher {
233
233
  if (chars.length == 1) {
234
234
  let first = state.codePointAt(word, 0);
235
235
  return first == chars[0] ? [0, 0, state.codePointSize(first)]
236
- : first == folded[0] ? [-200 /* CaseFold */, 0, state.codePointSize(first)] : null;
236
+ : first == folded[0] ? [-200 /* Penalty.CaseFold */, 0, state.codePointSize(first)] : null;
237
237
  }
238
238
  let direct = word.indexOf(this.pattern);
239
239
  if (direct == 0)
@@ -261,7 +261,7 @@ class FuzzyMatcher {
261
261
  let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
262
262
  let hasLower = /[a-z]/.test(word), wordAdjacent = true;
263
263
  // Go over the option's text, scanning for the various kinds of matches
264
- for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
264
+ for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
265
265
  let next = state.codePointAt(word, i);
266
266
  if (direct < 0) {
267
267
  if (preciseTo < len && next == chars[preciseTo])
@@ -279,9 +279,9 @@ class FuzzyMatcher {
279
279
  }
280
280
  }
281
281
  let ch, type = next < 0xff
282
- ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
283
- : ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
284
- if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
282
+ ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
283
+ : ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
284
+ if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
285
285
  if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
286
286
  byWord[byWordTo++] = i;
287
287
  else if (byWord.length)
@@ -291,17 +291,17 @@ class FuzzyMatcher {
291
291
  i += state.codePointSize(next);
292
292
  }
293
293
  if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
294
- return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
294
+ return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
295
295
  if (adjacentTo == len && adjacentStart == 0)
296
- return [-200 /* CaseFold */ - word.length, 0, adjacentEnd];
296
+ return [-200 /* Penalty.CaseFold */ - word.length, 0, adjacentEnd];
297
297
  if (direct > -1)
298
- return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
298
+ return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length];
299
299
  if (adjacentTo == len)
300
- return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
300
+ return [-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, adjacentStart, adjacentEnd];
301
301
  if (byWordTo == len)
302
- return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
303
- (wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
304
- return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
302
+ return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
303
+ (wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
304
+ return chars.length == 2 ? null : this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
305
305
  }
306
306
  result(score, positions, word) {
307
307
  let result = [score - word.length], i = 1;
@@ -331,7 +331,8 @@ const completionConfig = state.Facet.define({
331
331
  aboveCursor: false,
332
332
  icons: true,
333
333
  addToOptions: [],
334
- compareCompletions: (a, b) => a.label.localeCompare(b.label)
334
+ compareCompletions: (a, b) => a.label.localeCompare(b.label),
335
+ interactionDelay: 75
335
336
  }, {
336
337
  defaultKeymap: (a, b) => a && b,
337
338
  closeOnBlur: (a, b) => a && b,
@@ -447,7 +448,7 @@ class CompletionTooltip {
447
448
  }
448
449
  updateSel() {
449
450
  let cState = this.view.state.field(this.stateField), open = cState.open;
450
- if (open.selected < this.range.from || open.selected >= this.range.to) {
451
+ if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
451
452
  this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
452
453
  this.list.remove();
453
454
  this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
@@ -508,26 +509,47 @@ class CompletionTooltip {
508
509
  let sel = this.dom.querySelector("[aria-selected]");
509
510
  if (!sel || !this.info)
510
511
  return null;
512
+ let win = this.dom.ownerDocument.defaultView;
511
513
  let listRect = this.dom.getBoundingClientRect();
512
514
  let infoRect = this.info.getBoundingClientRect();
513
515
  let selRect = sel.getBoundingClientRect();
514
- if (selRect.top > Math.min(innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
516
+ if (selRect.top > Math.min(win.innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
515
517
  return null;
516
- let top = Math.max(0, Math.min(selRect.top, innerHeight - infoRect.height)) - listRect.top;
517
- let left = this.view.textDirection == view.Direction.RTL;
518
- let spaceLeft = listRect.left, spaceRight = innerWidth - listRect.right;
518
+ let rtl = this.view.textDirection == view.Direction.RTL, left = rtl, narrow = false, maxWidth;
519
+ let top = "", bottom = "";
520
+ let spaceLeft = listRect.left, spaceRight = win.innerWidth - listRect.right;
519
521
  if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
520
522
  left = false;
521
523
  else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
522
524
  left = true;
523
- return { top, left };
525
+ if (infoRect.width <= (left ? spaceLeft : spaceRight)) {
526
+ top = (Math.max(0, Math.min(selRect.top, win.innerHeight - infoRect.height)) - listRect.top) + "px";
527
+ maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight) + "px";
528
+ }
529
+ else {
530
+ narrow = true;
531
+ maxWidth = Math.min(400 /* Info.Width */, (rtl ? listRect.right : win.innerWidth - listRect.left) - 30 /* Info.Margin */) + "px";
532
+ let spaceBelow = win.innerHeight - listRect.bottom;
533
+ if (spaceBelow >= infoRect.height || spaceBelow > listRect.top) // Below the completion
534
+ top = (selRect.bottom - listRect.top) + "px";
535
+ else // Above it
536
+ bottom = (listRect.bottom - selRect.top) + "px";
537
+ }
538
+ return {
539
+ top, bottom, maxWidth,
540
+ class: narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right",
541
+ };
524
542
  }
525
543
  positionInfo(pos) {
526
544
  if (this.info) {
527
- this.info.style.top = (pos ? pos.top : -1e6) + "px";
528
545
  if (pos) {
529
- this.info.classList.toggle("cm-completionInfo-left", pos.left);
530
- this.info.classList.toggle("cm-completionInfo-right", !pos.left);
546
+ this.info.style.top = pos.top;
547
+ this.info.style.bottom = pos.bottom;
548
+ this.info.style.maxWidth = pos.maxWidth;
549
+ this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class;
550
+ }
551
+ else {
552
+ this.info.style.top = "-1e6px";
531
553
  }
532
554
  }
533
555
  }
@@ -665,7 +687,7 @@ class CompletionState {
665
687
  state.languageDataAt("autocomplete", cur(state)).map(asSource);
666
688
  let active = sources.map(source => {
667
689
  let value = this.active.find(s => s.source == source) ||
668
- new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
690
+ new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
669
691
  return value.update(tr, conf);
670
692
  });
671
693
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
@@ -673,8 +695,8 @@ class CompletionState {
673
695
  let open = tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
674
696
  !sameResults(active, this.active) ? CompletionDialog.build(active, state, this.id, this.open, conf)
675
697
  : this.open && tr.docChanged ? this.open.map(tr.changes) : this.open;
676
- if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
677
- active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
698
+ if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
699
+ active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
678
700
  for (let effect of tr.effects)
679
701
  if (effect.is(setSelectedEffect))
680
702
  open = open && open.setSelected(effect.value, this.id);
@@ -728,13 +750,13 @@ class ActiveSource {
728
750
  value = value.handleUserEvent(tr, event, conf);
729
751
  else if (tr.docChanged)
730
752
  value = value.handleChange(tr);
731
- else if (tr.selection && value.state != 0 /* Inactive */)
732
- value = new ActiveSource(value.source, 0 /* Inactive */);
753
+ else if (tr.selection && value.state != 0 /* State.Inactive */)
754
+ value = new ActiveSource(value.source, 0 /* State.Inactive */);
733
755
  for (let effect of tr.effects) {
734
756
  if (effect.is(startCompletionEffect))
735
- value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
757
+ value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
736
758
  else if (effect.is(closeCompletionEffect))
737
- value = new ActiveSource(value.source, 0 /* Inactive */);
759
+ value = new ActiveSource(value.source, 0 /* State.Inactive */);
738
760
  else if (effect.is(setActiveEffect))
739
761
  for (let active of effect.value)
740
762
  if (active.source == value.source)
@@ -743,10 +765,10 @@ class ActiveSource {
743
765
  return value;
744
766
  }
745
767
  handleUserEvent(tr, type, conf) {
746
- return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
768
+ return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
747
769
  }
748
770
  handleChange(tr) {
749
- return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
771
+ return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
750
772
  }
751
773
  map(changes) {
752
774
  return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
@@ -754,7 +776,7 @@ class ActiveSource {
754
776
  }
755
777
  class ActiveResult extends ActiveSource {
756
778
  constructor(source, explicitPos, result, from, to) {
757
- super(source, 2 /* Result */, explicitPos);
779
+ super(source, 2 /* State.Result */, explicitPos);
758
780
  this.result = result;
759
781
  this.from = from;
760
782
  this.to = to;
@@ -767,17 +789,17 @@ class ActiveResult extends ActiveSource {
767
789
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
768
790
  pos > to ||
769
791
  type == "delete" && cur(tr.startState) == this.from)
770
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
792
+ return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
771
793
  let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
772
794
  if (checkValid(this.result.validFor, tr.state, from, to))
773
795
  return new ActiveResult(this.source, explicitPos, this.result, from, to);
774
796
  if (this.result.update &&
775
797
  (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
776
798
  return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
777
- return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
799
+ return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
778
800
  }
779
801
  handleChange(tr) {
780
- return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
802
+ return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
781
803
  }
782
804
  map(mapping) {
783
805
  return mapping.empty ? this :
@@ -805,7 +827,6 @@ const completionState = state.StateField.define({
805
827
  ]
806
828
  });
807
829
 
808
- const CompletionInteractMargin = 75;
809
830
  /**
810
831
  Returns a command that moves the completion selection forward or
811
832
  backward by the given amount.
@@ -813,7 +834,8 @@ backward by the given amount.
813
834
  function moveCompletionSelection(forward, by = "option") {
814
835
  return (view$1) => {
815
836
  let cState = view$1.state.field(completionState, false);
816
- if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
837
+ if (!cState || !cState.open ||
838
+ Date.now() - cState.open.timestamp < view$1.state.facet(completionConfig).interactionDelay)
817
839
  return false;
818
840
  let step = 1, tooltip;
819
841
  if (by == "page" && (tooltip = view.getTooltip(view$1, cState.open.tooltip)))
@@ -834,8 +856,8 @@ Accept the current completion.
834
856
  */
835
857
  const acceptCompletion = (view) => {
836
858
  let cState = view.state.field(completionState, false);
837
- if (view.state.readOnly || !cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin ||
838
- cState.open.selected < 0)
859
+ if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 ||
860
+ Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
839
861
  return false;
840
862
  applyCompletion(view, cState.open.options[cState.open.selected]);
841
863
  return true;
@@ -855,7 +877,7 @@ Close the currently active completion.
855
877
  */
856
878
  const closeCompletion = (view) => {
857
879
  let cState = view.state.field(completionState, false);
858
- if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
880
+ if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
859
881
  return false;
860
882
  view.dispatch({ effects: closeCompletionEffect.of(null) });
861
883
  return true;
@@ -878,9 +900,9 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
878
900
  this.debounceUpdate = -1;
879
901
  this.running = [];
880
902
  this.debounceAccept = -1;
881
- this.composing = 0 /* None */;
903
+ this.composing = 0 /* CompositionState.None */;
882
904
  for (let active of view.state.field(completionState).active)
883
- if (active.state == 1 /* Pending */)
905
+ if (active.state == 1 /* State.Pending */)
884
906
  this.startQuery(active);
885
907
  }
886
908
  update(update) {
@@ -911,21 +933,21 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
911
933
  }
912
934
  if (this.debounceUpdate > -1)
913
935
  clearTimeout(this.debounceUpdate);
914
- this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
936
+ this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
915
937
  ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
916
- if (this.composing != 0 /* None */)
938
+ if (this.composing != 0 /* CompositionState.None */)
917
939
  for (let tr of update.transactions) {
918
940
  if (getUserEvent(tr) == "input")
919
- this.composing = 2 /* Changed */;
920
- else if (this.composing == 2 /* Changed */ && tr.selection)
921
- this.composing = 3 /* ChangedAndMoved */;
941
+ this.composing = 2 /* CompositionState.Changed */;
942
+ else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
943
+ this.composing = 3 /* CompositionState.ChangedAndMoved */;
922
944
  }
923
945
  }
924
946
  startUpdate() {
925
947
  this.debounceUpdate = -1;
926
948
  let { state } = this.view, cState = state.field(completionState);
927
949
  for (let active of cState.active) {
928
- if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
950
+ if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
929
951
  this.startQuery(active);
930
952
  }
931
953
  }
@@ -976,14 +998,14 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
976
998
  }
977
999
  }
978
1000
  let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
979
- if (current && current.state == 1 /* Pending */) {
1001
+ if (current && current.state == 1 /* State.Pending */) {
980
1002
  if (query.done == null) {
981
1003
  // Explicitly failed. Should clear the pending status if it
982
1004
  // hasn't been re-set in the meantime.
983
- let active = new ActiveSource(query.active.source, 0 /* Inactive */);
1005
+ let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
984
1006
  for (let tr of query.updates)
985
1007
  active = active.update(tr, conf);
986
- if (active.state != 1 /* Pending */)
1008
+ if (active.state != 1 /* State.Pending */)
987
1009
  updated.push(active);
988
1010
  }
989
1011
  else {
@@ -1003,15 +1025,15 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1003
1025
  this.view.dispatch({ effects: closeCompletionEffect.of(null) });
1004
1026
  },
1005
1027
  compositionstart() {
1006
- this.composing = 1 /* Started */;
1028
+ this.composing = 1 /* CompositionState.Started */;
1007
1029
  },
1008
1030
  compositionend() {
1009
- if (this.composing == 3 /* ChangedAndMoved */) {
1031
+ if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
1010
1032
  // Safari fires compositionend events synchronously, possibly
1011
1033
  // from inside an update, so dispatch asynchronously to avoid reentrancy
1012
1034
  setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
1013
1035
  }
1014
- this.composing = 0 /* None */;
1036
+ this.composing = 0 /* CompositionState.None */;
1015
1037
  }
1016
1038
  }
1017
1039
  });
@@ -1056,10 +1078,13 @@ const baseTheme = view.EditorView.baseTheme({
1056
1078
  position: "absolute",
1057
1079
  padding: "3px 9px",
1058
1080
  width: "max-content",
1059
- maxWidth: "300px",
1081
+ maxWidth: `${400 /* Info.Width */}px`,
1082
+ boxSizing: "border-box"
1060
1083
  },
1061
1084
  ".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
1062
1085
  ".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
1086
+ ".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
1087
+ ".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
1063
1088
  "&light .cm-snippetField": { backgroundColor: "#00000022" },
1064
1089
  "&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
1065
1090
  ".cm-snippetFieldPosition": {
@@ -1394,7 +1419,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
1394
1419
  if (!seen[m[0]] && pos + m.index != ignoreAt) {
1395
1420
  result.push({ type: "text", label: m[0] });
1396
1421
  seen[m[0]] = true;
1397
- if (result.length >= 2000 /* MaxList */)
1422
+ if (result.length >= 2000 /* C.MaxList */)
1398
1423
  return;
1399
1424
  }
1400
1425
  }
@@ -1402,7 +1427,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
1402
1427
  }
1403
1428
  }
1404
1429
  function collectWords(doc, cache, wordRE, to, ignoreAt) {
1405
- let big = doc.length >= 1000 /* MinCacheLen */;
1430
+ let big = doc.length >= 1000 /* C.MinCacheLen */;
1406
1431
  let cached = big && cache.get(doc);
1407
1432
  if (cached)
1408
1433
  return cached;
@@ -1410,7 +1435,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
1410
1435
  if (doc.children) {
1411
1436
  let pos = 0;
1412
1437
  for (let ch of doc.children) {
1413
- if (ch.length >= 1000 /* MinCacheLen */) {
1438
+ if (ch.length >= 1000 /* C.MinCacheLen */) {
1414
1439
  for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
1415
1440
  if (!seen[c.label]) {
1416
1441
  seen[c.label] = true;
@@ -1427,7 +1452,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
1427
1452
  else {
1428
1453
  storeWords(doc, wordRE, result, seen, ignoreAt);
1429
1454
  }
1430
- if (big && result.length < 2000 /* MaxList */)
1455
+ if (big && result.length < 2000 /* C.MaxList */)
1431
1456
  cache.set(doc, result);
1432
1457
  return result;
1433
1458
  }
@@ -1443,7 +1468,7 @@ const completeAnyWord = context => {
1443
1468
  if (!token && !context.explicit)
1444
1469
  return null;
1445
1470
  let from = token ? token.from : context.pos;
1446
- let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
1471
+ let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from);
1447
1472
  return { from, options, validFor: mapRE(re, s => "^" + s) };
1448
1473
  };
1449
1474
 
@@ -1532,14 +1557,13 @@ const deleteBracketPair = ({ state: state$1, dispatch }) => {
1532
1557
  for (let token of tokens) {
1533
1558
  if (token == before && nextChar(state$1.doc, range.head) == closing(state.codePointAt(token, 0)))
1534
1559
  return { changes: { from: range.head - token.length, to: range.head + token.length },
1535
- range: state.EditorSelection.cursor(range.head - token.length),
1536
- userEvent: "delete.backward" };
1560
+ range: state.EditorSelection.cursor(range.head - token.length) };
1537
1561
  }
1538
1562
  }
1539
1563
  return { range: dont = range };
1540
1564
  });
1541
1565
  if (!dont)
1542
- dispatch(state$1.update(changes, { scrollIntoView: true }));
1566
+ dispatch(state$1.update(changes, { scrollIntoView: true, userEvent: "delete.backward" }));
1543
1567
  return !dont;
1544
1568
  };
1545
1569
  /**
@@ -1725,8 +1749,8 @@ returns `null`.
1725
1749
  */
1726
1750
  function completionStatus(state) {
1727
1751
  let cState = state.field(completionState, false);
1728
- return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
1729
- : cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
1752
+ return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending"
1753
+ : cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null;
1730
1754
  }
1731
1755
  const completionArrayCache = new WeakMap;
1732
1756
  /**
package/dist/index.d.ts CHANGED
@@ -78,6 +78,13 @@ interface CompletionConfig {
78
78
  [`localeCompare`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare).
79
79
  */
80
80
  compareCompletions?: (a: Completion, b: Completion) => number;
81
+ /**
82
+ By default, commands relating to an open completion only take
83
+ effect 75 milliseconds after the completion opened, so that key
84
+ presses made before the user is aware of the tooltip don't go to
85
+ the tooltip. This option can be used to configure that delay.
86
+ */
87
+ interactionDelay?: number;
81
88
  }
82
89
 
83
90
  /**
package/dist/index.js CHANGED
@@ -229,7 +229,7 @@ class FuzzyMatcher {
229
229
  if (chars.length == 1) {
230
230
  let first = codePointAt(word, 0);
231
231
  return first == chars[0] ? [0, 0, codePointSize(first)]
232
- : first == folded[0] ? [-200 /* CaseFold */, 0, codePointSize(first)] : null;
232
+ : first == folded[0] ? [-200 /* Penalty.CaseFold */, 0, codePointSize(first)] : null;
233
233
  }
234
234
  let direct = word.indexOf(this.pattern);
235
235
  if (direct == 0)
@@ -257,7 +257,7 @@ class FuzzyMatcher {
257
257
  let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
258
258
  let hasLower = /[a-z]/.test(word), wordAdjacent = true;
259
259
  // Go over the option's text, scanning for the various kinds of matches
260
- for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
260
+ for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
261
261
  let next = codePointAt(word, i);
262
262
  if (direct < 0) {
263
263
  if (preciseTo < len && next == chars[preciseTo])
@@ -275,9 +275,9 @@ class FuzzyMatcher {
275
275
  }
276
276
  }
277
277
  let ch, type = next < 0xff
278
- ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
279
- : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
280
- if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
278
+ ? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
279
+ : ((ch = fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
280
+ if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
281
281
  if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
282
282
  byWord[byWordTo++] = i;
283
283
  else if (byWord.length)
@@ -287,17 +287,17 @@ class FuzzyMatcher {
287
287
  i += codePointSize(next);
288
288
  }
289
289
  if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
290
- return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
290
+ return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
291
291
  if (adjacentTo == len && adjacentStart == 0)
292
- return [-200 /* CaseFold */ - word.length, 0, adjacentEnd];
292
+ return [-200 /* Penalty.CaseFold */ - word.length, 0, adjacentEnd];
293
293
  if (direct > -1)
294
- return [-700 /* NotStart */ - word.length, direct, direct + this.pattern.length];
294
+ return [-700 /* Penalty.NotStart */ - word.length, direct, direct + this.pattern.length];
295
295
  if (adjacentTo == len)
296
- return [-200 /* CaseFold */ + -700 /* NotStart */ - word.length, adjacentStart, adjacentEnd];
296
+ return [-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, adjacentStart, adjacentEnd];
297
297
  if (byWordTo == len)
298
- return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
299
- (wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
300
- return chars.length == 2 ? null : this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
298
+ return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
299
+ (wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
300
+ return chars.length == 2 ? null : this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
301
301
  }
302
302
  result(score, positions, word) {
303
303
  let result = [score - word.length], i = 1;
@@ -327,7 +327,8 @@ const completionConfig = /*@__PURE__*/Facet.define({
327
327
  aboveCursor: false,
328
328
  icons: true,
329
329
  addToOptions: [],
330
- compareCompletions: (a, b) => a.label.localeCompare(b.label)
330
+ compareCompletions: (a, b) => a.label.localeCompare(b.label),
331
+ interactionDelay: 75
331
332
  }, {
332
333
  defaultKeymap: (a, b) => a && b,
333
334
  closeOnBlur: (a, b) => a && b,
@@ -443,7 +444,7 @@ class CompletionTooltip {
443
444
  }
444
445
  updateSel() {
445
446
  let cState = this.view.state.field(this.stateField), open = cState.open;
446
- if (open.selected < this.range.from || open.selected >= this.range.to) {
447
+ if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
447
448
  this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
448
449
  this.list.remove();
449
450
  this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
@@ -504,26 +505,47 @@ class CompletionTooltip {
504
505
  let sel = this.dom.querySelector("[aria-selected]");
505
506
  if (!sel || !this.info)
506
507
  return null;
508
+ let win = this.dom.ownerDocument.defaultView;
507
509
  let listRect = this.dom.getBoundingClientRect();
508
510
  let infoRect = this.info.getBoundingClientRect();
509
511
  let selRect = sel.getBoundingClientRect();
510
- if (selRect.top > Math.min(innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
512
+ if (selRect.top > Math.min(win.innerHeight, listRect.bottom) - 10 || selRect.bottom < Math.max(0, listRect.top) + 10)
511
513
  return null;
512
- let top = Math.max(0, Math.min(selRect.top, innerHeight - infoRect.height)) - listRect.top;
513
- let left = this.view.textDirection == Direction.RTL;
514
- let spaceLeft = listRect.left, spaceRight = innerWidth - listRect.right;
514
+ let rtl = this.view.textDirection == Direction.RTL, left = rtl, narrow = false, maxWidth;
515
+ let top = "", bottom = "";
516
+ let spaceLeft = listRect.left, spaceRight = win.innerWidth - listRect.right;
515
517
  if (left && spaceLeft < Math.min(infoRect.width, spaceRight))
516
518
  left = false;
517
519
  else if (!left && spaceRight < Math.min(infoRect.width, spaceLeft))
518
520
  left = true;
519
- return { top, left };
521
+ if (infoRect.width <= (left ? spaceLeft : spaceRight)) {
522
+ top = (Math.max(0, Math.min(selRect.top, win.innerHeight - infoRect.height)) - listRect.top) + "px";
523
+ maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight) + "px";
524
+ }
525
+ else {
526
+ narrow = true;
527
+ maxWidth = Math.min(400 /* Info.Width */, (rtl ? listRect.right : win.innerWidth - listRect.left) - 30 /* Info.Margin */) + "px";
528
+ let spaceBelow = win.innerHeight - listRect.bottom;
529
+ if (spaceBelow >= infoRect.height || spaceBelow > listRect.top) // Below the completion
530
+ top = (selRect.bottom - listRect.top) + "px";
531
+ else // Above it
532
+ bottom = (listRect.bottom - selRect.top) + "px";
533
+ }
534
+ return {
535
+ top, bottom, maxWidth,
536
+ class: narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right",
537
+ };
520
538
  }
521
539
  positionInfo(pos) {
522
540
  if (this.info) {
523
- this.info.style.top = (pos ? pos.top : -1e6) + "px";
524
541
  if (pos) {
525
- this.info.classList.toggle("cm-completionInfo-left", pos.left);
526
- this.info.classList.toggle("cm-completionInfo-right", !pos.left);
542
+ this.info.style.top = pos.top;
543
+ this.info.style.bottom = pos.bottom;
544
+ this.info.style.maxWidth = pos.maxWidth;
545
+ this.info.className = "cm-tooltip cm-completionInfo cm-completionInfo-" + pos.class;
546
+ }
547
+ else {
548
+ this.info.style.top = "-1e6px";
527
549
  }
528
550
  }
529
551
  }
@@ -661,7 +683,7 @@ class CompletionState {
661
683
  state.languageDataAt("autocomplete", cur(state)).map(asSource);
662
684
  let active = sources.map(source => {
663
685
  let value = this.active.find(s => s.source == source) ||
664
- new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
686
+ new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
665
687
  return value.update(tr, conf);
666
688
  });
667
689
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
@@ -669,8 +691,8 @@ class CompletionState {
669
691
  let open = tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
670
692
  !sameResults(active, this.active) ? CompletionDialog.build(active, state, this.id, this.open, conf)
671
693
  : this.open && tr.docChanged ? this.open.map(tr.changes) : this.open;
672
- if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
673
- active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
694
+ if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
695
+ active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
674
696
  for (let effect of tr.effects)
675
697
  if (effect.is(setSelectedEffect))
676
698
  open = open && open.setSelected(effect.value, this.id);
@@ -724,13 +746,13 @@ class ActiveSource {
724
746
  value = value.handleUserEvent(tr, event, conf);
725
747
  else if (tr.docChanged)
726
748
  value = value.handleChange(tr);
727
- else if (tr.selection && value.state != 0 /* Inactive */)
728
- value = new ActiveSource(value.source, 0 /* Inactive */);
749
+ else if (tr.selection && value.state != 0 /* State.Inactive */)
750
+ value = new ActiveSource(value.source, 0 /* State.Inactive */);
729
751
  for (let effect of tr.effects) {
730
752
  if (effect.is(startCompletionEffect))
731
- value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
753
+ value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
732
754
  else if (effect.is(closeCompletionEffect))
733
- value = new ActiveSource(value.source, 0 /* Inactive */);
755
+ value = new ActiveSource(value.source, 0 /* State.Inactive */);
734
756
  else if (effect.is(setActiveEffect))
735
757
  for (let active of effect.value)
736
758
  if (active.source == value.source)
@@ -739,10 +761,10 @@ class ActiveSource {
739
761
  return value;
740
762
  }
741
763
  handleUserEvent(tr, type, conf) {
742
- return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
764
+ return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
743
765
  }
744
766
  handleChange(tr) {
745
- return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
767
+ return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
746
768
  }
747
769
  map(changes) {
748
770
  return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
@@ -750,7 +772,7 @@ class ActiveSource {
750
772
  }
751
773
  class ActiveResult extends ActiveSource {
752
774
  constructor(source, explicitPos, result, from, to) {
753
- super(source, 2 /* Result */, explicitPos);
775
+ super(source, 2 /* State.Result */, explicitPos);
754
776
  this.result = result;
755
777
  this.from = from;
756
778
  this.to = to;
@@ -763,17 +785,17 @@ class ActiveResult extends ActiveSource {
763
785
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
764
786
  pos > to ||
765
787
  type == "delete" && cur(tr.startState) == this.from)
766
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
788
+ return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
767
789
  let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
768
790
  if (checkValid(this.result.validFor, tr.state, from, to))
769
791
  return new ActiveResult(this.source, explicitPos, this.result, from, to);
770
792
  if (this.result.update &&
771
793
  (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
772
794
  return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
773
- return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
795
+ return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
774
796
  }
775
797
  handleChange(tr) {
776
- return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
798
+ return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
777
799
  }
778
800
  map(mapping) {
779
801
  return mapping.empty ? this :
@@ -801,7 +823,6 @@ const completionState = /*@__PURE__*/StateField.define({
801
823
  ]
802
824
  });
803
825
 
804
- const CompletionInteractMargin = 75;
805
826
  /**
806
827
  Returns a command that moves the completion selection forward or
807
828
  backward by the given amount.
@@ -809,7 +830,8 @@ backward by the given amount.
809
830
  function moveCompletionSelection(forward, by = "option") {
810
831
  return (view) => {
811
832
  let cState = view.state.field(completionState, false);
812
- if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
833
+ if (!cState || !cState.open ||
834
+ Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
813
835
  return false;
814
836
  let step = 1, tooltip;
815
837
  if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
@@ -830,8 +852,8 @@ Accept the current completion.
830
852
  */
831
853
  const acceptCompletion = (view) => {
832
854
  let cState = view.state.field(completionState, false);
833
- if (view.state.readOnly || !cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin ||
834
- cState.open.selected < 0)
855
+ if (view.state.readOnly || !cState || !cState.open || cState.open.selected < 0 ||
856
+ Date.now() - cState.open.timestamp < view.state.facet(completionConfig).interactionDelay)
835
857
  return false;
836
858
  applyCompletion(view, cState.open.options[cState.open.selected]);
837
859
  return true;
@@ -851,7 +873,7 @@ Close the currently active completion.
851
873
  */
852
874
  const closeCompletion = (view) => {
853
875
  let cState = view.state.field(completionState, false);
854
- if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
876
+ if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
855
877
  return false;
856
878
  view.dispatch({ effects: closeCompletionEffect.of(null) });
857
879
  return true;
@@ -874,9 +896,9 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
874
896
  this.debounceUpdate = -1;
875
897
  this.running = [];
876
898
  this.debounceAccept = -1;
877
- this.composing = 0 /* None */;
899
+ this.composing = 0 /* CompositionState.None */;
878
900
  for (let active of view.state.field(completionState).active)
879
- if (active.state == 1 /* Pending */)
901
+ if (active.state == 1 /* State.Pending */)
880
902
  this.startQuery(active);
881
903
  }
882
904
  update(update) {
@@ -907,21 +929,21 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
907
929
  }
908
930
  if (this.debounceUpdate > -1)
909
931
  clearTimeout(this.debounceUpdate);
910
- this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
932
+ this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
911
933
  ? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
912
- if (this.composing != 0 /* None */)
934
+ if (this.composing != 0 /* CompositionState.None */)
913
935
  for (let tr of update.transactions) {
914
936
  if (getUserEvent(tr) == "input")
915
- this.composing = 2 /* Changed */;
916
- else if (this.composing == 2 /* Changed */ && tr.selection)
917
- this.composing = 3 /* ChangedAndMoved */;
937
+ this.composing = 2 /* CompositionState.Changed */;
938
+ else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
939
+ this.composing = 3 /* CompositionState.ChangedAndMoved */;
918
940
  }
919
941
  }
920
942
  startUpdate() {
921
943
  this.debounceUpdate = -1;
922
944
  let { state } = this.view, cState = state.field(completionState);
923
945
  for (let active of cState.active) {
924
- if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
946
+ if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
925
947
  this.startQuery(active);
926
948
  }
927
949
  }
@@ -972,14 +994,14 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
972
994
  }
973
995
  }
974
996
  let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
975
- if (current && current.state == 1 /* Pending */) {
997
+ if (current && current.state == 1 /* State.Pending */) {
976
998
  if (query.done == null) {
977
999
  // Explicitly failed. Should clear the pending status if it
978
1000
  // hasn't been re-set in the meantime.
979
- let active = new ActiveSource(query.active.source, 0 /* Inactive */);
1001
+ let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
980
1002
  for (let tr of query.updates)
981
1003
  active = active.update(tr, conf);
982
- if (active.state != 1 /* Pending */)
1004
+ if (active.state != 1 /* State.Pending */)
983
1005
  updated.push(active);
984
1006
  }
985
1007
  else {
@@ -999,15 +1021,15 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
999
1021
  this.view.dispatch({ effects: closeCompletionEffect.of(null) });
1000
1022
  },
1001
1023
  compositionstart() {
1002
- this.composing = 1 /* Started */;
1024
+ this.composing = 1 /* CompositionState.Started */;
1003
1025
  },
1004
1026
  compositionend() {
1005
- if (this.composing == 3 /* ChangedAndMoved */) {
1027
+ if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
1006
1028
  // Safari fires compositionend events synchronously, possibly
1007
1029
  // from inside an update, so dispatch asynchronously to avoid reentrancy
1008
1030
  setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
1009
1031
  }
1010
- this.composing = 0 /* None */;
1032
+ this.composing = 0 /* CompositionState.None */;
1011
1033
  }
1012
1034
  }
1013
1035
  });
@@ -1052,10 +1074,13 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
1052
1074
  position: "absolute",
1053
1075
  padding: "3px 9px",
1054
1076
  width: "max-content",
1055
- maxWidth: "300px",
1077
+ maxWidth: `${400 /* Info.Width */}px`,
1078
+ boxSizing: "border-box"
1056
1079
  },
1057
1080
  ".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
1058
1081
  ".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
1082
+ ".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
1083
+ ".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
1059
1084
  "&light .cm-snippetField": { backgroundColor: "#00000022" },
1060
1085
  "&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
1061
1086
  ".cm-snippetFieldPosition": {
@@ -1390,7 +1415,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
1390
1415
  if (!seen[m[0]] && pos + m.index != ignoreAt) {
1391
1416
  result.push({ type: "text", label: m[0] });
1392
1417
  seen[m[0]] = true;
1393
- if (result.length >= 2000 /* MaxList */)
1418
+ if (result.length >= 2000 /* C.MaxList */)
1394
1419
  return;
1395
1420
  }
1396
1421
  }
@@ -1398,7 +1423,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
1398
1423
  }
1399
1424
  }
1400
1425
  function collectWords(doc, cache, wordRE, to, ignoreAt) {
1401
- let big = doc.length >= 1000 /* MinCacheLen */;
1426
+ let big = doc.length >= 1000 /* C.MinCacheLen */;
1402
1427
  let cached = big && cache.get(doc);
1403
1428
  if (cached)
1404
1429
  return cached;
@@ -1406,7 +1431,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
1406
1431
  if (doc.children) {
1407
1432
  let pos = 0;
1408
1433
  for (let ch of doc.children) {
1409
- if (ch.length >= 1000 /* MinCacheLen */) {
1434
+ if (ch.length >= 1000 /* C.MinCacheLen */) {
1410
1435
  for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
1411
1436
  if (!seen[c.label]) {
1412
1437
  seen[c.label] = true;
@@ -1423,7 +1448,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
1423
1448
  else {
1424
1449
  storeWords(doc, wordRE, result, seen, ignoreAt);
1425
1450
  }
1426
- if (big && result.length < 2000 /* MaxList */)
1451
+ if (big && result.length < 2000 /* C.MaxList */)
1427
1452
  cache.set(doc, result);
1428
1453
  return result;
1429
1454
  }
@@ -1439,7 +1464,7 @@ const completeAnyWord = context => {
1439
1464
  if (!token && !context.explicit)
1440
1465
  return null;
1441
1466
  let from = token ? token.from : context.pos;
1442
- let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
1467
+ let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from);
1443
1468
  return { from, options, validFor: mapRE(re, s => "^" + s) };
1444
1469
  };
1445
1470
 
@@ -1528,14 +1553,13 @@ const deleteBracketPair = ({ state, dispatch }) => {
1528
1553
  for (let token of tokens) {
1529
1554
  if (token == before && nextChar(state.doc, range.head) == closing(codePointAt(token, 0)))
1530
1555
  return { changes: { from: range.head - token.length, to: range.head + token.length },
1531
- range: EditorSelection.cursor(range.head - token.length),
1532
- userEvent: "delete.backward" };
1556
+ range: EditorSelection.cursor(range.head - token.length) };
1533
1557
  }
1534
1558
  }
1535
1559
  return { range: dont = range };
1536
1560
  });
1537
1561
  if (!dont)
1538
- dispatch(state.update(changes, { scrollIntoView: true }));
1562
+ dispatch(state.update(changes, { scrollIntoView: true, userEvent: "delete.backward" }));
1539
1563
  return !dont;
1540
1564
  };
1541
1565
  /**
@@ -1721,8 +1745,8 @@ returns `null`.
1721
1745
  */
1722
1746
  function completionStatus(state) {
1723
1747
  let cState = state.field(completionState, false);
1724
- return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
1725
- : cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
1748
+ return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending"
1749
+ : cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null;
1726
1750
  }
1727
1751
  const completionArrayCache = /*@__PURE__*/new WeakMap;
1728
1752
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",