@codemirror/autocomplete 0.19.12 → 0.19.15
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 +24 -0
- package/dist/index.cjs +69 -32
- package/dist/index.d.ts +13 -3
- package/dist/index.js +70 -35
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## 0.19.15 (2022-03-23)
|
|
2
|
+
|
|
3
|
+
### New features
|
|
4
|
+
|
|
5
|
+
The `selectedCompletionIndex` function tells you the position of the currently selected completion.
|
|
6
|
+
|
|
7
|
+
The new `setSelectionCompletion` function creates a state effect that moves the selected completion to a given index.
|
|
8
|
+
|
|
9
|
+
A completion's `info` method may now return null to indicate that no further info is available.
|
|
10
|
+
|
|
11
|
+
## 0.19.14 (2022-03-10)
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
Make the ARIA attributes added to the editor during autocompletion spec-compliant.
|
|
16
|
+
|
|
17
|
+
## 0.19.13 (2022-02-18)
|
|
18
|
+
|
|
19
|
+
### Bug fixes
|
|
20
|
+
|
|
21
|
+
Fix an issue where the completion tooltip stayed open if it was explicitly opened and the user backspaced past its start.
|
|
22
|
+
|
|
23
|
+
Stop snippet filling when a change happens across one of the snippet fields' boundaries.
|
|
24
|
+
|
|
1
25
|
## 0.19.12 (2022-01-11)
|
|
2
26
|
|
|
3
27
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -374,22 +374,6 @@ function optionContent(config) {
|
|
|
374
374
|
});
|
|
375
375
|
return content.sort((a, b) => a.position - b.position).map(a => a.render);
|
|
376
376
|
}
|
|
377
|
-
function createInfoDialog(option, view$1) {
|
|
378
|
-
let dom = document.createElement("div");
|
|
379
|
-
dom.className = "cm-tooltip cm-completionInfo";
|
|
380
|
-
let { info } = option.completion;
|
|
381
|
-
if (typeof info == "string") {
|
|
382
|
-
dom.textContent = info;
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
let content = info(option.completion);
|
|
386
|
-
if (content.then)
|
|
387
|
-
content.then(node => dom.appendChild(node), e => view.logException(view$1.state, e, "completion info"));
|
|
388
|
-
else
|
|
389
|
-
dom.appendChild(content);
|
|
390
|
-
}
|
|
391
|
-
return dom;
|
|
392
|
-
}
|
|
393
377
|
function rangeAroundSelected(total, selected, max) {
|
|
394
378
|
if (total <= max)
|
|
395
379
|
return { from: 0, to: total };
|
|
@@ -458,13 +442,31 @@ class CompletionTooltip {
|
|
|
458
442
|
this.info.remove();
|
|
459
443
|
this.info = null;
|
|
460
444
|
}
|
|
461
|
-
let
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
445
|
+
let { completion } = open.options[open.selected];
|
|
446
|
+
let { info } = completion;
|
|
447
|
+
if (!info)
|
|
448
|
+
return;
|
|
449
|
+
let infoResult = typeof info === 'string' ? document.createTextNode(info) : info(completion);
|
|
450
|
+
if (!infoResult)
|
|
451
|
+
return;
|
|
452
|
+
if ('then' in infoResult) {
|
|
453
|
+
infoResult.then(node => {
|
|
454
|
+
if (node && this.view.state.field(this.stateField, false) == cState)
|
|
455
|
+
this.addInfoPane(node);
|
|
456
|
+
}).catch(e => view.logException(this.view.state, e, "completion info"));
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
this.addInfoPane(infoResult);
|
|
465
460
|
}
|
|
466
461
|
}
|
|
467
462
|
}
|
|
463
|
+
addInfoPane(content) {
|
|
464
|
+
let dom = this.info = document.createElement("div");
|
|
465
|
+
dom.className = "cm-tooltip cm-completionInfo";
|
|
466
|
+
dom.appendChild(content);
|
|
467
|
+
this.dom.appendChild(dom);
|
|
468
|
+
this.view.requestMeasure(this.placeInfo);
|
|
469
|
+
}
|
|
468
470
|
updateSelectedOption(selected) {
|
|
469
471
|
let set = null;
|
|
470
472
|
for (let opt = this.list.firstChild, i = this.range.from; opt; opt = opt.nextSibling, i++) {
|
|
@@ -514,6 +516,7 @@ class CompletionTooltip {
|
|
|
514
516
|
const ul = document.createElement("ul");
|
|
515
517
|
ul.id = id;
|
|
516
518
|
ul.setAttribute("role", "listbox");
|
|
519
|
+
ul.setAttribute("aria-expanded", "true");
|
|
517
520
|
for (let i = range.from; i < range.to; i++) {
|
|
518
521
|
let { completion, match } = options[i];
|
|
519
522
|
const li = ul.appendChild(document.createElement("li"));
|
|
@@ -574,7 +577,6 @@ function sortOptions(active, state) {
|
|
|
574
577
|
}
|
|
575
578
|
}
|
|
576
579
|
}
|
|
577
|
-
options.sort(cmpOption);
|
|
578
580
|
let result = [], prev = null;
|
|
579
581
|
for (let opt of options.sort(cmpOption)) {
|
|
580
582
|
if (result.length == MaxOptions)
|
|
@@ -607,10 +609,11 @@ class CompletionDialog {
|
|
|
607
609
|
let selected = 0;
|
|
608
610
|
if (prev && prev.selected) {
|
|
609
611
|
let selectedValue = prev.options[prev.selected].completion;
|
|
610
|
-
for (let i = 0; i < options.length
|
|
611
|
-
if (options[i].completion == selectedValue)
|
|
612
|
+
for (let i = 0; i < options.length; i++)
|
|
613
|
+
if (options[i].completion == selectedValue) {
|
|
612
614
|
selected = i;
|
|
613
|
-
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
614
617
|
}
|
|
615
618
|
return new CompletionDialog(options, makeAttrs(id, selected), {
|
|
616
619
|
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
@@ -671,13 +674,12 @@ function sameResults(a, b) {
|
|
|
671
674
|
}
|
|
672
675
|
}
|
|
673
676
|
const baseAttrs = {
|
|
674
|
-
"aria-autocomplete": "list"
|
|
675
|
-
"aria-expanded": "false"
|
|
677
|
+
"aria-autocomplete": "list"
|
|
676
678
|
};
|
|
677
679
|
function makeAttrs(id, selected) {
|
|
678
680
|
return {
|
|
679
681
|
"aria-autocomplete": "list",
|
|
680
|
-
"aria-
|
|
682
|
+
"aria-haspopup": "listbox",
|
|
681
683
|
"aria-activedescendant": id + "-" + selected,
|
|
682
684
|
"aria-controls": id
|
|
683
685
|
};
|
|
@@ -741,7 +743,9 @@ class ActiveResult extends ActiveSource {
|
|
|
741
743
|
handleUserEvent(tr, type, conf) {
|
|
742
744
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
743
745
|
let pos = cur(tr.state);
|
|
744
|
-
if ((this.explicitPos
|
|
746
|
+
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
|
747
|
+
pos > to ||
|
|
748
|
+
type == "delete" && cur(tr.startState) == this.from)
|
|
745
749
|
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
746
750
|
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
747
751
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
@@ -857,7 +861,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
857
861
|
for (let i = 0; i < this.running.length; i++) {
|
|
858
862
|
let query = this.running[i];
|
|
859
863
|
if (doesReset ||
|
|
860
|
-
query.updates.length + update.transactions.length > MaxUpdateCount &&
|
|
864
|
+
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
861
865
|
for (let handler of query.context.abortListeners) {
|
|
862
866
|
try {
|
|
863
867
|
handler();
|
|
@@ -1093,7 +1097,9 @@ class FieldRange {
|
|
|
1093
1097
|
this.to = to;
|
|
1094
1098
|
}
|
|
1095
1099
|
map(changes) {
|
|
1096
|
-
|
|
1100
|
+
let from = changes.mapPos(this.from, -1, state.MapMode.TrackDel);
|
|
1101
|
+
let to = changes.mapPos(this.to, 1, state.MapMode.TrackDel);
|
|
1102
|
+
return from == null || to == null ? null : new FieldRange(this.field, from, to);
|
|
1097
1103
|
}
|
|
1098
1104
|
}
|
|
1099
1105
|
class Snippet {
|
|
@@ -1162,7 +1168,14 @@ class ActiveSnippet {
|
|
|
1162
1168
|
this.deco = view.Decoration.set(ranges.map(r => (r.from == r.to ? fieldMarker : fieldRange).range(r.from, r.to)));
|
|
1163
1169
|
}
|
|
1164
1170
|
map(changes) {
|
|
1165
|
-
|
|
1171
|
+
let ranges = [];
|
|
1172
|
+
for (let r of this.ranges) {
|
|
1173
|
+
let mapped = r.map(changes);
|
|
1174
|
+
if (!mapped)
|
|
1175
|
+
return null;
|
|
1176
|
+
ranges.push(mapped);
|
|
1177
|
+
}
|
|
1178
|
+
return new ActiveSnippet(ranges, this.active);
|
|
1166
1179
|
}
|
|
1167
1180
|
selectionInsideField(sel) {
|
|
1168
1181
|
return sel.ranges.every(range => this.ranges.some(r => r.field == this.active && r.from <= range.from && r.to >= range.to));
|
|
@@ -1424,13 +1437,19 @@ function completionStatus(state) {
|
|
|
1424
1437
|
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
|
|
1425
1438
|
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
|
|
1426
1439
|
}
|
|
1440
|
+
const completionArrayCache = new WeakMap;
|
|
1427
1441
|
/**
|
|
1428
1442
|
Returns the available completions as an array.
|
|
1429
1443
|
*/
|
|
1430
1444
|
function currentCompletions(state) {
|
|
1431
1445
|
var _a;
|
|
1432
1446
|
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1433
|
-
|
|
1447
|
+
if (!open)
|
|
1448
|
+
return [];
|
|
1449
|
+
let completions = completionArrayCache.get(open.options);
|
|
1450
|
+
if (!completions)
|
|
1451
|
+
completionArrayCache.set(open.options, completions = open.options.map(o => o.completion));
|
|
1452
|
+
return completions;
|
|
1434
1453
|
}
|
|
1435
1454
|
/**
|
|
1436
1455
|
Return the currently selected completion, if any.
|
|
@@ -1440,6 +1459,22 @@ function selectedCompletion(state) {
|
|
|
1440
1459
|
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1441
1460
|
return open ? open.options[open.selected].completion : null;
|
|
1442
1461
|
}
|
|
1462
|
+
/**
|
|
1463
|
+
Returns the currently selected position in the active completion
|
|
1464
|
+
list, or null if no completions are active.
|
|
1465
|
+
*/
|
|
1466
|
+
function selectedCompletionIndex(state) {
|
|
1467
|
+
var _a;
|
|
1468
|
+
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1469
|
+
return open ? open.selected : null;
|
|
1470
|
+
}
|
|
1471
|
+
/**
|
|
1472
|
+
Create an effect that can be attached to a transaction to change
|
|
1473
|
+
the currently selected completion.
|
|
1474
|
+
*/
|
|
1475
|
+
function setSelectedCompletion(index) {
|
|
1476
|
+
return setSelectedEffect.of(index);
|
|
1477
|
+
}
|
|
1443
1478
|
|
|
1444
1479
|
exports.CompletionContext = CompletionContext;
|
|
1445
1480
|
exports.acceptCompletion = acceptCompletion;
|
|
@@ -1458,6 +1493,8 @@ exports.nextSnippetField = nextSnippetField;
|
|
|
1458
1493
|
exports.pickedCompletion = pickedCompletion;
|
|
1459
1494
|
exports.prevSnippetField = prevSnippetField;
|
|
1460
1495
|
exports.selectedCompletion = selectedCompletion;
|
|
1496
|
+
exports.selectedCompletionIndex = selectedCompletionIndex;
|
|
1497
|
+
exports.setSelectedCompletion = setSelectedCompletion;
|
|
1461
1498
|
exports.snippet = snippet;
|
|
1462
1499
|
exports.snippetCompletion = snippetCompletion;
|
|
1463
1500
|
exports.snippetKeymap = snippetKeymap;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _codemirror_state from '@codemirror/state';
|
|
2
|
-
import { EditorState, Transaction, StateCommand, Facet, Extension } from '@codemirror/state';
|
|
2
|
+
import { EditorState, Transaction, StateCommand, Facet, Extension, StateEffect } from '@codemirror/state';
|
|
3
3
|
import { EditorView, KeyBinding, Command } from '@codemirror/view';
|
|
4
4
|
import * as _lezer_common from '@lezer/common';
|
|
5
5
|
|
|
@@ -81,7 +81,7 @@ interface Completion {
|
|
|
81
81
|
a plain string or a function that'll render the DOM structure to
|
|
82
82
|
show when invoked.
|
|
83
83
|
*/
|
|
84
|
-
info?: string | ((completion: Completion) => (Node | Promise<Node>));
|
|
84
|
+
info?: string | ((completion: Completion) => (Node | null | Promise<Node | null>));
|
|
85
85
|
/**
|
|
86
86
|
How to apply the completion. The default is to replace it with
|
|
87
87
|
its [label](https://codemirror.net/6/docs/ref/#autocomplete.Completion.label). When this holds a
|
|
@@ -362,5 +362,15 @@ declare function currentCompletions(state: EditorState): readonly Completion[];
|
|
|
362
362
|
Return the currently selected completion, if any.
|
|
363
363
|
*/
|
|
364
364
|
declare function selectedCompletion(state: EditorState): Completion | null;
|
|
365
|
+
/**
|
|
366
|
+
Returns the currently selected position in the active completion
|
|
367
|
+
list, or null if no completions are active.
|
|
368
|
+
*/
|
|
369
|
+
declare function selectedCompletionIndex(state: EditorState): number | null;
|
|
370
|
+
/**
|
|
371
|
+
Create an effect that can be attached to a transaction to change
|
|
372
|
+
the currently selected completion.
|
|
373
|
+
*/
|
|
374
|
+
declare function setSelectedCompletion(index: number): StateEffect<unknown>;
|
|
365
375
|
|
|
366
|
-
export { Completion, CompletionContext, CompletionResult, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
376
|
+
export { Completion, CompletionContext, CompletionResult, CompletionSource, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Annotation, Facet, combineConfig, StateEffect, StateField, Prec, EditorSelection, Text } from '@codemirror/state';
|
|
2
|
-
import {
|
|
1
|
+
import { Annotation, Facet, combineConfig, StateEffect, StateField, Prec, EditorSelection, Text, MapMode } from '@codemirror/state';
|
|
2
|
+
import { logException, Direction, EditorView, ViewPlugin, Decoration, WidgetType, keymap } from '@codemirror/view';
|
|
3
3
|
import { showTooltip, getTooltip } from '@codemirror/tooltip';
|
|
4
4
|
import { syntaxTree, indentUnit } from '@codemirror/language';
|
|
5
5
|
import { codePointAt, codePointSize, fromCodePoint } from '@codemirror/text';
|
|
@@ -370,22 +370,6 @@ function optionContent(config) {
|
|
|
370
370
|
});
|
|
371
371
|
return content.sort((a, b) => a.position - b.position).map(a => a.render);
|
|
372
372
|
}
|
|
373
|
-
function createInfoDialog(option, view) {
|
|
374
|
-
let dom = document.createElement("div");
|
|
375
|
-
dom.className = "cm-tooltip cm-completionInfo";
|
|
376
|
-
let { info } = option.completion;
|
|
377
|
-
if (typeof info == "string") {
|
|
378
|
-
dom.textContent = info;
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
381
|
-
let content = info(option.completion);
|
|
382
|
-
if (content.then)
|
|
383
|
-
content.then(node => dom.appendChild(node), e => logException(view.state, e, "completion info"));
|
|
384
|
-
else
|
|
385
|
-
dom.appendChild(content);
|
|
386
|
-
}
|
|
387
|
-
return dom;
|
|
388
|
-
}
|
|
389
373
|
function rangeAroundSelected(total, selected, max) {
|
|
390
374
|
if (total <= max)
|
|
391
375
|
return { from: 0, to: total };
|
|
@@ -454,13 +438,31 @@ class CompletionTooltip {
|
|
|
454
438
|
this.info.remove();
|
|
455
439
|
this.info = null;
|
|
456
440
|
}
|
|
457
|
-
let
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
441
|
+
let { completion } = open.options[open.selected];
|
|
442
|
+
let { info } = completion;
|
|
443
|
+
if (!info)
|
|
444
|
+
return;
|
|
445
|
+
let infoResult = typeof info === 'string' ? document.createTextNode(info) : info(completion);
|
|
446
|
+
if (!infoResult)
|
|
447
|
+
return;
|
|
448
|
+
if ('then' in infoResult) {
|
|
449
|
+
infoResult.then(node => {
|
|
450
|
+
if (node && this.view.state.field(this.stateField, false) == cState)
|
|
451
|
+
this.addInfoPane(node);
|
|
452
|
+
}).catch(e => logException(this.view.state, e, "completion info"));
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
this.addInfoPane(infoResult);
|
|
461
456
|
}
|
|
462
457
|
}
|
|
463
458
|
}
|
|
459
|
+
addInfoPane(content) {
|
|
460
|
+
let dom = this.info = document.createElement("div");
|
|
461
|
+
dom.className = "cm-tooltip cm-completionInfo";
|
|
462
|
+
dom.appendChild(content);
|
|
463
|
+
this.dom.appendChild(dom);
|
|
464
|
+
this.view.requestMeasure(this.placeInfo);
|
|
465
|
+
}
|
|
464
466
|
updateSelectedOption(selected) {
|
|
465
467
|
let set = null;
|
|
466
468
|
for (let opt = this.list.firstChild, i = this.range.from; opt; opt = opt.nextSibling, i++) {
|
|
@@ -510,6 +512,7 @@ class CompletionTooltip {
|
|
|
510
512
|
const ul = document.createElement("ul");
|
|
511
513
|
ul.id = id;
|
|
512
514
|
ul.setAttribute("role", "listbox");
|
|
515
|
+
ul.setAttribute("aria-expanded", "true");
|
|
513
516
|
for (let i = range.from; i < range.to; i++) {
|
|
514
517
|
let { completion, match } = options[i];
|
|
515
518
|
const li = ul.appendChild(document.createElement("li"));
|
|
@@ -570,7 +573,6 @@ function sortOptions(active, state) {
|
|
|
570
573
|
}
|
|
571
574
|
}
|
|
572
575
|
}
|
|
573
|
-
options.sort(cmpOption);
|
|
574
576
|
let result = [], prev = null;
|
|
575
577
|
for (let opt of options.sort(cmpOption)) {
|
|
576
578
|
if (result.length == MaxOptions)
|
|
@@ -603,10 +605,11 @@ class CompletionDialog {
|
|
|
603
605
|
let selected = 0;
|
|
604
606
|
if (prev && prev.selected) {
|
|
605
607
|
let selectedValue = prev.options[prev.selected].completion;
|
|
606
|
-
for (let i = 0; i < options.length
|
|
607
|
-
if (options[i].completion == selectedValue)
|
|
608
|
+
for (let i = 0; i < options.length; i++)
|
|
609
|
+
if (options[i].completion == selectedValue) {
|
|
608
610
|
selected = i;
|
|
609
|
-
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
610
613
|
}
|
|
611
614
|
return new CompletionDialog(options, makeAttrs(id, selected), {
|
|
612
615
|
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
@@ -667,13 +670,12 @@ function sameResults(a, b) {
|
|
|
667
670
|
}
|
|
668
671
|
}
|
|
669
672
|
const baseAttrs = {
|
|
670
|
-
"aria-autocomplete": "list"
|
|
671
|
-
"aria-expanded": "false"
|
|
673
|
+
"aria-autocomplete": "list"
|
|
672
674
|
};
|
|
673
675
|
function makeAttrs(id, selected) {
|
|
674
676
|
return {
|
|
675
677
|
"aria-autocomplete": "list",
|
|
676
|
-
"aria-
|
|
678
|
+
"aria-haspopup": "listbox",
|
|
677
679
|
"aria-activedescendant": id + "-" + selected,
|
|
678
680
|
"aria-controls": id
|
|
679
681
|
};
|
|
@@ -737,7 +739,9 @@ class ActiveResult extends ActiveSource {
|
|
|
737
739
|
handleUserEvent(tr, type, conf) {
|
|
738
740
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
739
741
|
let pos = cur(tr.state);
|
|
740
|
-
if ((this.explicitPos
|
|
742
|
+
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
|
743
|
+
pos > to ||
|
|
744
|
+
type == "delete" && cur(tr.startState) == this.from)
|
|
741
745
|
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
742
746
|
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
743
747
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
@@ -853,7 +857,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
853
857
|
for (let i = 0; i < this.running.length; i++) {
|
|
854
858
|
let query = this.running[i];
|
|
855
859
|
if (doesReset ||
|
|
856
|
-
query.updates.length + update.transactions.length > MaxUpdateCount &&
|
|
860
|
+
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
857
861
|
for (let handler of query.context.abortListeners) {
|
|
858
862
|
try {
|
|
859
863
|
handler();
|
|
@@ -1089,7 +1093,9 @@ class FieldRange {
|
|
|
1089
1093
|
this.to = to;
|
|
1090
1094
|
}
|
|
1091
1095
|
map(changes) {
|
|
1092
|
-
|
|
1096
|
+
let from = changes.mapPos(this.from, -1, MapMode.TrackDel);
|
|
1097
|
+
let to = changes.mapPos(this.to, 1, MapMode.TrackDel);
|
|
1098
|
+
return from == null || to == null ? null : new FieldRange(this.field, from, to);
|
|
1093
1099
|
}
|
|
1094
1100
|
}
|
|
1095
1101
|
class Snippet {
|
|
@@ -1158,7 +1164,14 @@ class ActiveSnippet {
|
|
|
1158
1164
|
this.deco = Decoration.set(ranges.map(r => (r.from == r.to ? fieldMarker : fieldRange).range(r.from, r.to)));
|
|
1159
1165
|
}
|
|
1160
1166
|
map(changes) {
|
|
1161
|
-
|
|
1167
|
+
let ranges = [];
|
|
1168
|
+
for (let r of this.ranges) {
|
|
1169
|
+
let mapped = r.map(changes);
|
|
1170
|
+
if (!mapped)
|
|
1171
|
+
return null;
|
|
1172
|
+
ranges.push(mapped);
|
|
1173
|
+
}
|
|
1174
|
+
return new ActiveSnippet(ranges, this.active);
|
|
1162
1175
|
}
|
|
1163
1176
|
selectionInsideField(sel) {
|
|
1164
1177
|
return sel.ranges.every(range => this.ranges.some(r => r.field == this.active && r.from <= range.from && r.to >= range.to));
|
|
@@ -1420,13 +1433,19 @@ function completionStatus(state) {
|
|
|
1420
1433
|
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
|
|
1421
1434
|
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
|
|
1422
1435
|
}
|
|
1436
|
+
const completionArrayCache = /*@__PURE__*/new WeakMap;
|
|
1423
1437
|
/**
|
|
1424
1438
|
Returns the available completions as an array.
|
|
1425
1439
|
*/
|
|
1426
1440
|
function currentCompletions(state) {
|
|
1427
1441
|
var _a;
|
|
1428
1442
|
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1429
|
-
|
|
1443
|
+
if (!open)
|
|
1444
|
+
return [];
|
|
1445
|
+
let completions = completionArrayCache.get(open.options);
|
|
1446
|
+
if (!completions)
|
|
1447
|
+
completionArrayCache.set(open.options, completions = open.options.map(o => o.completion));
|
|
1448
|
+
return completions;
|
|
1430
1449
|
}
|
|
1431
1450
|
/**
|
|
1432
1451
|
Return the currently selected completion, if any.
|
|
@@ -1436,5 +1455,21 @@ function selectedCompletion(state) {
|
|
|
1436
1455
|
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1437
1456
|
return open ? open.options[open.selected].completion : null;
|
|
1438
1457
|
}
|
|
1458
|
+
/**
|
|
1459
|
+
Returns the currently selected position in the active completion
|
|
1460
|
+
list, or null if no completions are active.
|
|
1461
|
+
*/
|
|
1462
|
+
function selectedCompletionIndex(state) {
|
|
1463
|
+
var _a;
|
|
1464
|
+
let open = (_a = state.field(completionState, false)) === null || _a === void 0 ? void 0 : _a.open;
|
|
1465
|
+
return open ? open.selected : null;
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
Create an effect that can be attached to a transaction to change
|
|
1469
|
+
the currently selected completion.
|
|
1470
|
+
*/
|
|
1471
|
+
function setSelectedCompletion(index) {
|
|
1472
|
+
return setSelectedEffect.of(index);
|
|
1473
|
+
}
|
|
1439
1474
|
|
|
1440
|
-
export { CompletionContext, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|
|
1475
|
+
export { CompletionContext, acceptCompletion, autocompletion, clearSnippet, closeCompletion, completeAnyWord, completeFromList, completionKeymap, completionStatus, currentCompletions, ifIn, ifNotIn, moveCompletionSelection, nextSnippetField, pickedCompletion, prevSnippetField, selectedCompletion, selectedCompletionIndex, setSelectedCompletion, snippet, snippetCompletion, snippetKeymap, startCompletion };
|