@codemirror/autocomplete 6.11.1 → 6.12.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 +14 -0
- package/dist/index.cjs +10 -4
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +11 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 6.12.0 (2024-01-12)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make sure snippet completions also set `userEvent` to `input.complete`.
|
|
6
|
+
|
|
7
|
+
Fix a crash when the editor lost focus during an update and autocompletion was active.
|
|
8
|
+
|
|
9
|
+
Fix a crash when using a snippet that has only one field, but multiple instances of that field.
|
|
10
|
+
|
|
11
|
+
### New features
|
|
12
|
+
|
|
13
|
+
The new `activateOnTypingDelay` option allows control over the debounce time before the completions are queried when the user types.
|
|
14
|
+
|
|
1
15
|
## 6.11.1 (2023-11-27)
|
|
2
16
|
|
|
3
17
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -329,6 +329,7 @@ const completionConfig = state.Facet.define({
|
|
|
329
329
|
combine(configs) {
|
|
330
330
|
return state.combineConfig(configs, {
|
|
331
331
|
activateOnTyping: true,
|
|
332
|
+
activateOnTypingDelay: 100,
|
|
332
333
|
selectOnOpen: true,
|
|
333
334
|
override: null,
|
|
334
335
|
closeOnBlur: true,
|
|
@@ -1033,6 +1034,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
1033
1034
|
this.debounceUpdate = -1;
|
|
1034
1035
|
this.running = [];
|
|
1035
1036
|
this.debounceAccept = -1;
|
|
1037
|
+
this.pendingStart = false;
|
|
1036
1038
|
this.composing = 0 /* CompositionState.None */;
|
|
1037
1039
|
for (let active of view.state.field(completionState).active)
|
|
1038
1040
|
if (active.state == 1 /* State.Pending */)
|
|
@@ -1066,8 +1068,11 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
1066
1068
|
}
|
|
1067
1069
|
if (this.debounceUpdate > -1)
|
|
1068
1070
|
clearTimeout(this.debounceUpdate);
|
|
1071
|
+
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect))))
|
|
1072
|
+
this.pendingStart = true;
|
|
1073
|
+
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay;
|
|
1069
1074
|
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
1070
|
-
? setTimeout(() => this.startUpdate(),
|
|
1075
|
+
? setTimeout(() => this.startUpdate(), delay) : -1;
|
|
1071
1076
|
if (this.composing != 0 /* CompositionState.None */)
|
|
1072
1077
|
for (let tr of update.transactions) {
|
|
1073
1078
|
if (getUserEvent(tr) == "input")
|
|
@@ -1078,6 +1083,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
1078
1083
|
}
|
|
1079
1084
|
startUpdate() {
|
|
1080
1085
|
this.debounceUpdate = -1;
|
|
1086
|
+
this.pendingStart = false;
|
|
1081
1087
|
let { state } = this.view, cState = state.field(completionState);
|
|
1082
1088
|
for (let active of cState.active) {
|
|
1083
1089
|
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
@@ -1157,7 +1163,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
1157
1163
|
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
|
1158
1164
|
let dialog = state.open && view.getTooltip(this.view, state.open.tooltip);
|
|
1159
1165
|
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
|
1160
|
-
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
1166
|
+
setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
|
|
1161
1167
|
}
|
|
1162
1168
|
},
|
|
1163
1169
|
compositionstart() {
|
|
@@ -1465,11 +1471,11 @@ function snippet(template) {
|
|
|
1465
1471
|
let spec = {
|
|
1466
1472
|
changes: { from, to, insert: state.Text.of(text) },
|
|
1467
1473
|
scrollIntoView: true,
|
|
1468
|
-
annotations: completion ? pickedCompletion.of(completion) : undefined
|
|
1474
|
+
annotations: completion ? [pickedCompletion.of(completion), state.Transaction.userEvent.of("input.complete")] : undefined
|
|
1469
1475
|
};
|
|
1470
1476
|
if (ranges.length)
|
|
1471
1477
|
spec.selection = fieldSelection(ranges, 0);
|
|
1472
|
-
if (ranges.
|
|
1478
|
+
if (ranges.some(r => r.field > 0)) {
|
|
1473
1479
|
let active = new ActiveSnippet(ranges, 0);
|
|
1474
1480
|
let effects = spec.effects = [setActive.of(active)];
|
|
1475
1481
|
if (editor.state.field(snippetState, false) === undefined)
|
package/dist/index.d.cts
CHANGED
|
@@ -275,6 +275,14 @@ interface CompletionConfig {
|
|
|
275
275
|
*/
|
|
276
276
|
activateOnTyping?: boolean;
|
|
277
277
|
/**
|
|
278
|
+
The amount of time to wait for further typing before querying
|
|
279
|
+
completion sources via
|
|
280
|
+
[`activateOnTyping`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.activateOnTyping).
|
|
281
|
+
Defaults to 100, which should be fine unless your completion
|
|
282
|
+
source is very slow and/or doesn't use `validFor`.
|
|
283
|
+
*/
|
|
284
|
+
activateOnTypingDelay?: number;
|
|
285
|
+
/**
|
|
278
286
|
By default, when completion opens, the first option is selected
|
|
279
287
|
and can be confirmed with
|
|
280
288
|
[`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion). When this
|
|
@@ -571,4 +579,4 @@ the currently selected completion.
|
|
|
571
579
|
*/
|
|
572
580
|
declare function setSelectedCompletion(index: number): StateEffect<unknown>;
|
|
573
581
|
|
|
574
|
-
export { CloseBracketConfig, Completion, CompletionContext, CompletionInfo, CompletionResult, CompletionSection, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
582
|
+
export { type CloseBracketConfig, type Completion, CompletionContext, type CompletionInfo, type CompletionResult, type CompletionSection, type CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
package/dist/index.d.ts
CHANGED
|
@@ -275,6 +275,14 @@ interface CompletionConfig {
|
|
|
275
275
|
*/
|
|
276
276
|
activateOnTyping?: boolean;
|
|
277
277
|
/**
|
|
278
|
+
The amount of time to wait for further typing before querying
|
|
279
|
+
completion sources via
|
|
280
|
+
[`activateOnTyping`](https://codemirror.net/6/docs/ref/#autocomplete.autocompletion^config.activateOnTyping).
|
|
281
|
+
Defaults to 100, which should be fine unless your completion
|
|
282
|
+
source is very slow and/or doesn't use `validFor`.
|
|
283
|
+
*/
|
|
284
|
+
activateOnTypingDelay?: number;
|
|
285
|
+
/**
|
|
278
286
|
By default, when completion opens, the first option is selected
|
|
279
287
|
and can be confirmed with
|
|
280
288
|
[`acceptCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.acceptCompletion). When this
|
|
@@ -571,4 +579,4 @@ the currently selected completion.
|
|
|
571
579
|
*/
|
|
572
580
|
declare function setSelectedCompletion(index: number): StateEffect<unknown>;
|
|
573
581
|
|
|
574
|
-
export { CloseBracketConfig, Completion, CompletionContext, CompletionInfo, CompletionResult, CompletionSection, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
582
|
+
export { type CloseBracketConfig, type Completion, CompletionContext, type CompletionInfo, type CompletionResult, type CompletionSection, type CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeBrackets, closeBracketsKeymap, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, deleteBracketPair, hasNextSnippetField, hasPrevSnippetField, ifIn, ifNotIn, insertBracket, insertCompletionText, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Annotation, StateEffect, EditorSelection, codePointAt, codePointSize, fromCodePoint, Facet, combineConfig, StateField, Prec, Text, MapMode, RangeValue, RangeSet, CharCategory } from '@codemirror/state';
|
|
1
|
+
import { Annotation, StateEffect, EditorSelection, codePointAt, codePointSize, fromCodePoint, Facet, combineConfig, StateField, Prec, Text, Transaction, MapMode, RangeValue, RangeSet, CharCategory } from '@codemirror/state';
|
|
2
2
|
import { Direction, logException, showTooltip, EditorView, ViewPlugin, getTooltip, Decoration, WidgetType, keymap } from '@codemirror/view';
|
|
3
3
|
import { syntaxTree, indentUnit } from '@codemirror/language';
|
|
4
4
|
|
|
@@ -327,6 +327,7 @@ const completionConfig = /*@__PURE__*/Facet.define({
|
|
|
327
327
|
combine(configs) {
|
|
328
328
|
return combineConfig(configs, {
|
|
329
329
|
activateOnTyping: true,
|
|
330
|
+
activateOnTypingDelay: 100,
|
|
330
331
|
selectOnOpen: true,
|
|
331
332
|
override: null,
|
|
332
333
|
closeOnBlur: true,
|
|
@@ -1031,6 +1032,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
1031
1032
|
this.debounceUpdate = -1;
|
|
1032
1033
|
this.running = [];
|
|
1033
1034
|
this.debounceAccept = -1;
|
|
1035
|
+
this.pendingStart = false;
|
|
1034
1036
|
this.composing = 0 /* CompositionState.None */;
|
|
1035
1037
|
for (let active of view.state.field(completionState).active)
|
|
1036
1038
|
if (active.state == 1 /* State.Pending */)
|
|
@@ -1064,8 +1066,11 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
1064
1066
|
}
|
|
1065
1067
|
if (this.debounceUpdate > -1)
|
|
1066
1068
|
clearTimeout(this.debounceUpdate);
|
|
1069
|
+
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect))))
|
|
1070
|
+
this.pendingStart = true;
|
|
1071
|
+
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay;
|
|
1067
1072
|
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
|
|
1068
|
-
? setTimeout(() => this.startUpdate(),
|
|
1073
|
+
? setTimeout(() => this.startUpdate(), delay) : -1;
|
|
1069
1074
|
if (this.composing != 0 /* CompositionState.None */)
|
|
1070
1075
|
for (let tr of update.transactions) {
|
|
1071
1076
|
if (getUserEvent(tr) == "input")
|
|
@@ -1076,6 +1081,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
1076
1081
|
}
|
|
1077
1082
|
startUpdate() {
|
|
1078
1083
|
this.debounceUpdate = -1;
|
|
1084
|
+
this.pendingStart = false;
|
|
1079
1085
|
let { state } = this.view, cState = state.field(completionState);
|
|
1080
1086
|
for (let active of cState.active) {
|
|
1081
1087
|
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
|
|
@@ -1155,7 +1161,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
1155
1161
|
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
|
|
1156
1162
|
let dialog = state.open && getTooltip(this.view, state.open.tooltip);
|
|
1157
1163
|
if (!dialog || !dialog.dom.contains(event.relatedTarget))
|
|
1158
|
-
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
|
|
1164
|
+
setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
|
|
1159
1165
|
}
|
|
1160
1166
|
},
|
|
1161
1167
|
compositionstart() {
|
|
@@ -1463,11 +1469,11 @@ function snippet(template) {
|
|
|
1463
1469
|
let spec = {
|
|
1464
1470
|
changes: { from, to, insert: Text.of(text) },
|
|
1465
1471
|
scrollIntoView: true,
|
|
1466
|
-
annotations: completion ? pickedCompletion.of(completion) : undefined
|
|
1472
|
+
annotations: completion ? [pickedCompletion.of(completion), Transaction.userEvent.of("input.complete")] : undefined
|
|
1467
1473
|
};
|
|
1468
1474
|
if (ranges.length)
|
|
1469
1475
|
spec.selection = fieldSelection(ranges, 0);
|
|
1470
|
-
if (ranges.
|
|
1476
|
+
if (ranges.some(r => r.field > 0)) {
|
|
1471
1477
|
let active = new ActiveSnippet(ranges, 0);
|
|
1472
1478
|
let effects = spec.effects = [setActive.of(active)];
|
|
1473
1479
|
if (editor.state.field(snippetState, false) === undefined)
|