@codemirror/autocomplete 6.12.0 → 6.14.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,15 @@
1
+ ## 6.14.0 (2024-03-10)
2
+
3
+ ### New features
4
+
5
+ Completion results can now define a `map` method that can be used to adjust position-dependent information for document changes.
6
+
7
+ ## 6.13.0 (2024-02-29)
8
+
9
+ ### New features
10
+
11
+ Completions may now provide 'commit characters' that, when typed, commit the completion before inserting the character.
12
+
1
13
  ## 6.12.0 (2024-01-12)
2
14
 
3
15
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -909,26 +909,33 @@ class ActiveResult extends ActiveSource {
909
909
  hasResult() { return true; }
910
910
  handleUserEvent(tr, type, conf) {
911
911
  var _a;
912
+ let result = this.result;
913
+ if (result.map && !tr.changes.empty)
914
+ result = result.map(result, tr.changes);
912
915
  let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
913
916
  let pos = cur(tr.state);
914
917
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
915
- pos > to ||
918
+ pos > to || !result ||
916
919
  type == "delete" && cur(tr.startState) == this.from)
917
920
  return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
918
- let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
919
- if (checkValid(this.result.validFor, tr.state, from, to))
920
- return new ActiveResult(this.source, explicitPos, this.result, from, to);
921
- if (this.result.update &&
922
- (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
923
- return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
921
+ let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
922
+ if (checkValid(result.validFor, tr.state, from, to))
923
+ return new ActiveResult(this.source, explicitPos, result, from, to);
924
+ if (result.update &&
925
+ (result = result.update(result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
926
+ return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
924
927
  return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
925
928
  }
926
929
  handleChange(tr) {
927
930
  return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
928
931
  }
929
932
  map(mapping) {
930
- return mapping.empty ? this :
931
- new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
933
+ if (mapping.empty)
934
+ return this;
935
+ let result = this.result.map ? this.result.map(this.result, mapping) : this.result;
936
+ if (!result)
937
+ return new ActiveSource(this.source, 0 /* State.Inactive */);
938
+ return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
932
939
  }
933
940
  }
934
941
  function checkValid(validFor, state, from, to) {
@@ -1179,6 +1186,21 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1179
1186
  }
1180
1187
  }
1181
1188
  });
1189
+ const windows = typeof navigator == "object" && /Win/.test(navigator.platform);
1190
+ const commitCharacters = state.Prec.highest(view.EditorView.domEventHandlers({
1191
+ keydown(event, view) {
1192
+ let field = view.state.field(completionState, false);
1193
+ if (!field || !field.open || field.open.disabled || field.open.selected < 0 ||
1194
+ event.key.length > 1 || event.ctrlKey && !(windows && event.altKey) || event.metaKey)
1195
+ return false;
1196
+ let option = field.open.options[field.open.selected];
1197
+ let result = field.active.find(a => a.source == option.source);
1198
+ let commitChars = option.completion.commitCharacters || result.result.commitCharacters;
1199
+ if (commitChars && commitChars.indexOf(event.key) > -1)
1200
+ applyCompletion(view, option);
1201
+ return false;
1202
+ }
1203
+ }));
1182
1204
 
1183
1205
  const baseTheme = view.EditorView.baseTheme({
1184
1206
  ".cm-tooltip.cm-tooltip-autocomplete": {
@@ -1900,6 +1922,7 @@ Returns an extension that enables autocompletion.
1900
1922
  */
1901
1923
  function autocompletion(config = {}) {
1902
1924
  return [
1925
+ commitCharacters,
1903
1926
  completionState,
1904
1927
  completionConfig.of(config),
1905
1928
  completionPlugin,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _codemirror_state from '@codemirror/state';
2
- import { EditorState, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
2
+ import { EditorState, ChangeDesc, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
3
3
  import { EditorView, Rect, KeyBinding, Command } from '@codemirror/view';
4
4
  import * as _lezer_common from '@lezer/common';
5
5
 
@@ -54,6 +54,11 @@ interface Completion {
54
54
  */
55
55
  type?: string;
56
56
  /**
57
+ When this option is selected, and one of these characters is
58
+ typed, insert the completion before typing the character.
59
+ */
60
+ commitCharacters?: readonly string[];
61
+ /**
57
62
  When given, should be a number from -99 to 99 that adjusts how
58
63
  this completion is ranked compared to other completions that
59
64
  match the input as well as this one. A negative number moves it
@@ -255,6 +260,20 @@ interface CompletionResult {
255
260
  completion still applies in the new state.
256
261
  */
257
262
  update?: (current: CompletionResult, from: number, to: number, context: CompletionContext) => CompletionResult | null;
263
+ /**
264
+ When results contain position-dependent information in, for
265
+ example, `apply` methods, you can provide this method to update
266
+ the result for transactions that happen after the query. It is
267
+ not necessary to update `from` and `to`—those are tracked
268
+ automatically.
269
+ */
270
+ map?: (current: CompletionResult, changes: ChangeDesc) => CompletionResult | null;
271
+ /**
272
+ Set a default set of [commit
273
+ characters](https://codemirror.net/6/docs/ref/#autocomplete.Completion.commitCharacters) for all
274
+ options in this result.
275
+ */
276
+ commitCharacters?: readonly string[];
258
277
  }
259
278
  /**
260
279
  This annotation is added to transactions that are produced by
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _codemirror_state from '@codemirror/state';
2
- import { EditorState, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
2
+ import { EditorState, ChangeDesc, TransactionSpec, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
3
3
  import { EditorView, Rect, KeyBinding, Command } from '@codemirror/view';
4
4
  import * as _lezer_common from '@lezer/common';
5
5
 
@@ -54,6 +54,11 @@ interface Completion {
54
54
  */
55
55
  type?: string;
56
56
  /**
57
+ When this option is selected, and one of these characters is
58
+ typed, insert the completion before typing the character.
59
+ */
60
+ commitCharacters?: readonly string[];
61
+ /**
57
62
  When given, should be a number from -99 to 99 that adjusts how
58
63
  this completion is ranked compared to other completions that
59
64
  match the input as well as this one. A negative number moves it
@@ -255,6 +260,20 @@ interface CompletionResult {
255
260
  completion still applies in the new state.
256
261
  */
257
262
  update?: (current: CompletionResult, from: number, to: number, context: CompletionContext) => CompletionResult | null;
263
+ /**
264
+ When results contain position-dependent information in, for
265
+ example, `apply` methods, you can provide this method to update
266
+ the result for transactions that happen after the query. It is
267
+ not necessary to update `from` and `to`—those are tracked
268
+ automatically.
269
+ */
270
+ map?: (current: CompletionResult, changes: ChangeDesc) => CompletionResult | null;
271
+ /**
272
+ Set a default set of [commit
273
+ characters](https://codemirror.net/6/docs/ref/#autocomplete.Completion.commitCharacters) for all
274
+ options in this result.
275
+ */
276
+ commitCharacters?: readonly string[];
258
277
  }
259
278
  /**
260
279
  This annotation is added to transactions that are produced by
package/dist/index.js CHANGED
@@ -907,26 +907,33 @@ class ActiveResult extends ActiveSource {
907
907
  hasResult() { return true; }
908
908
  handleUserEvent(tr, type, conf) {
909
909
  var _a;
910
+ let result = this.result;
911
+ if (result.map && !tr.changes.empty)
912
+ result = result.map(result, tr.changes);
910
913
  let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
911
914
  let pos = cur(tr.state);
912
915
  if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
913
- pos > to ||
916
+ pos > to || !result ||
914
917
  type == "delete" && cur(tr.startState) == this.from)
915
918
  return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
916
- let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
917
- if (checkValid(this.result.validFor, tr.state, from, to))
918
- return new ActiveResult(this.source, explicitPos, this.result, from, to);
919
- if (this.result.update &&
920
- (updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
921
- return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
919
+ let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
920
+ if (checkValid(result.validFor, tr.state, from, to))
921
+ return new ActiveResult(this.source, explicitPos, result, from, to);
922
+ if (result.update &&
923
+ (result = result.update(result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
924
+ return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
922
925
  return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
923
926
  }
924
927
  handleChange(tr) {
925
928
  return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
926
929
  }
927
930
  map(mapping) {
928
- return mapping.empty ? this :
929
- new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
931
+ if (mapping.empty)
932
+ return this;
933
+ let result = this.result.map ? this.result.map(this.result, mapping) : this.result;
934
+ if (!result)
935
+ return new ActiveSource(this.source, 0 /* State.Inactive */);
936
+ return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
930
937
  }
931
938
  }
932
939
  function checkValid(validFor, state, from, to) {
@@ -1177,6 +1184,21 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1177
1184
  }
1178
1185
  }
1179
1186
  });
1187
+ const windows = typeof navigator == "object" && /*@__PURE__*//Win/.test(navigator.platform);
1188
+ const commitCharacters = /*@__PURE__*/Prec.highest(/*@__PURE__*/EditorView.domEventHandlers({
1189
+ keydown(event, view) {
1190
+ let field = view.state.field(completionState, false);
1191
+ if (!field || !field.open || field.open.disabled || field.open.selected < 0 ||
1192
+ event.key.length > 1 || event.ctrlKey && !(windows && event.altKey) || event.metaKey)
1193
+ return false;
1194
+ let option = field.open.options[field.open.selected];
1195
+ let result = field.active.find(a => a.source == option.source);
1196
+ let commitChars = option.completion.commitCharacters || result.result.commitCharacters;
1197
+ if (commitChars && commitChars.indexOf(event.key) > -1)
1198
+ applyCompletion(view, option);
1199
+ return false;
1200
+ }
1201
+ }));
1180
1202
 
1181
1203
  const baseTheme = /*@__PURE__*/EditorView.baseTheme({
1182
1204
  ".cm-tooltip.cm-tooltip-autocomplete": {
@@ -1898,6 +1920,7 @@ Returns an extension that enables autocompletion.
1898
1920
  */
1899
1921
  function autocompletion(config = {}) {
1900
1922
  return [
1923
+ commitCharacters,
1901
1924
  completionState,
1902
1925
  completionConfig.of(config),
1903
1926
  completionPlugin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.12.0",
3
+ "version": "6.14.0",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",