@codemirror/autocomplete 6.20.0 → 6.20.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,14 @@
1
+ ## 6.20.2 (2026-05-06)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where you couldn't move to the last page of completions when its count was a precise multiple of the page size.
6
+
7
+ ## 6.20.1 (2026-03-02)
8
+
9
+ ### Bug fixes
10
+
11
+ Clicking the horizontal dots at the top/bottom of a list of completion options now moves the selection there, so that more completions become visible.
1
12
  ## 6.20.0 (2025-11-20)
2
13
 
3
14
  ### New features
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @codemirror/autocomplete [![NPM version](https://img.shields.io/npm/v/@codemirror/autocomplete.svg)](https://www.npmjs.org/package/@codemirror/autocomplete)
2
2
 
3
- [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#autocomplete) | [**ISSUES**](https://github.com/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/c/next/) | [**CHANGELOG**](https://github.com/codemirror/autocomplete/blob/main/CHANGELOG.md) ]
3
+ [ [**WEBSITE**](https://codemirror.net/) | [**DOCS**](https://codemirror.net/docs/ref/#autocomplete) | [**ISSUES**](https://code.haverbeke.berlin/codemirror/dev/issues) | [**FORUM**](https://discuss.codemirror.net/) | [**CHANGELOG**](https://code.haverbeke.berlin/codemirror/autocomplete/src/branch/main/CHANGELOG.md) ]
4
4
 
5
5
  This package implements autocompletion for the
6
6
  [CodeMirror](https://codemirror.net/) code editor.
@@ -10,7 +10,7 @@ number of [examples](https://codemirror.net/examples/) and the
10
10
  [documentation](https://codemirror.net/docs/).
11
11
 
12
12
  This code is released under an
13
- [MIT license](https://github.com/codemirror/autocomplete/tree/main/LICENSE).
13
+ [MIT license](https://code.haverbeke.berlin/codemirror/autocomplete/tree/main/LICENSE).
14
14
 
15
15
  We aim to be an inclusive, welcoming community. To make that explicit,
16
16
  we have a [code of
package/dist/index.cjs CHANGED
@@ -441,6 +441,7 @@ function defaultPositionInfo(view$1, list, option, info, space, tooltip) {
441
441
  };
442
442
  }
443
443
 
444
+ const setSelectedEffect = state.StateEffect.define();
444
445
  function optionContent(config) {
445
446
  let content = config.addToOptions.slice();
446
447
  if (config.icons)
@@ -496,8 +497,8 @@ function rangeAroundSelected(total, selected, max) {
496
497
  let off = Math.floor(selected / max);
497
498
  return { from: off * max, to: (off + 1) * max };
498
499
  }
499
- let off = Math.floor((total - selected) / max);
500
- return { from: total - (off + 1) * max, to: total - off * max };
500
+ let off = Math.ceil((total - selected) / max);
501
+ return { from: total - off * max, to: total - (off - 1) * max };
501
502
  }
502
503
  class CompletionTooltip {
503
504
  constructor(view, stateField, applyCompletion) {
@@ -532,6 +533,16 @@ class CompletionTooltip {
532
533
  return;
533
534
  }
534
535
  }
536
+ if (e.target == this.list) {
537
+ let move = this.list.classList.contains("cm-completionListIncompleteTop") &&
538
+ e.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 :
539
+ this.list.classList.contains("cm-completionListIncompleteBottom") &&
540
+ e.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
541
+ if (move != null) {
542
+ view.dispatch({ effects: setSelectedEffect.of(move) });
543
+ e.preventDefault();
544
+ }
545
+ }
535
546
  });
536
547
  this.dom.addEventListener("focusout", (e) => {
537
548
  let state = view.state.field(this.stateField, false);
@@ -1033,7 +1044,6 @@ function checkValid(validFor, state, from, to) {
1033
1044
  const setActiveEffect = state.StateEffect.define({
1034
1045
  map(sources, mapping) { return sources.map(s => s.map(mapping)); }
1035
1046
  });
1036
- const setSelectedEffect = state.StateEffect.define();
1037
1047
  const completionState = state.StateField.define({
1038
1048
  create() { return CompletionState.start(); },
1039
1049
  update(value, tr) { return value.update(tr); },
@@ -1347,7 +1357,8 @@ const baseTheme = view.EditorView.baseTheme({
1347
1357
  content: '"···"',
1348
1358
  opacity: 0.5,
1349
1359
  display: "block",
1350
- textAlign: "center"
1360
+ textAlign: "center",
1361
+ cursor: "pointer",
1351
1362
  },
1352
1363
  ".cm-tooltip.cm-completionInfo": {
1353
1364
  position: "absolute",
@@ -1767,7 +1778,8 @@ A completion source that will scan the document for words (using a
1767
1778
  return those as completions.
1768
1779
  */
1769
1780
  const completeAnyWord = context => {
1770
- let wordChars = context.state.languageDataAt("wordChars", context.pos).join("");
1781
+ var _a;
1782
+ let wordChars = (_a = context.state.languageDataAt("wordChars", context.pos)[0]) !== null && _a !== void 0 ? _a : "";
1771
1783
  let re = wordRE(wordChars);
1772
1784
  let token = context.matchBefore(mapRE(re, s => s + "$"));
1773
1785
  if (!token && !context.explicit)
package/dist/index.js CHANGED
@@ -439,6 +439,7 @@ function defaultPositionInfo(view, list, option, info, space, tooltip) {
439
439
  };
440
440
  }
441
441
 
442
+ const setSelectedEffect = /*@__PURE__*/StateEffect.define();
442
443
  function optionContent(config) {
443
444
  let content = config.addToOptions.slice();
444
445
  if (config.icons)
@@ -494,8 +495,8 @@ function rangeAroundSelected(total, selected, max) {
494
495
  let off = Math.floor(selected / max);
495
496
  return { from: off * max, to: (off + 1) * max };
496
497
  }
497
- let off = Math.floor((total - selected) / max);
498
- return { from: total - (off + 1) * max, to: total - off * max };
498
+ let off = Math.ceil((total - selected) / max);
499
+ return { from: total - off * max, to: total - (off - 1) * max };
499
500
  }
500
501
  class CompletionTooltip {
501
502
  constructor(view, stateField, applyCompletion) {
@@ -530,6 +531,16 @@ class CompletionTooltip {
530
531
  return;
531
532
  }
532
533
  }
534
+ if (e.target == this.list) {
535
+ let move = this.list.classList.contains("cm-completionListIncompleteTop") &&
536
+ e.clientY < this.list.firstChild.getBoundingClientRect().top ? this.range.from - 1 :
537
+ this.list.classList.contains("cm-completionListIncompleteBottom") &&
538
+ e.clientY > this.list.lastChild.getBoundingClientRect().bottom ? this.range.to : null;
539
+ if (move != null) {
540
+ view.dispatch({ effects: setSelectedEffect.of(move) });
541
+ e.preventDefault();
542
+ }
543
+ }
533
544
  });
534
545
  this.dom.addEventListener("focusout", (e) => {
535
546
  let state = view.state.field(this.stateField, false);
@@ -1031,7 +1042,6 @@ function checkValid(validFor, state, from, to) {
1031
1042
  const setActiveEffect = /*@__PURE__*/StateEffect.define({
1032
1043
  map(sources, mapping) { return sources.map(s => s.map(mapping)); }
1033
1044
  });
1034
- const setSelectedEffect = /*@__PURE__*/StateEffect.define();
1035
1045
  const completionState = /*@__PURE__*/StateField.define({
1036
1046
  create() { return CompletionState.start(); },
1037
1047
  update(value, tr) { return value.update(tr); },
@@ -1345,7 +1355,8 @@ const baseTheme = /*@__PURE__*/EditorView.baseTheme({
1345
1355
  content: '"···"',
1346
1356
  opacity: 0.5,
1347
1357
  display: "block",
1348
- textAlign: "center"
1358
+ textAlign: "center",
1359
+ cursor: "pointer",
1349
1360
  },
1350
1361
  ".cm-tooltip.cm-completionInfo": {
1351
1362
  position: "absolute",
@@ -1765,7 +1776,8 @@ A completion source that will scan the document for words (using a
1765
1776
  return those as completions.
1766
1777
  */
1767
1778
  const completeAnyWord = context => {
1768
- let wordChars = context.state.languageDataAt("wordChars", context.pos).join("");
1779
+ var _a;
1780
+ let wordChars = (_a = context.state.languageDataAt("wordChars", context.pos)[0]) !== null && _a !== void 0 ? _a : "";
1769
1781
  let re = wordRE(wordChars);
1770
1782
  let token = context.matchBefore(mapRE(re, s => s + "$"));
1771
1783
  if (!token && !context.explicit)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.20.0",
3
+ "version": "6.20.2",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",
@@ -36,6 +36,6 @@
36
36
  },
37
37
  "repository": {
38
38
  "type": "git",
39
- "url": "https://github.com/codemirror/autocomplete.git"
39
+ "url": "git+https://code.haverbeke.berlin/codemirror/autocomplete.git"
40
40
  }
41
41
  }
@@ -1,16 +0,0 @@
1
- name: Trigger CI
2
- on: push
3
-
4
- jobs:
5
- build:
6
- name: Dispatch to main repo
7
- runs-on: ubuntu-latest
8
- steps:
9
- - name: Emit repository_dispatch
10
- uses: mvasigh/dispatch-action@main
11
- with:
12
- # You should create a personal access token and store it in your repository
13
- token: ${{ secrets.DISPATCH_AUTH }}
14
- repo: dev
15
- owner: codemirror
16
- event_type: push