@codemirror/autocomplete 6.18.0 → 6.18.2

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.18.2 (2024-10-30)
2
+
3
+ ### Bug fixes
4
+
5
+ Don't immediately show synchronously updated completions when there are some sources that still need to return.
6
+
7
+ ## 6.18.1 (2024-09-14)
8
+
9
+ ### Bug fixes
10
+
11
+ Fix an issue where `insertCompletionText` would get confused about the length of the inserted text when it contained CRLF line breaks, and create an invalid selection.
12
+
13
+ Add Alt-Backtick as additional binding on macOS, where IME can take over Ctrl-Space.
14
+
1
15
  ## 6.18.0 (2024-08-05)
2
16
 
3
17
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -193,9 +193,10 @@ function insertCompletionText(state$1, text, from, to) {
193
193
  if (range != main && from != to &&
194
194
  state$1.sliceDoc(range.from + fromOff, range.from + toOff) != state$1.sliceDoc(from, to))
195
195
  return { range };
196
+ let lines = state$1.toText(text);
196
197
  return {
197
- changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
198
- range: state.EditorSelection.cursor(range.from + fromOff + text.length)
198
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: lines },
199
+ range: state.EditorSelection.cursor(range.from + fromOff + lines.length)
199
200
  };
200
201
  })), { scrollIntoView: true, userEvent: "input.complete" });
201
202
  }
@@ -815,12 +816,12 @@ class CompletionDialog {
815
816
  return selected == this.selected || selected >= this.options.length ? this
816
817
  : new CompletionDialog(this.options, makeAttrs(id, selected), this.tooltip, this.timestamp, selected, this.disabled);
817
818
  }
818
- static build(active, state, id, prev, conf) {
819
+ static build(active, state, id, prev, conf, didSetActive) {
820
+ if (prev && !didSetActive && active.some(s => s.state == 1 /* State.Pending */))
821
+ return prev.setDisabled();
819
822
  let options = sortOptions(active, state);
820
- if (!options.length) {
821
- return prev && active.some(a => a.state == 1 /* State.Pending */) ?
822
- new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
823
- }
823
+ if (!options.length)
824
+ return prev && active.some(a => a.state == 1 /* State.Pending */) ? prev.setDisabled() : null;
824
825
  let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
825
826
  if (prev && prev.selected != selected && prev.selected != -1) {
826
827
  let selectedValue = prev.options[prev.selected].completion;
@@ -839,6 +840,9 @@ class CompletionDialog {
839
840
  map(changes) {
840
841
  return new CompletionDialog(this.options, this.attrs, Object.assign(Object.assign({}, this.tooltip), { pos: changes.mapPos(this.tooltip.pos) }), this.timestamp, this.selected, this.disabled);
841
842
  }
843
+ setDisabled() {
844
+ return new CompletionDialog(this.options, this.attrs, this.tooltip, this.timestamp, this.selected, true);
845
+ }
842
846
  }
843
847
  class CompletionState {
844
848
  constructor(active, id, open) {
@@ -860,12 +864,12 @@ class CompletionState {
860
864
  });
861
865
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
862
866
  active = this.active;
863
- let open = this.open;
867
+ let open = this.open, didSet = tr.effects.some(e => e.is(setActiveEffect));
864
868
  if (open && tr.docChanged)
865
869
  open = open.map(tr.changes);
866
870
  if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
867
- !sameResults(active, this.active))
868
- open = CompletionDialog.build(active, state, this.id, open, conf);
871
+ !sameResults(active, this.active) || didSet)
872
+ open = CompletionDialog.build(active, state, this.id, open, conf, didSet);
869
873
  else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
870
874
  open = null;
871
875
  if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
@@ -1157,6 +1161,8 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1157
1161
  if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
1158
1162
  this.startQuery(active);
1159
1163
  }
1164
+ if (this.running.length && cState.open && cState.open.disabled)
1165
+ this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
1160
1166
  }
