@codemirror/autocomplete 6.16.3 → 6.17.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,13 @@
1
+ ## 6.17.0 (2024-07-03)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where completions weren't properly reset when starting a new completion through `activateOnCompletion`.
6
+
7
+ ### New features
8
+
9
+ `CompletionContext` objects now have a `view` property that holds the editor view when the query context has a view available.
10
+
1
11
  ## 6.16.3 (2024-06-19)
2
12
 
3
13
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -28,10 +28,19 @@ class CompletionContext {
28
28
  only return completions when either there is part of a
29
29
  completable entity before the cursor, or `explicit` is true.
30
30
  */
31
- explicit) {
31
+ explicit,
32
+ /**
33
+ The editor view. May be undefined if the context was created
34
+ in a situation where there is no such view available, such as
35
+ in synchronous updates via
36
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
37
+ or when called by test code.
38
+ */
39
+ view) {
32
40
  this.state = state;
33
41
  this.pos = pos;
34
42
  this.explicit = explicit;
43
+ this.view = view;
35
44
  /**
36
45
  @internal
37
46
  */
@@ -884,13 +893,18 @@ function makeAttrs(id, selected) {
884
893
  return result;
885
894
  }
886
895
  const none = [];
887
- function getUserEvent(tr, conf) {
896
+ function getUpdateType(tr, conf) {
888
897
  if (tr.isUserEvent("input.complete")) {
889
898
  let completion = tr.annotation(pickedCompletion);
890
899
  if (completion && conf.activateOnCompletion(completion))
891
- return "input";
900
+ return 4 /* UpdateType.Activate */ | 8 /* UpdateType.Reset */;
892
901
  }
893
- return tr.isUserEvent("input.type") ? "input" : tr.isUserEvent("delete.backward") ? "delete" : null;
902
+ let typing = tr.isUserEvent("input.type");
903
+ return typing && conf.activateOnTyping ? 4 /* UpdateType.Activate */ | 1 /* UpdateType.Typing */
904
+ : typing ? 1 /* UpdateType.Typing */
905
+ : tr.isUserEvent("delete.backward") ? 2 /* UpdateType.Backspacing */
906
+ : tr.selection ? 8 /* UpdateType.Reset */
907
+ : tr.docChanged ? 16 /* UpdateType.ResetIfTouching */ : 0 /* UpdateType.None */;
894
908
  }
895
909
  class ActiveSource {
896
910
  constructor(source, state, explicitPos = -1) {
@@ -900,13 +914,12 @@ class ActiveSource {
900
914
  }
901
915
  hasResult() { return false; }
902
916
  update(tr, conf) {
903
- let event = getUserEvent(tr, conf), value = this;
904
- if (event)
905
- value = value.handleUserEvent(tr, event, conf);
906
- else if (tr.docChanged)
907
- value = value.handleChange(tr);
908
- else if (tr.selection && value.state != 0 /* State.Inactive */)
917
+ let type = getUpdateType(tr, conf), value = this;
918
+ if ((type & 8 /* UpdateType.Reset */) || (type & 16 /* UpdateType.ResetIfTouching */) && this.touches(tr))
909
919
  value = new ActiveSource(value.source, 0 /* State.Inactive */);
920
+ if ((type & 4 /* UpdateType.Activate */) && value.state == 0 /* State.Inactive */)
921
+ value = new ActiveSource(this.source, 1 /* State.Pending */);
922
+ value = value.updateFor(tr, type);
910
923
  for (let effect of tr.effects) {
911
924
  if (effect.is(startCompletionEffect))
912
925
  value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
@@ -919,15 +932,13 @@ class ActiveSource {
919
932
  }
920
933
  return value;
921
934
  }
922
- handleUserEvent(tr, type, conf) {
923
- return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
924
- }
925
- handleChange(tr) {
926
- return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
927
- }
935
+ updateFor(tr, type) { return this.map(tr.changes); }
928
936
  map(changes) {
929
937
  return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
930
938
  }
939
+ touches(tr) {
940
+ return tr.changes.touchesRange(cur(tr.state));
941
+ }
931
942
  }
932
943
  class ActiveResult extends ActiveSource {
933
944
  constructor(source, explicitPos, result, from, to) {
@@ -937,8 +948,10 @@ class ActiveResult extends ActiveSource {
937
948
  this.to = to;
938
949
  }
939
950
  hasResult() { return true; }
940
- handleUserEvent(tr, type, conf) {
951
+ updateFor(tr, type) {
941
952
  var _a;
953
+ if (!(type & 3 /* UpdateType.SimpleInteraction */))
954
+ return this.map(tr.changes);
942
955
  let result = this.result;
943
956
  if (result.map && !tr.changes.empty)
944
957
  result = result.map(result, tr.changes);
@@ -946,8 +959,8 @@ class ActiveResult extends ActiveSource {
946
959
  let pos = cur(tr.state);
947
960
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
948
961
  pos > to || !result ||
949
- type == "delete" && cur(tr.startState) == this.from)
950
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
962
+ (type & 2 /* UpdateType.Backspacing */) && cur(tr.startState) == this.from)
963
+ return new ActiveSource(this.source, type & 4 /* UpdateType.Activate */ ? 1 /* State.Pending */ : 0 /* State.Inactive */);
951
964
  let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
952
965
  if (checkValid(result.validFor, tr.state, from, to))
953
966
  return new ActiveResult(this.source, explicitPos, result, from, to);
@@ -956,9 +969,6 @@ class ActiveResult extends ActiveSource {
956
969
  return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
957
970
  return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
958
971
  }
959
- handleChange(tr) {
960
- return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
961
- }
962
972
  map(mapping) {
963
973
  if (mapping.empty)
964
974
  return this;
@@ -967,6 +977,9 @@ class ActiveResult extends ActiveSource {
967
977
  return new ActiveSource(this.source, 0 /* State.Inactive */);
968
978
  return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
969
979
  }
980
+ touches(tr) {
981
+ return tr.changes.touchesRange(this.from, this.to);
982
+ }
970
983
  }
971
984
  function checkValid(validFor, state, from, to) {
972
985
  if (!validFor)
@@ -1083,7 +1096,8 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1083
1096
  if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
1084
1097
  return;
1085
1098
  let doesReset = update.transactions.some(tr => {
1086
- return (tr.selection || tr.docChanged) && !getUserEvent(tr, conf);
1099
+ let type = getUpdateType(tr, conf);
1100
+ return (type & 8 /* UpdateType.Reset */) || (tr.selection || tr.docChanged) && !(type & 3 /* UpdateType.SimpleInteraction */);
1087
1101
  });
1088
1102
  for (let i = 0; i < this.running.length; i++) {
1089
1103
  let query = this.running[i];
@@ -1113,7 +1127,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1113
1127
  ? setTimeout(() => this.startUpdate(), delay) : -1;
1114
1128
  if (this.composing != 0 /* CompositionState.None */)
1115
1129
  for (let tr of update.transactions) {
1116
- if (getUserEvent(tr, conf) == "input")
1130
+ if (tr.isUserEvent("input.type"))
1117
1131
  this.composing = 2 /* CompositionState.Changed */;
1118
1132
  else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
1119
1133
  this.composing = 3 /* CompositionState.ChangedAndMoved */;
@@ -1130,7 +1144,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1130
1144
  }
1131
1145
  startQuery(active) {
1132
1146
  let { state } = this.view, pos = cur(state);
1133
- let context = new CompletionContext(state, pos, active.explicitPos == pos);
1147
+ let context = new CompletionContext(state, pos, active.explicitPos == pos, this.view);
1134
1148
  let pending = new RunningQuery(active, context);
1135
1149
  this.running.push(pending);
1136
1150
  Promise.resolve(active.source(context)).then(result => {
package/dist/index.d.cts CHANGED
@@ -129,6 +129,14 @@ declare class CompletionContext {
129
129
  */
130
130
  readonly explicit: boolean;
131
131
  /**
132
+ The editor view. May be undefined if the context was created
133
+ in a situation where there is no such view available, such as
134
+ in synchronous updates via
135
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
136
+ or when called by test code.
137
+ */
138
+ readonly view?: EditorView | undefined;
139
+ /**
132
140
  Create a new completion context. (Mostly useful for testing
133
141
  completion sources—in the editor, the extension will create
134
142
  these for you.)
@@ -148,7 +156,15 @@ declare class CompletionContext {
148
156
  only return completions when either there is part of a
149
157
  completable entity before the cursor, or `explicit` is true.
150
158
  */
151
- explicit: boolean);
159
+ explicit: boolean,
160
+ /**
161
+ The editor view. May be undefined if the context was created
162
+ in a situation where there is no such view available, such as
163
+ in synchronous updates via
164
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
165
+ or when called by test code.
166
+ */
167
+ view?: EditorView | undefined);
152
168
  /**
153
169
  Get the extent, content, and (if there is a token) type of the
154
170
  token before `this.pos`.
package/dist/index.d.ts CHANGED
@@ -129,6 +129,14 @@ declare class CompletionContext {
129
129
  */
130
130
  readonly explicit: boolean;
131
131
  /**
132
+ The editor view. May be undefined if the context was created
133
+ in a situation where there is no such view available, such as
134
+ in synchronous updates via
135
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
136
+ or when called by test code.
137
+ */
138
+ readonly view?: EditorView | undefined;
139
+ /**
132
140
  Create a new completion context. (Mostly useful for testing
133
141
  completion sources—in the editor, the extension will create
134
142
  these for you.)
@@ -148,7 +156,15 @@ declare class CompletionContext {
148
156
  only return completions when either there is part of a
149
157
  completable entity before the cursor, or `explicit` is true.
150
158
  */
151
- explicit: boolean);
159
+ explicit: boolean,
160
+ /**
161
+ The editor view. May be undefined if the context was created
162
+ in a situation where there is no such view available, such as
163
+ in synchronous updates via
164
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
165
+ or when called by test code.
166
+ */
167
+ view?: EditorView | undefined);
152
168
  /**
153
169
  Get the extent, content, and (if there is a token) type of the
154
170
  token before `this.pos`.
package/dist/index.js CHANGED
@@ -26,10 +26,19 @@ class CompletionContext {
26
26
  only return completions when either there is part of a
27
27
  completable entity before the cursor, or `explicit` is true.
28
28
  */
29
- explicit) {
29
+ explicit,
30
+ /**
31
+ The editor view. May be undefined if the context was created
32
+ in a situation where there is no such view available, such as
33
+ in synchronous updates via
34
+ [`CompletionResult.update`](https://codemirror.net/6/docs/ref/#autocomplete.CompletionResult.update)
35
+ or when called by test code.
36
+ */
37
+ view) {
30
38
  this.state = state;
31
39
  this.pos = pos;
32
40
  this.explicit = explicit;
41
+ this.view = view;
33
42
  /**
34
43
  @internal
35
44
  */
@@ -882,13 +891,18 @@ function makeAttrs(id, selected) {
882
891
  return result;
883
892
  }
884
893
  const none = [];
885
- function getUserEvent(tr, conf) {
894
+ function getUpdateType(tr, conf) {
886
895
  if (tr.isUserEvent("input.complete")) {
887
896
  let completion = tr.annotation(pickedCompletion);
888
897
  if (completion && conf.activateOnCompletion(completion))
889
- return "input";
898
+ return 4 /* UpdateType.Activate */ | 8 /* UpdateType.Reset */;
890
899
  }
891
- return tr.isUserEvent("input.type") ? "input" : tr.isUserEvent("delete.backward") ? "delete" : null;
900
+ let typing = tr.isUserEvent("input.type");
901
+ return typing && conf.activateOnTyping ? 4 /* UpdateType.Activate */ | 1 /* UpdateType.Typing */
902
+ : typing ? 1 /* UpdateType.Typing */
903
+ : tr.isUserEvent("delete.backward") ? 2 /* UpdateType.Backspacing */
904
+ : tr.selection ? 8 /* UpdateType.Reset */
905
+ : tr.docChanged ? 16 /* UpdateType.ResetIfTouching */ : 0 /* UpdateType.None */;
892
906
  }
893
907
  class ActiveSource {
894
908
  constructor(source, state, explicitPos = -1) {
@@ -898,13 +912,12 @@ class ActiveSource {
898
912
  }
899
913
  hasResult() { return false; }
900
914
  update(tr, conf) {
901
- let event = getUserEvent(tr, conf), value = this;
902
- if (event)
903
- value = value.handleUserEvent(tr, event, conf);
904
- else if (tr.docChanged)
905
- value = value.handleChange(tr);
906
- else if (tr.selection && value.state != 0 /* State.Inactive */)
915
+ let type = getUpdateType(tr, conf), value = this;
916
+ if ((type & 8 /* UpdateType.Reset */) || (type & 16 /* UpdateType.ResetIfTouching */) && this.touches(tr))
907
917
  value = new ActiveSource(value.source, 0 /* State.Inactive */);
918
+ if ((type & 4 /* UpdateType.Activate */) && value.state == 0 /* State.Inactive */)
919
+ value = new ActiveSource(this.source, 1 /* State.Pending */);
920
+ value = value.updateFor(tr, type);
908
921
  for (let effect of tr.effects) {
909
922
  if (effect.is(startCompletionEffect))
910
923
  value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
@@ -917,15 +930,13 @@ class ActiveSource {
917
930
  }
918
931
  return value;
919
932
  }
920
- handleUserEvent(tr, type, conf) {
921
- return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
922
- }
923
- handleChange(tr) {
924
- return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
925
- }
933
+ updateFor(tr, type) { return this.map(tr.changes); }
926
934
  map(changes) {
927
935
  return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
928
936
  }
937
+ touches(tr) {
938
+ return tr.changes.touchesRange(cur(tr.state));
939
+ }
929
940
  }
930
941
  class ActiveResult extends ActiveSource {
931
942
  constructor(source, explicitPos, result, from, to) {
@@ -935,8 +946,10 @@ class ActiveResult extends ActiveSource {
935
946
  this.to = to;
936
947
  }
937
948
  hasResult() { return true; }
938
- handleUserEvent(tr, type, conf) {
949
+ updateFor(tr, type) {
939
950
  var _a;
951
+ if (!(type & 3 /* UpdateType.SimpleInteraction */))
952
+ return this.map(tr.changes);
940
953
  let result = this.result;
941
954
  if (result.map && !tr.changes.empty)
942
955
  result = result.map(result, tr.changes);
@@ -944,8 +957,8 @@ class ActiveResult extends ActiveSource {
944
957
  let pos = cur(tr.state);
945
958
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
946
959
  pos > to || !result ||
947
- type == "delete" && cur(tr.startState) == this.from)
948
- return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
960
+ (type & 2 /* UpdateType.Backspacing */) && cur(tr.startState) == this.from)
961
+ return new ActiveSource(this.source, type & 4 /* UpdateType.Activate */ ? 1 /* State.Pending */ : 0 /* State.Inactive */);
949
962
  let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
950
963
  if (checkValid(result.validFor, tr.state, from, to))
951
964
  return new ActiveResult(this.source, explicitPos, result, from, to);
@@ -954,9 +967,6 @@ class ActiveResult extends ActiveSource {
954
967
  return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
955
968
  return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
956
969
  }
957
- handleChange(tr) {
958
- return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
959
- }
960
970
  map(mapping) {
961
971
  if (mapping.empty)
962
972
  return this;
@@ -965,6 +975,9 @@ class ActiveResult extends ActiveSource {
965
975
  return new ActiveSource(this.source, 0 /* State.Inactive */);
966
976
  return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
967
977
  }
978
+ touches(tr) {
979
+ return tr.changes.touchesRange(this.from, this.to);
980
+ }
968
981
  }
969
982
  function checkValid(validFor, state, from, to) {
970
983
  if (!validFor)
@@ -1081,7 +1094,8 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1081
1094
  if (!update.selectionSet && !update.docChanged && update.startState.field(completionState) == cState)
1082
1095
  return;
1083
1096
  let doesReset = update.transactions.some(tr => {
1084
- return (tr.selection || tr.docChanged) && !getUserEvent(tr, conf);
1097
+ let type = getUpdateType(tr, conf);
1098
+ return (type & 8 /* UpdateType.Reset */) || (tr.selection || tr.docChanged) && !(type & 3 /* UpdateType.SimpleInteraction */);
1085
1099
  });
1086
1100
  for (let i = 0; i < this.running.length; i++) {
1087
1101
  let query = this.running[i];
@@ -1111,7 +1125,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1111
1125
  ? setTimeout(() => this.startUpdate(), delay) : -1;
1112
1126
  if (this.composing != 0 /* CompositionState.None */)
1113
1127
  for (let tr of update.transactions) {
1114
- if (getUserEvent(tr, conf) == "input")
1128
+ if (tr.isUserEvent("input.type"))
1115
1129
  this.composing = 2 /* CompositionState.Changed */;
1116
1130
  else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
1117
1131
  this.composing = 3 /* CompositionState.ChangedAndMoved */;
@@ -1128,7 +1142,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1128
1142
  }
1129
1143
  startQuery(active) {
1130
1144
  let { state } = this.view, pos = cur(state);
1131
- let context = new CompletionContext(state, pos, active.explicitPos == pos);
1145
+ let context = new CompletionContext(state, pos, active.explicitPos == pos, this.view);
1132
1146
  let pending = new RunningQuery(active, context);
1133
1147
  this.running.push(pending);
1134
1148
  Promise.resolve(active.source(context)).then(result => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.16.3",
3
+ "version": "6.17.0",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",