Skip to content
This repository was archived by the owner on Sep 19, 2025. It is now read-only.

Commit 6a4b4b1

Browse files
committed
Add biome
1 parent 0ad027c commit 6a4b4b1

38 files changed

+848
-734
lines changed

biome.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3+
"vcs": {
4+
"enabled": false,
5+
"clientKind": "git",
6+
"useIgnoreFile": false
7+
},
8+
"files": {
9+
"ignoreUnknown": false,
10+
"ignore": ["demo", "dist", "coverage", "scripts", "test"]
11+
},
12+
"formatter": {
13+
"enabled": true,
14+
"indentStyle": "tab"
15+
},
16+
"organizeImports": {
17+
"enabled": true
18+
},
19+
"linter": {
20+
"enabled": true,
21+
"rules": {
22+
"recommended": true,
23+
"style": {
24+
"noNonNullAssertion": "off"
25+
}
26+
}
27+
},
28+
"javascript": {
29+
"formatter": {
30+
"quoteStyle": "double"
31+
}
32+
}
33+
}

package-lock.json

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"prepare": "tsc",
99
"dev": "vite",
1010
"typecheck": "tsc --noEmit",
11+
"lint": "biome check",
1112
"test": "vitest run",
1213
"test:watch": "vitest",
1314
"build": "vite build"
@@ -29,6 +30,7 @@
2930
"@vitest/coverage-v8": "^2.1.8",
3031
"codemirror": "^6",
3132
"comlink": "^4.4.2",
33+
"happy-dom": "^15.11.7",
3234
"tshy": "^3.0.2",
3335
"typescript": "^5.7.2",
3436
"vite": "^6.0.3",
@@ -66,4 +68,3 @@
6668
"module": "./dist/esm/index.js",
6769
"nx": {}
6870
}
69-
Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
import {
2-
Completion,
3-
insertCompletionText,
4-
pickedCompletion,
2+
type Completion,
3+
insertCompletionText,
4+
pickedCompletion,
55
} from "@codemirror/autocomplete";
6-
import { RawCompletion, RawCompletionItem } from "../types.js";
7-
import { TransactionSpec } from "@codemirror/state";
6+
import type { TransactionSpec } from "@codemirror/state";
7+
import type { EditorView } from "codemirror";
8+
import type ts from "typescript";
89
import { renderDisplayParts } from "../hover/renderTooltip.js";
9-
import { EditorView } from "codemirror";
10-
import ts from "typescript";
10+
import type { RawCompletion, RawCompletionItem } from "../types.js";
1111

1212
export function deserializeCompletions(raw: RawCompletion | null) {
13-
if (!raw) return raw;
14-
return {
15-
from: raw.from,
16-
options: raw.options.map((o) => deserializeCompletion(o)),
17-
};
13+
if (!raw) return raw;
14+
return {
15+
from: raw.from,
16+
options: raw.options.map((o) => deserializeCompletion(o)),
17+
};
1818
}
1919

2020
function deserializeCompletion(raw: RawCompletionItem): Completion {
21-
const { codeActions, label, type } = raw;
21+
const { codeActions, label, type } = raw;
2222

23-
return {
24-
label,
25-
type,
26-
apply: codeActions ? codeActionToApplyFunction(codeActions) : raw.label,
27-
info: () => {
28-
const elem = document.createElement("div");
29-
elem.appendChild(renderDisplayParts(raw.displayParts));
30-
return elem;
31-
},
32-
};
23+
return {
24+
label,
25+
type,
26+
apply: codeActions ? codeActionToApplyFunction(codeActions) : raw.label,
27+
info: () => {
28+
const elem = document.createElement("div");
29+
elem.appendChild(renderDisplayParts(raw.displayParts));
30+
return elem;
31+
},
32+
};
3333
}
3434