1161
1167
  startQuery(active) {
1162
1168
  let { state } = this.view, pos = cur(state);
@@ -1187,7 +1193,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1187
1193
  clearTimeout(this.debounceAccept);
1188
1194
  this.debounceAccept = -1;
1189
1195
  let updated = [];
1190
- let conf = this.view.state.facet(completionConfig);
1196
+ let conf = this.view.state.facet(completionConfig), cState = this.view.state.field(completionState);
1191
1197
  for (let i = 0; i < this.running.length; i++) {
1192
1198
  let query = this.running[i];
1193
1199
  if (query.done === undefined)
@@ -1204,7 +1210,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1204
1210
  continue;
1205
1211
  }
1206
1212
  }
1207
- let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
1213
+ let current = cState.active.find(a => a.source == query.active.source);
1208
1214
  if (current && current.state == 1 /* State.Pending */) {
1209
1215
  if (query.done == null) {
1210
1216
  // Explicitly failed. Should clear the pending status if it
@@ -1221,7 +1227,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
1221
1227
  }
1222
1228
  }
1223
1229
  }
1224
- if (updated.length)
1230
+ if (updated.length || cState.open && cState.open.disabled)
1225
1231
  this.view.dispatch({ effects: setActiveEffect.of(updated) });
1226
1232
  }
1227
1233
  }, {
@@ -1996,7 +2002,7 @@ function autocompletion(config = {}) {
1996
2002
  /**
1997
2003
  Basic keybindings for autocompletion.
1998
2004
 
1999
- - Ctrl-Space: [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
2005
+ - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
2000
2006
  - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion)
2001
2007
  - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)`
2002
2008
  - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)`
@@ -2006,6 +2012,7 @@ Basic keybindings for autocompletion.
2006
2012
  */
2007
2013
  const completionKeymap = [
2008
2014
  { key: "Ctrl-Space", run: startCompletion },
2015
+ { mac: "Alt-`", run: startCompletion },
2009
2016
  { key: "Escape", run: closeCompletion },
2010
2017
  { key: "ArrowDown", run: moveCompletionSelection(true) },
2011
2018
  { key: "ArrowUp", run: moveCompletionSelection(false) },
package/dist/index.d.cts CHANGED
@@ -601,7 +601,7 @@ declare function autocompletion(config?: CompletionConfig): Extension;
601
601
  /**
602
602
  Basic keybindings for autocompletion.
603
603
 
604
- - Ctrl-Space: [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
604
+ - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
605
605
  - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion)
606
606
  - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)`
607
607
  - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)`
package/dist/index.d.ts CHANGED
@@ -601,7 +601,7 @@ declare function autocompletion(config?: CompletionConfig): Extension;
601
601
  /**
602
602
  Basic keybindings for autocompletion.
603
603
 
604
- - Ctrl-Space: [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
604
+ - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
605
605
  - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion)
606
606
  - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)`
607
607
  - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)`
package/dist/index.js CHANGED
@@ -191,9 +191,10 @@ function insertCompletionText(state, text, from, to) {
191
191
  if (range != main && from != to &&
192
192
  state.sliceDoc(range.from + fromOff, range.from + toOff) != state.sliceDoc(from, to))
193
193
  return { range };
194
+ let lines = state.toText(text);
194
195
  return {
195
- changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
196
- range: EditorSelection.cursor(range.from + fromOff + text.length)
196
+ changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: lines },
197
+ range: EditorSelection.cursor(range.from + fromOff + lines.length)
197
198
  };
198
199
  })), { scrollIntoView: true, userEvent: "input.complete" });
199
200
  }
@@ -813,12 +814,12 @@ class CompletionDialog {
813
814
  return selected == this.selected || selected >= this.options.length ? this
814
815
  : new CompletionDialog(this.options, makeAttrs(id, selected), this.tooltip, this.timestamp, selected, this.disabled);
815
816
  }
816
- static build(active, state, id, prev, conf) {
817
+ static build(active, state, id, prev, conf, didSetActive) {
818
+ if (prev && !didSetActive && active.some(s => s.state == 1 /* State.Pending */))
819
+ return prev.setDisabled();
817
820
  let options = sortOptions(active, state);
818
- if (!options.length) {
819
- return prev && active.some(a => a.state == 1 /* State.Pending */) ?
820
- new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
821
- }
821
+ if (!options.length)
822
+ return prev && active.some(a => a.state == 1 /* State.Pending */) ? prev.setDisabled() : null;
822
823
  let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
823
824
  if (prev && prev.selected != selected && prev.selected != -1) {
824
825
  let selectedValue = prev.options[prev.selected].completion;
@@ -837,6 +838,9 @@ class CompletionDialog {
837
838
  map(changes) {
838
839
  return new CompletionDialog(this.options, this.attrs, Object.assign(Object.assign({}, this.tooltip), { pos: changes.mapPos(this.tooltip.pos) }), this.timestamp, this.selected, this.disabled);
839
840
  }
841
+ setDisabled() {
842
+ return new CompletionDialog(this.options, this.attrs, this.tooltip, this.timestamp, this.selected, true);
843
+ }
840
844
  }
841
845
  class CompletionState {
842
846
  constructor(active, id, open) {
@@ -858,12 +862,12 @@ class CompletionState {
858
862
  });
859
863
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
860
864
  active = this.active;
861
- let open = this.open;
865
+ let open = this.open, didSet = tr.effects.some(e => e.is(setActiveEffect));
862
866
  if (open && tr.docChanged)
863
867
  open = open.map(tr.changes);
864
868
  if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
865
- !sameResults(active, this.active))
866
- open = CompletionDialog.build(active, state, this.id, open, conf);
869
+ !sameResults(active, this.active) || didSet)
870
+ open = CompletionDialog.build(active, state, this.id, open, conf, didSet);
867
871
  else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
868
872
  open = null;
869
873
  if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
@@ -1155,6 +1159,8 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1155
1159
  if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
1156
1160
  this.startQuery(active);
1157
1161
  }
1162
+ if (this.running.length && cState.open && cState.open.disabled)
1163
+ this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
1158
1164
  }
1159
1165
  startQuery(active) {
1160
1166
  let { state } = this.view, pos = cur(state);
@@ -1185,7 +1191,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1185
1191
  clearTimeout(this.debounceAccept);
1186
1192
  this.debounceAccept = -1;
1187
1193
  let updated = [];
1188
- let conf = this.view.state.facet(completionConfig);
1194
+ let conf = this.view.state.facet(completionConfig), cState = this.view.state.field(completionState);
1189
1195
  for (let i = 0; i < this.running.length; i++) {
1190
1196
  let query = this.running[i];
1191
1197
  if (query.done === undefined)
@@ -1202,7 +1208,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1202
1208
  continue;
1203
1209
  }
1204
1210
  }
1205
- let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
1211
+ let current = cState.active.find(a => a.source == query.active.source);
1206
1212
  if (current && current.state == 1 /* State.Pending */) {
1207
1213
  if (query.done == null) {
1208
1214
  // Explicitly failed. Should clear the pending status if it
@@ -1219,7 +1225,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
1219
1225
  }
1220
1226
  }
1221
1227
  }
1222
- if (updated.length)
1228
+ if (updated.length || cState.open && cState.open.disabled)
1223
1229
  this.view.dispatch({ effects: setActiveEffect.of(updated) });
1224
1230
  }
1225
1231
  }, {
@@ -1994,7 +2000,7 @@ function autocompletion(config = {}) {
1994
2000
  /**
1995
2001
  Basic keybindings for autocompletion.
1996
2002
 
1997
- - Ctrl-Space: [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
2003
+ - Ctrl-Space (and Alt-\` on macOS): [`startCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.startCompletion)
1998
2004
  - Escape: [`closeCompletion`](https://codemirror.net/6/docs/ref/#autocomplete.closeCompletion)
1999
2005
  - ArrowDown: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(true)`
2000
2006
  - ArrowUp: [`moveCompletionSelection`](https://codemirror.net/6/docs/ref/#autocomplete.moveCompletionSelection)`(false)`
@@ -2004,6 +2010,7 @@ Basic keybindings for autocompletion.
2004
2010
  */
2005
2011
  const completionKeymap = [
2006
2012
  { key: "Ctrl-Space", run: startCompletion },
2013
+ { mac: "Alt-`", run: startCompletion },
2007
2014
  { key: "Escape", run: closeCompletion },
2008
2015
  { key: "ArrowDown", run: /*@__PURE__*/moveCompletionSelection(true) },
2009
2016
  { key: "ArrowUp", run: /*@__PURE__*/moveCompletionSelection(false) },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.18.0",
3
+ "version": "6.18.2",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",