3535
/**
@@ -40,48 +40,48 @@ function deserializeCompletion(raw: RawCompletionItem): Completion {
4040
* lets you import them automatically.
4141
*/
4242
export function codeActionToApplyFunction(codeActions: ts.CodeAction[]) {
43-
return (
44-
view: EditorView,
45-
completion: Completion,
46-
from: number,
47-
to: number,
48-
) => {
49-
const insTransaction: TransactionSpec = {
50-
...insertCompletionText(view.state, completion.label, from, to),
51-
annotations: pickedCompletion.of(completion),
52-
};
43+
return (
44+
view: EditorView,
45+
completion: Completion,
46+
from: number,
47+
to: number,
48+
) => {
49+
const insTransaction: TransactionSpec = {
50+
...insertCompletionText(view.state, completion.label, from, to),
51+
annotations: pickedCompletion.of(completion),
52+
};
5353

54-
const actionTransactions: TransactionSpec[] = [];
54+
const actionTransactions: TransactionSpec[] = [];
5555

56-
// Complete, but also implement code actions.
57-
// https://github.com/codemirror/autocomplete/blob/30307656e85c9e5911a69fe2432de05be1580958/src/state.ts#L322
58-
for (const action of codeActions) {
59-
for (const change of action.changes) {
60-
for (const textChange of change.textChanges) {
61-
// Note that this may be dangerous! We've had many problems
62-
// with trying to dispatch transactions on CodeMirror when the length
63-
// of the document is different than what it expects or needs. I think
64-
// that this will be safe in that case because we're combining
65-
// and only declaring the length once.
66-
//
67-
// NOTE: this has less than ideal history behavior! ideal this would
68-
// be composed with `insTransaction` and produce one history event.
69-
// But that is tough because the two need to perfectly agree on the document that
70-
// they're editing, and the length of the document changes.
71-
actionTransactions.push({
72-
changes: [
73-
{
74-
from: textChange.span.start,
75-
to: textChange.span.start + textChange.span.length,
76-
insert: textChange.newText,
77-
},
78-
],
79-
annotations: pickedCompletion.of(completion),
80-
});
81-
}
82-
}
83-
}
56+
// Complete, but also implement code actions.
57+
// https://github.com/codemirror/autocomplete/blob/30307656e85c9e5911a69fe2432de05be1580958/src/state.ts#L322
58+
for (const action of codeActions) {
59+
for (const change of action.changes) {
60+
for (const textChange of change.textChanges) {
61+
// Note that this may be dangerous! We've had many problems
62+
// with trying to dispatch transactions on CodeMirror when the length
63+
// of the document is different than what it expects or needs. I think
64+
// that this will be safe in that case because we're combining
65+
// and only declaring the length once.
66+
//
67+
// NOTE: this has less than ideal history behavior! ideal this would
68+
// be composed with `insTransaction` and produce one history event.
69+
// But that is tough because the two need to perfectly agree on the document that
70+
// they're editing, and the length of the document changes.
71+
actionTransactions.push({
72+
changes: [
73+
{
74+
from: textChange.span.start,
75+
to: textChange.span.start + textChange.span.length,
76+
insert: textChange.newText,
77+
},
78+
],
79+
annotations: pickedCompletion.of(completion),
80+
});
81+
}
82+
}
83+
}
8484

85-
view.dispatch(...[insTransaction, ...actionTransactions]);
86-
};
85+
view.dispatch(...[insTransaction, ...actionTransactions]);
86+
};
8787
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { test, expect } from "vitest";
1+
import { expect, test } from "vitest";
22
import { ensureAnchor } from "./ensureAnchor.js";
33

44
test("ensureAnchor", () => {
5-
expect(ensureAnchor(/hi/, false)).toEqual(/(?:hi)$/);
6-
expect(ensureAnchor(/hi$/, false)).toEqual(/hi$/);
7-
expect(ensureAnchor(/hi$/, true)).toEqual(/^(?:hi$)/);
8-
expect(ensureAnchor(/^hi$/, true)).toEqual(/^hi$/);
5+
expect(ensureAnchor(/hi/, false)).toEqual(/(?:hi)$/);
6+
expect(ensureAnchor(/hi$/, false)).toEqual(/hi$/);
7+
expect(ensureAnchor(/hi$/, true)).toEqual(/^(?:hi$)/);
8+
expect(ensureAnchor(/^hi$/, true)).toEqual(/^hi$/);
99
});

src/autocomplete/ensureAnchor.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// From: https://github.com/codemirror/autocomplete/blob/53cc58393252659ac4a86162b40afef13eeb2241/src/completion.ts#L245
22
// TODO: do we need this, or can use import it from codemirror?
33
export function ensureAnchor(expr: RegExp, start: boolean) {
4-
let { source } = expr;
5-
let addStart = start && source[0] != "^",
6-
addEnd = source[source.length - 1] != "$";
7-
if (!addStart && !addEnd) return expr;
8-
return new RegExp(
9-
`${addStart ? "^" : ""}(?:${source})${addEnd ? "$" : ""}`,
10-
expr.flags ?? (expr.ignoreCase ? "i" : ""),
11-
);
4+
const { source } = expr;
5+
// biome-ignore lint/style/useSingleVarDeclarator: vendor
6+
// biome-ignore lint/suspicious/noDoubleEquals: vendor
7+
const addStart = start && source[0] != "^",
8+
// biome-ignore lint/suspicious/noDoubleEquals: vendor
9+
addEnd = source[source.length - 1] != "$";
10+
if (!addStart && !addEnd) return expr;
11+
return new RegExp(
12+
`${addStart ? "^" : ""}(?:${source})${addEnd ? "$" : ""}`,
13+
expr.flags ?? (expr.ignoreCase ? "i" : ""),
14+
);
1215
}

0 commit comments

Comments
 (0)