From fd81f6975ac13a6eddc2ba5f8963c820f3a26774 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 21:08:29 +0200 Subject: [PATCH 1/9] Added eslint/func-names rule to oxlint --- oxlint.config.mts | 14 ++-- packages/app-vscode/src/ReleaseNotes.test.ts | 2 +- .../VscodeFancyRangeHighlighter.ts | 2 +- .../app-web-docs/src/docs/components/Code.tsx | 5 +- .../lib-common/src/testUtil/asyncSafety.ts | 2 +- .../CustomSpokenFormGeneratorImpl.test.ts | 2 +- .../validateQueryCaptures.test.ts | 2 +- .../processTargets/marks/LineNumberStage.ts | 9 ++- .../src/snippets/snippetParser.test.ts | 2 +- packages/lib-engine/src/test/scopes.test.ts | 2 +- .../src/test/spokenForms.talon.test.ts | 2 +- .../lib-sentence-parser/src/test/abbr.test.ts | 40 +++++------ .../src/test/empty.test.ts | 12 ++-- .../src/test/lists.test.ts | 14 ++-- .../src/test/multiple_sentences.test.ts | 70 +++++++++---------- .../src/test/newline.test.ts | 22 +++--- .../src/test/preserve_whitespace.test.ts | 18 ++--- .../src/test/single_sentence.test.ts | 42 +++++------ .../src/test/symbols.test.ts | 26 +++---- .../src/launchNeovimAndRunTests.ts | 2 +- 20 files changed, 148 insertions(+), 142 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index 8d658e5b3a..4a465535c7 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -4,11 +4,11 @@ import { defineConfig } from "oxlint"; // These rules should probably be re-enabled eventually const temporarilyDisabled = [ "eslint/no-param-reassign", - "eslint/no-shadow", "eslint/prefer-template", "import/no-default-export", "typescript/no-unsafe-type-assertion", "unicorn/no-array-reduce", + "react/rules-of-hooks", ]; const disabledRules = [ @@ -17,7 +17,6 @@ const disabledRules = [ "eslint/capitalized-comments", "eslint/class-methods-use-this", "eslint/complexity", - "eslint/func-names", "eslint/id-length", "eslint/init-declarations", "eslint/max-classes-per-file", @@ -30,10 +29,10 @@ const disabledRules = [ "eslint/no-continue", "eslint/no-eq-null", "eslint/no-lonely-if", - "eslint/no-loop-func", "eslint/no-magic-numbers", "eslint/no-negated-condition", "eslint/no-plusplus", + "eslint/no-shadow", "eslint/no-ternary", "eslint/no-undefined", "eslint/no-use-before-define", @@ -61,11 +60,9 @@ const disabledRules = [ "promise/prefer-await-to-callbacks", "react-perf/jsx-no-new-function-as-prop", "react/jsx-max-depth", - "react/no-danger", "react/no-multi-comp", "react/only-export-components", "react/react-in-jsx-scope", - "react/rules-of-hooks", "typescript/explicit-function-return-type", "typescript/parameter-properties", "typescript/prefer-readonly-parameter-types", @@ -242,6 +239,13 @@ export default defineConfig({ }, }, + { + files: ["*.test.ts", "endToEndTestSetup.ts"], + rules: { + "eslint/func-names": "off", + }, + }, + { files: ["packages/lib-common/src/types/command/**/*.ts"], rules: { diff --git a/packages/app-vscode/src/ReleaseNotes.test.ts b/packages/app-vscode/src/ReleaseNotes.test.ts index 8cff925ce0..367bbdfcb8 100644 --- a/packages/app-vscode/src/ReleaseNotes.test.ts +++ b/packages/app-vscode/src/ReleaseNotes.test.ts @@ -152,7 +152,7 @@ const testCases: TestCase[] = [ }, ]; -suite("release notes", function () { +suite("release notes", () => { teardown(() => { sinon.restore(); }); diff --git a/packages/app-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts b/packages/app-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts index 74250b2d9a..0985702544 100644 --- a/packages/app-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts +++ b/packages/app-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts @@ -44,7 +44,7 @@ export class VscodeFancyRangeHighlighter { // A single range will be split into multiple decorations if it spans // multiple lines, so that we can eg use dashed lines to end lines that // are part of the same range. - function* ({ range, differentiationIndex }) { + function* generateDecorations({ range, differentiationIndex }) { const iterable = range.type === "line" ? generateDecorationsForLineRange(range.start, range.end) diff --git a/packages/app-web-docs/src/docs/components/Code.tsx b/packages/app-web-docs/src/docs/components/Code.tsx index aede094897..dcd6f53f6a 100644 --- a/packages/app-web-docs/src/docs/components/Code.tsx +++ b/packages/app-web-docs/src/docs/components/Code.tsx @@ -84,7 +84,10 @@ export function Code({ -
{" "} +
); } diff --git a/packages/lib-common/src/testUtil/asyncSafety.ts b/packages/lib-common/src/testUtil/asyncSafety.ts index ff5f7963b9..ad708a13a7 100644 --- a/packages/lib-common/src/testUtil/asyncSafety.ts +++ b/packages/lib-common/src/testUtil/asyncSafety.ts @@ -15,7 +15,7 @@ import type { Context, Done } from "mocha"; * @returns A safely wrapped test function */ export function asyncSafety(fn: () => Promise) { - return function (this: Context, done: Done) { + return function runAsyncTestSafely(this: Context, done: Done) { const runnable = this.runnable(); void (async () => { diff --git a/packages/lib-engine/src/generateSpokenForm/CustomSpokenFormGeneratorImpl.test.ts b/packages/lib-engine/src/generateSpokenForm/CustomSpokenFormGeneratorImpl.test.ts index 4b8df6f57c..0658fc9fdb 100644 --- a/packages/lib-engine/src/generateSpokenForm/CustomSpokenFormGeneratorImpl.test.ts +++ b/packages/lib-engine/src/generateSpokenForm/CustomSpokenFormGeneratorImpl.test.ts @@ -2,7 +2,7 @@ import * as assert from "node:assert/strict"; import { FakeIDE, LATEST_VERSION, asyncSafety } from "@cursorless/lib-common"; import { CustomSpokenFormGeneratorImpl } from "./CustomSpokenFormGeneratorImpl"; -suite("CustomSpokenFormGeneratorImpl", function () { +suite("CustomSpokenFormGeneratorImpl", () => { test( "basic", asyncSafety(async () => { diff --git a/packages/lib-engine/src/languages/TreeSitterQuery/validateQueryCaptures.test.ts b/packages/lib-engine/src/languages/TreeSitterQuery/validateQueryCaptures.test.ts index 462eab1b12..9113912078 100644 --- a/packages/lib-engine/src/languages/TreeSitterQuery/validateQueryCaptures.test.ts +++ b/packages/lib-engine/src/languages/TreeSitterQuery/validateQueryCaptures.test.ts @@ -87,7 +87,7 @@ const testCases: { name: string; isOk: boolean; content: string }[] = [ }, ]; -suite("validateQueryCaptures", function () { +suite("validateQueryCaptures", () => { const ide = new FakeIDE(); for (const testCase of testCases) { diff --git a/packages/lib-engine/src/processTargets/marks/LineNumberStage.ts b/packages/lib-engine/src/processTargets/marks/LineNumberStage.ts index 00f3490d64..5d10585d64 100644 --- a/packages/lib-engine/src/processTargets/marks/LineNumberStage.ts +++ b/packages/lib-engine/src/processTargets/marks/LineNumberStage.ts @@ -52,15 +52,14 @@ const getLineNumber = ( let currentLineNumber = base + lineNumber; while (currentLineNumber <= endLine) { if (currentLineNumber >= startLine) { + const lineNumber = currentLineNumber; const visible = editor.visibleRanges.find( - (r) => - currentLineNumber >= r.start.line && - currentLineNumber <= r.end.line, + (r) => lineNumber >= r.start.line && lineNumber <= r.end.line, ); if (visible) { - visibleLines.push(currentLineNumber); + visibleLines.push(lineNumber); } else { - invisibleLines.push(currentLineNumber); + invisibleLines.push(lineNumber); } } currentLineNumber += stepSize; diff --git a/packages/lib-engine/src/snippets/snippetParser.test.ts b/packages/lib-engine/src/snippets/snippetParser.test.ts index 3d731d6680..36cbd4c14f 100644 --- a/packages/lib-engine/src/snippets/snippetParser.test.ts +++ b/packages/lib-engine/src/snippets/snippetParser.test.ts @@ -6,7 +6,7 @@ import * as assert from "node:assert/strict"; import { SnippetParser } from "./vendor/vscodeSnippet/snippetParser"; suite("SnippetParser", () => { - test("Marker, toTextmateString()", function () { + test("Marker, toTextmateString()", () => { function assertTextsnippetString(input: string, expected: string): void { const snippet = new SnippetParser().parse(input); const actual = snippet.toTextmateString(); diff --git a/packages/lib-engine/src/test/scopes.test.ts b/packages/lib-engine/src/test/scopes.test.ts index 39623ddb08..b7d21957a7 100644 --- a/packages/lib-engine/src/test/scopes.test.ts +++ b/packages/lib-engine/src/test/scopes.test.ts @@ -23,7 +23,7 @@ import { serializeScopeFixture, } from "../testUtil/serializeScopeFixture"; -suite("Scope test cases", function () { +suite("Scope test cases", () => { const testPaths = getScopeTestPathsRecursively(); let testEnvironment: TestEnvironment; diff --git a/packages/lib-engine/src/test/spokenForms.talon.test.ts b/packages/lib-engine/src/test/spokenForms.talon.test.ts index f09da3c87c..d933ccd31c 100644 --- a/packages/lib-engine/src/test/spokenForms.talon.test.ts +++ b/packages/lib-engine/src/test/spokenForms.talon.test.ts @@ -16,7 +16,7 @@ import { multiActionFixture } from "./fixtures/multiAction.fixture"; import { synonymousSpokenFormsFixture } from "./fixtures/synonymousSpokenForms.fixture"; import { talonApiFixture } from "./fixtures/talonApi.fixture"; -suite("Talon spoken forms", function () { +suite("Talon spoken forms", () => { const repl = new TalonRepl(); suiteSetup( diff --git a/packages/lib-sentence-parser/src/test/abbr.test.ts b/packages/lib-sentence-parser/src/test/abbr.test.ts index 5d43ee49bd..d16c75ea49 100644 --- a/packages/lib-sentence-parser/src/test/abbr.test.ts +++ b/packages/lib-sentence-parser/src/test/abbr.test.ts @@ -1,68 +1,68 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Abbreviations in sentences", function () { - suite("Skip dotted abbreviations", function () { +suite("sentence-parser: Abbreviations in sentences", () => { + suite("Skip dotted abbreviations", () => { const entry = "Lorem ipsum, dolor sed amat frequentor minimus In I.C.T we have multiple challenges! There should only be two sentences."; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Skip dotted abbreviations (B)", function () { + suite("Skip dotted abbreviations (B)", () => { const entry = "From amat frequentor minimus hello there at 8 a.m. there p.m. should only be two sentences."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Skip dotted abbreviations (C)", function () { + suite("Skip dotted abbreviations (C)", () => { const entry = "The school, called Booker T and Stevie Ray's Wrestling and Mixed Mart Arts Academy, will have an open house 2-6 p.m. Saturday."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Skip common abbreviations", function () { + suite("Skip common abbreviations", () => { const entry = "Fig. 2. displays currency rates i.e. something libsum. Currencies widely available (i.e. euro, dollar, pound), or alternatively (e.g. €, $, etc.)"; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Skip two worded abbreviations", function () { + suite("Skip two worded abbreviations", () => { const entry = "Claims 1–6 and 15–26 are rejected under pre-AIA 35 USC § 103(a) as being unpatentable over Chalana et al. (US 2012/0179503) in view of Oh (US 2013/0013993)."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Skip two worded abbreviations", function () { + suite("Skip two worded abbreviations", () => { const entry = "Et al. is an abbreviation of the Latin loanphrase et alii, meaning and others. It is similar to etc. (short for et cetera, meaning and the rest), but whereas etc. applies to things, et al. applies to people."; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Use other languages (accented)", function () { + suite("Use other languages (accented)", () => { const options: parser.SentenceParserOptions = { newlineBoundaries: true, preserveWhitespace: true, @@ -73,12 +73,12 @@ suite("sentence-parser: Abbreviations in sentences", function () { "Random words pré. other words and things. Different status updates all assigned"; const sentences = parser.getSentences(entry, options); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Use other languages", function () { + suite("Use other languages", () => { const entry = "Trzeba tu coś napisać, np. fragment odnoszący się do pkt. 3 wcześniejszego tekstu."; const sentencesEN = parser.getSentences(entry); @@ -86,18 +86,18 @@ suite("sentence-parser: Abbreviations in sentences", function () { abbreviations: ["np", "pkt"], }); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentencesEN.length, 3); assert.equal(sentencesPL.length, 1); }); - test("should not permanently override abbreviations", function () { + test("should not permanently override abbreviations", () => { const sentences = parser.getSentences(entry); assert.equal(sentences.length, 3); }); }); - suite("Use other languages (Cyrillic)", function () { + suite("Use other languages (Cyrillic)", () => { const options = { newlineBoundaries: true, preserveWhitespace: true, @@ -108,7 +108,7 @@ suite("sentence-parser: Abbreviations in sentences", function () { "матрицю SWOT- аналізу (табл. hello). Факторами макросередовища (рис. 5.8.). Things on a new line"; const sentencesCyrillic = parser.getSentences(entry, options); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentencesCyrillic.length, 3); }); }); diff --git a/packages/lib-sentence-parser/src/test/empty.test.ts b/packages/lib-sentence-parser/src/test/empty.test.ts index f354b9c6f7..b3623ca4ad 100644 --- a/packages/lib-sentence-parser/src/test/empty.test.ts +++ b/packages/lib-sentence-parser/src/test/empty.test.ts @@ -1,28 +1,28 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Empty", function () { - suite("string", function () { +suite("sentence-parser: Empty", () => { + suite("string", () => { let entry = ""; let sentences = parser.getSentences(entry); - test("should not get a sentence", function () { + test("should not get a sentence", () => { assert.equal(sentences.length, 0); }); entry = " \n\n "; sentences = parser.getSentences(entry); - test("should not get a sentence from whitespace", function () { + test("should not get a sentence from whitespace", () => { assert.equal(sentences.length, 0); }); }); - suite("symbols only", function () { + suite("symbols only", () => { const entry = "^&%(*&"; const sentences = parser.getSentences(entry); - test("should not single entry", function () { + test("should not single entry", () => { assert.equal(sentences.length, 1); }); }); diff --git a/packages/lib-sentence-parser/src/test/lists.test.ts b/packages/lib-sentence-parser/src/test/lists.test.ts index c34871ab48..1d5b3ed7c5 100644 --- a/packages/lib-sentence-parser/src/test/lists.test.ts +++ b/packages/lib-sentence-parser/src/test/lists.test.ts @@ -1,30 +1,30 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Lists", function () { - suite("It should skip list enumeration", function () { +suite("sentence-parser: Lists", () => { + suite("It should skip list enumeration", () => { const entry = "1. The item\n2. Another item"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("It should skip alternative list enumeration", function () { + suite("It should skip alternative list enumeration", () => { const entry = "a. The item\nab. Another item\n(1.) Third item"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentences.length, 3); }); }); - suite("It should keep empty list enumeration", function () { + suite("It should keep empty list enumeration", () => { const entry = "a. The item\nzz.\nab.\ncd. Hello"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 4 sentences", function () { + test("should get 4 sentences", () => { assert.equal(sentences.length, 4); }); }); diff --git a/packages/lib-sentence-parser/src/test/multiple_sentences.test.ts b/packages/lib-sentence-parser/src/test/multiple_sentences.test.ts index b456ee6616..bc85ce1825 100644 --- a/packages/lib-sentence-parser/src/test/multiple_sentences.test.ts +++ b/packages/lib-sentence-parser/src/test/multiple_sentences.test.ts @@ -1,172 +1,172 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Multiple sentences", function () { - suite("Include ellipsis as ending if starts with capital", function () { +suite("sentence-parser: Multiple sentences", () => { + suite("Include ellipsis as ending if starts with capital", () => { const entry = "First sentence... Another sentence"; const sentences = parser.getSentences(entry); - test("should get two sentences", function () { + test("should get two sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Two sentences", function () { + suite("Two sentences", () => { const entry = "Lorem ipsum, dolor sed amat frequentor minimus. Second sentence."; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (A)", function () { + suite("Difficult two sentences (A)", () => { const entry = "On Jan. 20, former Sen. Barack Obama became the 44th President of the U.S. Millions attended the Inauguration."; const sentences = parser.getSentences(entry); - test("should get two sentences", function () { + test("should get two sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (B)", function () { + suite("Difficult two sentences (B)", () => { const entry = "Sen. Barack Obama became the 44th President of the US. Millions attended."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (C)", function () { + suite("Difficult two sentences (C)", () => { const entry = "Barack Obama, previously Sen. of lorem ipsum, became the 44th President of the U.S. Millions attended."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (D)", function () { + suite("Difficult two sentences (D)", () => { const entry = "Baril, a Richmond lawyer once nominated for a federal prosecutors job, endorsed a faith-based drug initiative in local jails patterned after the Henrico County jails therapeutic program called Project R.I.S.E. Just as important, he had a great foil across the net."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (E)", function () { + suite("Difficult two sentences (E)", () => { const entry = "Newsletter AIDs CARE, EDUCATION AND TRAINING Issue No. 7. Acet Home Care, which moves into the building in July, will share the offices with two other AIDS charities, P.A.L.S. (Portsmouth AIDS Link Support) and the Link Project."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (F)", function () { + suite("Difficult two sentences (F)", () => { const entry = "Another is expanded hours of operation -- from fewer than five hours a day to 9:30 a.m. to 4 p.m. Monday through Saturday. Sunday remains closed."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); - suite("Difficult two sentences (G)", function () { + suite("Difficult two sentences (G)", () => { const entry = "Gold Wing Road Rider's Association - Coffee break, Guzzardo's Italian Villa, eat, 6 p.m.; ride, 7 p.m. Then at 9 p.m. go home."; const sentences = parser.getSentences(entry); - test("should get two sentence", function () { + test("should get two sentence", () => { assert.equal(sentences.length, 2); }); }); suite( "Dot in middle of word is not skipped if followed by capital letter", - function () { + () => { const entry = "Hello Barney.The bird in the word."; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }, ); - suite("Question- and exlamation mark", function () { + suite("Question- and exlamation mark", () => { const entry = "Hello this is my first sentence? There is also a second! A third"; const sentences = parser.getSentences(entry); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentences.length, 3); }); }); - suite("It should skip keywords/code with a dot in it", function () { + suite("It should skip keywords/code with a dot in it", () => { const entry = "HELLO A.TOP IS NICE"; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 1); }); }); - suite("If newlines are boundaries", function () { + suite("If newlines are boundaries", () => { const entry = "Search on http://google.com\n\nThen send me an email: gg@gggg.kk"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Sentences with quotations", function () { + suite("Sentences with quotations", () => { const entry = "“If there’s no balance and your boss doesn’t provide support and work that’s meaningful, your chances of burning out are great.” What bothers most people in situations like these is “the lack of boundaries,” says Nancy Rothbard, the David Pottruck Professor of Management at the University of Pennsylvania’s Wharton School."; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("Sentences with quotations", function () { + suite("Sentences with quotations", () => { const entry = "“If there’s no balance! And your boss doesn’t provide support and work that’s meaningful, your chances of burning out are great.” What bothers most people in situations like these is “the lack of boundaries,” says Nancy Rothbard, the David Pottruck Professor of Management at the University of Pennsylvania’s Wharton School."; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentences.length, 3); }); }); - suite("Sentences with a name ending a sentence", function () { + suite("Sentences with a name ending a sentence", () => { const entry = `If your boss assumes he can interrupt you any time and it’s "impacting the way you do your job," you should communicate that "you feel stretched," says Hill. A growing body of research shows that being “always on” hurts results.`; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("If newlines are boundaries (B)", function () { + suite("If newlines are boundaries (B)", () => { const entry = "FAMILIY HISTORY ========================================== Nothing interesting"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); diff --git a/packages/lib-sentence-parser/src/test/newline.test.ts b/packages/lib-sentence-parser/src/test/newline.test.ts index f53e45209c..6d034b4e7f 100644 --- a/packages/lib-sentence-parser/src/test/newline.test.ts +++ b/packages/lib-sentence-parser/src/test/newline.test.ts @@ -1,38 +1,38 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Save newlines", function () { - suite("Basic", function () { +suite("sentence-parser: Save newlines", () => { + suite("Basic", () => { const entry = "First sentence... Another list: \n - green \n - blue \n - red"; const sentences = parser.getSentences(entry); - test("second sentence should have newlines", function () { + test("second sentence should have newlines", () => { assert.equal(sentences[1], "Another list: \n - green \n - blue \n - red"); }); }); - suite("Sentence without lists", function () { + suite("Sentence without lists", () => { const entry = "First sentence... Another sentence.\nThis is a new paragraph."; const sentences = parser.getSentences(entry); - test("second sentence should have newlines", function () { + test("second sentence should have newlines", () => { assert.equal(sentences.length, 3); }); }); - suite("With option to use newlines as sentence boundaries", function () { + suite("With option to use newlines as sentence boundaries", () => { const entry = "First sentence... Another list: \n - green \n - blue \n - red"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("second sentence should have newlines", function () { + test("second sentence should have newlines", () => { assert.equal(sentences.length, 5); }); }); - suite("Multiline strings", function () { + suite("Multiline strings", () => { const entry = // oxlint-disable-next-line no-multi-str "How now brown cow.\ @@ -41,7 +41,7 @@ suite("sentence-parser: Save newlines", function () { const sentences = parser.getSentences(entry); - test("Should have 3 sentences ending in periods", function () { + test("Should have 3 sentences ending in periods", () => { assert.equal(sentences[0], "How now brown cow."); assert.equal( sentences[1], @@ -50,14 +50,14 @@ suite("sentence-parser: Save newlines", function () { }); }); - suite("Template multiline strings", function () { + suite("Template multiline strings", () => { const entry = `How now brown cow. Peter Piper Picked a peck of pickled peppers. A peck of pickled peppers peter piper picked.`; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("Should have 3 sentences ending in periods", function () { + test("Should have 3 sentences ending in periods", () => { assert.equal(sentences[0], "How now brown cow."); assert.equal( sentences[1], diff --git a/packages/lib-sentence-parser/src/test/preserve_whitespace.test.ts b/packages/lib-sentence-parser/src/test/preserve_whitespace.test.ts index df1a55da09..0b28bfe19b 100644 --- a/packages/lib-sentence-parser/src/test/preserve_whitespace.test.ts +++ b/packages/lib-sentence-parser/src/test/preserve_whitespace.test.ts @@ -3,17 +3,17 @@ import * as parser from ".."; const options = { preserveWhitespace: true }; -suite("sentence-parser: Preserve whitespace", function () { - suite("Basic", function () { +suite("sentence-parser: Preserve whitespace", () => { + suite("Basic", () => { const entry = " This is\ta sentence with funny whitespace. And this is \tanother.\tHere is a third. "; const sentences = parser.getSentences(entry, options); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentences.length, 3); }); - test("funny whitespace is preserved in the sentences", function () { + test("funny whitespace is preserved in the sentences", () => { assert.equal(sentences.join(""), entry); assert.equal( sentences[0], @@ -24,28 +24,28 @@ suite("sentence-parser: Preserve whitespace", function () { }); }); - suite("No effect if newline_boundaries are specified", function () { + suite("No effect if newline_boundaries are specified", () => { const entry = " This is\ta sentence with funny whitespace. "; const sentences = parser.getSentences(entry, { newlineBoundaries: true, ...options, }); - test("should get 1 sentences", function () { + test("should get 1 sentences", () => { assert.equal(sentences.length, 1); }); - test("funny whitespace is not preserved when newline_boundaries is specified", function () { + test("funny whitespace is not preserved when newline_boundaries is specified", () => { assert.equal(sentences[0], "This is a sentence with funny whitespace."); }); }); - suite("It should properly join single-word list sentences", function () { + suite("It should properly join single-word list sentences", () => { const entry = "iv. determining that the advertisement in the lift study is a candidate ad for the user, computing whether to include the user in a test group or a control group for the lift study ([0032]), v. based on the computation indicating that the user is in the control group, holding out the advertisement from completing the ad selection process for the user ([0032]), and vi. based on the computation indicating that the user is in the test group, allowing the advertisement to continue through the ad selection process such that the user receives either the advertisement in the lift study or another advertisement ([0032]); and "; const sentences = parser.getSentences(entry, options); - test("should get the correct sentences", function () { + test("should get the correct sentences", () => { assert.deepEqual(sentences, [ "iv. determining that the advertisement in the lift study is a candidate ad for the user, computing whether to include the user in a test group or a control group for the lift study ([0032]), v. based on the computation indicating that the user is in the control group, holding out the advertisement from completing the ad selection process for the user ([0032]), and vi. ", "based on the computation indicating that the user is in the test group, allowing the advertisement to continue through the ad selection process such that the user receives either the advertisement in the lift study or another advertisement ([0032]); and ", diff --git a/packages/lib-sentence-parser/src/test/single_sentence.test.ts b/packages/lib-sentence-parser/src/test/single_sentence.test.ts index f34392064e..85cd706b33 100644 --- a/packages/lib-sentence-parser/src/test/single_sentence.test.ts +++ b/packages/lib-sentence-parser/src/test/single_sentence.test.ts @@ -1,101 +1,101 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Single sentences", function () { - suite("Basic", function () { +suite("sentence-parser: Single sentences", () => { + suite("Basic", () => { const entry = "First sentence."; const sentences = parser.getSentences(entry); - test("should get one sentence", function () { + test("should get one sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Skip ellipsis", function () { + suite("Skip ellipsis", () => { const entry = "First sentence... another sentence"; const sentences = parser.getSentences(entry); - test("should get one sentence", function () { + test("should get one sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult single sentence (A)", function () { + suite("Difficult single sentence (A)", () => { const entry = "On Jan. 20, former Sen. Barack Obama became the 44th President of the U.S."; const sentences = parser.getSentences(entry); - test("should get one sentence", function () { + test("should get one sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult sentence (B)", function () { + suite("Difficult sentence (B)", () => { const entry = "It happened around 5:30 p.m. in the 500 block of W. 82nd St. Investigators say Terrence Taylor, 22, and Deontrell Sloan, 17, got into an argument over money during the game."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult sentence (C)", function () { + suite("Difficult sentence (C)", () => { const entry = "GARY Mayor Scott L. King has declared a 'cash crisis' and has asked city department heads to put off all non-essential spending until June."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult sentence (D)", function () { + suite("Difficult sentence (D)", () => { const entry = "HOWELL, Mich. - Blissfield was only nine outs away from ending the longest winning streak"; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult sentence (E)", function () { + suite("Difficult sentence (E)", () => { const entry = "33 FORT LAUDERDALE U.S. President George W Bush touted free trade as a means of strengthening democracy"; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("Difficult sentence (F)", function () { + suite("Difficult sentence (F)", () => { const entry = "Mike Tyler rides his bike on Del. 1 near Lewes early last month"; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); // Questionable behavior, but can only be fixed using ML? - suite("Dot in middle of word is skipped", function () { + suite("Dot in middle of word is skipped", () => { const entry = "Hello.this is my first sentence."; const sentences = parser.getSentences(entry); - test("should get 1 sentences", function () { + test("should get 1 sentences", () => { assert.equal(sentences.length, 1); }); }); - suite("Punctuation is skipped inside brackets", function () { + suite("Punctuation is skipped inside brackets", () => { const entry = "Lorem ipsum, dolor sed amat frequentor minimus with a sentence [example?] that should not (Though sometimes...) be two or more (but one!) sentences."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); diff --git a/packages/lib-sentence-parser/src/test/symbols.test.ts b/packages/lib-sentence-parser/src/test/symbols.test.ts index 8bff864ecc..5ded4d80a0 100644 --- a/packages/lib-sentence-parser/src/test/symbols.test.ts +++ b/packages/lib-sentence-parser/src/test/symbols.test.ts @@ -1,61 +1,61 @@ import * as assert from "node:assert/strict"; import * as parser from ".."; -suite("sentence-parser: Sentences with symbols", function () { - suite("It should skip numbers", function () { +suite("sentence-parser: Sentences with symbols", () => { + suite("It should skip numbers", () => { const entry = "10 times 10 = 10.00^2. 13.000 14.50 and 14,000,000.50"; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("It should skip urls and emails", function () { + suite("It should skip urls and emails", () => { const entry = "Search on http://google.com. Then send me an email: fabien@somedomain.com or fabien@anotherdomain.cc"; const sentences = parser.getSentences(entry); - test("should get 2 sentences", function () { + test("should get 2 sentences", () => { assert.equal(sentences.length, 2); }); }); - suite("It should skip phone numbers", function () { + suite("It should skip phone numbers", () => { const entry = "Call +44.3847838 for whatever."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 1); }); }); - suite("It should skip money with currency indication", function () { + suite("It should skip money with currency indication", () => { const entry = "I paid €12.50 for that CD. Twelve dollars and fifty cent ($12.50). Ten pounds - £10.00 it is fine."; const sentences = parser.getSentences(entry); - test("should get 1 sentence", function () { + test("should get 1 sentence", () => { assert.equal(sentences.length, 3); }); }); - suite("Newlines/paragraph must be enabled to end sentences", function () { + suite("Newlines/paragraph must be enabled to end sentences", () => { const entry = "The humble bundle sale\r\nDate: Monday-Fri starting 2015-01-01"; const sentences = parser.getSentences(entry); - test("should get 1 sentences", function () { + test("should get 1 sentences", () => { assert.equal(sentences.length, 1); }); }); - suite("Newlines/paragraph enabled ends sentences", function () { + suite("Newlines/paragraph enabled ends sentences", () => { const entry = "The humble bundle sale\r\nDate: Monday-Fri starting 2015-01-01\nSales starting at ¤2,50"; const sentences = parser.getSentences(entry, { newlineBoundaries: true }); - test("should get 3 sentences", function () { + test("should get 3 sentences", () => { assert.equal(sentences.length, 3); }); }); diff --git a/packages/test-runner/src/launchNeovimAndRunTests.ts b/packages/test-runner/src/launchNeovimAndRunTests.ts index e898047877..2bf759e958 100644 --- a/packages/test-runner/src/launchNeovimAndRunTests.ts +++ b/packages/test-runner/src/launchNeovimAndRunTests.ts @@ -122,7 +122,7 @@ export async function launchNeovimAndRunTests() { code = 3; exit(code); } - tailTest.on("line", function (data: string) { + tailTest.on("line", (data: string) => { console.log(`neovim test: ${data}`); if (data.includes("==== TESTS FINISHED:")) { done = true; From c539a4b2cbda51deb65e45d2952cbed85fbe7c13 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 21:31:47 +0200 Subject: [PATCH 2/9] Added "import/no-default-export" lint rule --- .meta-updater/main.mjs | 1 + oxlint.config.mts | 1 - packages/app-neovim/src/index.ts | 1 + .../src/ide/vscode/VscodeClipboard.ts | 2 +- .../src/ide/vscode/VscodeConfiguration.ts | 2 +- .../app-vscode/src/ide/vscode/VscodeEdit.ts | 2 +- .../vscode/VscodeEnabledHatStyleManager.ts | 2 +- .../src/ide/vscode/VscodeFlashHandler.ts | 4 +-- .../src/ide/vscode/VscodeFocusEditor.ts | 2 +- .../src/ide/vscode/VscodeHighlights.ts | 2 +- .../app-vscode/src/ide/vscode/VscodeIDE.ts | 12 +++---- .../src/ide/vscode/VscodeKeyValueStore.ts | 2 +- .../src/ide/vscode/VscodeMessages.ts | 2 +- .../src/ide/vscode/VscodeOpenLink.ts | 2 +- .../src/ide/vscode/VscodeTextDocument.ts | 2 +- .../src/ide/vscode/VscodeTextEditor.ts | 6 ++-- .../src/ide/vscode/VscodeTextLine.ts | 2 +- .../src/ide/vscode/hats/VscodeHatRenderer.ts | 10 +++--- .../src/ide/vscode/hats/VscodeHats.ts | 4 +-- .../src/ide/vscode/hats/getHatThemeColors.ts | 2 +- .../src/ide/vscode/textLine.vscode.test.ts | 2 +- .../src/keyboard/KeyboardCommandHandler.ts | 6 ++-- .../src/keyboard/KeyboardCommands.ts | 6 ++-- .../src/keyboard/KeyboardCommandsModal.ts | 6 ++-- .../keyboard/KeyboardCommandsModalLayer.ts | 2 +- .../src/keyboard/KeyboardCommandsTargeted.ts | 6 ++-- .../src/keyboard/KeyboardHandler.ts | 2 +- packages/app-web-docs/docusaurus.config.mts | 1 + packages/app-web-docs/sidebar.js | 1 + .../src/plugins/scope-tests-plugin.ts | 1 + packages/app-web-docs/src/theme/Root.tsx | 1 + packages/app-web/vite.config.ts | 1 + packages/lib-cheatsheet-local/jest.config.ts | 1 + .../src/test/styleMock.ts | 2 +- packages/lib-cheatsheet-local/vite.config.ts | 1 + packages/lib-cheatsheet/jest.config.ts | 1 + .../lib-cheatsheet/src/lib/Cheatsheet.tsx | 8 ++--- .../src/lib/CheatsheetLegendSection.tsx | 6 ++-- .../src/lib/CheatsheetListSection.tsx | 4 +-- .../src/lib/CheatsheetNotesSection.tsx | 4 +-- .../src/lib/utils/SmartLink.tsx | 2 +- .../src/lib/utils/formatCaptures.tsx | 2 +- .../src/lib/utils/useIsHighlighted.ts | 2 +- packages/lib-cheatsheet/src/test/styleMock.ts | 2 +- .../lib-common/src/ide/fake/FakeClipboard.ts | 2 +- .../src/ide/fake/FakeConfiguration.ts | 2 +- packages/lib-common/src/ide/fake/FakeIDE.ts | 8 ++--- .../src/ide/fake/FakeKeyValueStore.ts | 2 +- .../lib-common/src/ide/fake/FakeMessages.ts | 2 +- .../src/ide/normalized/NormalizedIDE.ts | 4 +-- packages/lib-common/src/ide/spy/SpyIDE.ts | 2 +- .../lib-common/src/ide/spy/SpyMessages.ts | 2 +- packages/lib-engine/src/actions/Actions.ts | 36 +++++++++---------- packages/lib-engine/src/actions/Call.ts | 2 +- packages/lib-engine/src/actions/Clear.ts | 2 +- packages/lib-engine/src/actions/Deselect.ts | 2 +- .../lib-engine/src/actions/ExecuteCommand.ts | 2 +- packages/lib-engine/src/actions/FollowLink.ts | 2 +- .../GenerateSnippet/GenerateSnippet.ts | 2 +- .../actions/GenerateSnippet/Substituter.ts | 2 +- .../src/actions/GenerateSnippet/index.ts | 2 +- packages/lib-engine/src/actions/GetTargets.ts | 2 +- packages/lib-engine/src/actions/GetText.ts | 2 +- packages/lib-engine/src/actions/Highlight.ts | 2 +- .../lib-engine/src/actions/InsertSnippet.ts | 2 +- packages/lib-engine/src/actions/JoinLines.ts | 2 +- packages/lib-engine/src/actions/Remove.ts | 4 ++- packages/lib-engine/src/actions/Replace.ts | 2 +- packages/lib-engine/src/actions/Rewrap.ts | 2 +- .../lib-engine/src/actions/ShowParseTree.ts | 4 ++- .../src/actions/ToggleBreakpoint.ts | 2 +- packages/lib-engine/src/actions/Wrap.ts | 2 +- .../lib-engine/src/actions/WrapWithSnippet.ts | 2 +- .../canonicalizeAndValidateCommand.ts | 2 +- .../canonicalizeTargetsInPlace.ts | 2 +- .../upgradeV5ToV6/canonicalizeActionName.ts | 2 +- .../upgradeV5ToV6/upgradeV5ToV6.ts | 2 +- .../getOffsetsForDeleteOrReplace.ts | 2 +- .../getOffsetsForEmptyRangeInsert.ts | 2 +- .../getOffsetsForNonEmptyRangeInsert.ts | 2 +- .../core/updateSelections/updateRangeInfos.ts | 6 ++-- .../transformRecordedTests/moveFile.ts | 2 +- .../src/ide/neovim/NeovimClipboard.ts | 2 +- .../src/ide/neovim/NeovimConfiguration.ts | 2 +- .../src/ide/neovim/NeovimEdit.ts | 2 +- .../src/ide/neovim/NeovimIDE.ts | 8 ++--- .../src/ide/neovim/NeovimKeyValueStore.ts | 2 +- .../src/ide/neovim/NeovimMessages.ts | 2 +- .../src/ide/neovim/NeovimTextDocument.ts | 2 +- .../src/ide/neovim/NeovimTextEditor.ts | 2 +- .../src/ide/neovim/NeovimTextLine.ts | 2 +- .../vite.config.ts | 1 + .../src/runners/extensionTestsNeovim.ts | 1 + stylelint.config.mjs | 1 + 94 files changed, 153 insertions(+), 133 deletions(-) diff --git a/.meta-updater/main.mjs b/.meta-updater/main.mjs index 594010bbe1..b7f0ed5892 100644 --- a/.meta-updater/main.mjs +++ b/.meta-updater/main.mjs @@ -1,3 +1,4 @@ import { updater } from "../packages/tool-meta-updater/src/index.ts"; +// oxlint-disable-next-line import/no-default-export export default updater; diff --git a/oxlint.config.mts b/oxlint.config.mts index 4a465535c7..0853a51b07 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -5,7 +5,6 @@ import { defineConfig } from "oxlint"; const temporarilyDisabled = [ "eslint/no-param-reassign", "eslint/prefer-template", - "import/no-default-export", "typescript/no-unsafe-type-assertion", "unicorn/no-array-reduce", "react/rules-of-hooks", diff --git a/packages/app-neovim/src/index.ts b/packages/app-neovim/src/index.ts index 354a4ba48e..62e322e7ac 100644 --- a/packages/app-neovim/src/index.ts +++ b/packages/app-neovim/src/index.ts @@ -6,6 +6,7 @@ import { activate } from "./extension"; * - Register the functions that are exposed to Neovim. * Note that these function need to start with a capital letter to be callable from Neovim. */ +// oxlint-disable-next-line import/no-default-export export default function entry(plugin: NvimPlugin) { // We make sure the cursorless-neovim extension is only loaded once, // as otherwise we will run our first copy when loading the extension diff --git a/packages/app-vscode/src/ide/vscode/VscodeClipboard.ts b/packages/app-vscode/src/ide/vscode/VscodeClipboard.ts index 9064e81516..baa7cbb26b 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeClipboard.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeClipboard.ts @@ -1,7 +1,7 @@ import * as vscode from "vscode"; import type { Clipboard } from "@cursorless/lib-common"; -export default class VscodeClipboard implements Clipboard { +export class VscodeClipboard implements Clipboard { async readText(): Promise { return await vscode.env.clipboard.readText(); } diff --git a/packages/app-vscode/src/ide/vscode/VscodeConfiguration.ts b/packages/app-vscode/src/ide/vscode/VscodeConfiguration.ts index a4488d43fd..66590907cb 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeConfiguration.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeConfiguration.ts @@ -22,7 +22,7 @@ const translators: TranslatorMap = { }, }; -export default class VscodeConfiguration implements Configuration { +export class VscodeConfiguration implements Configuration { private notifier = new Notifier(); constructor(ide: VscodeIDE) { diff --git a/packages/app-vscode/src/ide/vscode/VscodeEdit.ts b/packages/app-vscode/src/ide/vscode/VscodeEdit.ts index f2f7300878..dbf39c879a 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeEdit.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeEdit.ts @@ -2,7 +2,7 @@ import type * as vscode from "vscode"; import type { Edit } from "@cursorless/lib-common"; import { toVscodePosition, toVscodeRange } from "@cursorless/lib-vscode-common"; -export default async function vscodeEdit( +export async function vscodeEdit( editor: vscode.TextEditor, edits: Edit[], ): Promise { diff --git a/packages/app-vscode/src/ide/vscode/VscodeEnabledHatStyleManager.ts b/packages/app-vscode/src/ide/vscode/VscodeEnabledHatStyleManager.ts index 03fea0cd33..c3253ff24f 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeEnabledHatStyleManager.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeEnabledHatStyleManager.ts @@ -27,7 +27,7 @@ export type ExtendedHatStyleMap = Partial< * In VSCode, there is a hat style for every shape-color combination, filtered * by those whose penalty is not too large. */ -export default class VscodeEnabledHatStyleManager { +export class VscodeEnabledHatStyleManager { hatStyleMap!: ExtendedHatStyleMap; private notifier: Notifier<[HatStyleMap]> = new Notifier(); diff --git a/packages/app-vscode/src/ide/vscode/VscodeFlashHandler.ts b/packages/app-vscode/src/ide/vscode/VscodeFlashHandler.ts index e580d1b2f4..95d9a3ecb8 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeFlashHandler.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeFlashHandler.ts @@ -5,10 +5,10 @@ import type { FlashStyle, } from "@cursorless/lib-common"; import { groupBy, sleep } from "@cursorless/lib-common"; -import type VscodeHighlights from "./VscodeHighlights"; +import type { VscodeHighlights } from "./VscodeHighlights"; import type { VscodeIDE } from "./VscodeIDE"; -export default class VscodeFlashHandler { +export class VscodeFlashHandler { constructor( private ide: VscodeIDE, private highlights: VscodeHighlights, diff --git a/packages/app-vscode/src/ide/vscode/VscodeFocusEditor.ts b/packages/app-vscode/src/ide/vscode/VscodeFocusEditor.ts index 88f7054935..96628eee59 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeFocusEditor.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeFocusEditor.ts @@ -21,7 +21,7 @@ const columnFocusCommands = { /** * Focus editor. Returns true if selection needs to be set again. */ -export default async function vscodeFocusEditor( +export async function vscodeFocusEditor( editor: VscodeTextEditor, ): Promise { const viewColumn = getViewColumn(editor.vscodeEditor); diff --git a/packages/app-vscode/src/ide/vscode/VscodeHighlights.ts b/packages/app-vscode/src/ide/vscode/VscodeHighlights.ts index f024c9bbc4..5d9ebf2ea8 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeHighlights.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeHighlights.ts @@ -29,7 +29,7 @@ const allStyles = Object.values(FlashStyle).concat( * {@link VscodeFlashHandler} for rendering the decorations used for flashes, but this * class doesn't handle the timing of the flashes. */ -export default class VscodeHighlights { +export class VscodeHighlights { private highlightDecorations: Record< VscodeStyle, VscodeHighlightDecorationTypes diff --git a/packages/app-vscode/src/ide/vscode/VscodeIDE.ts b/packages/app-vscode/src/ide/vscode/VscodeIDE.ts index 40463f312f..795033a332 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeIDE.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeIDE.ts @@ -27,14 +27,14 @@ import { fromVscodeSelection, } from "@cursorless/lib-vscode-common"; import { VscodeCapabilities } from "./VscodeCapabilities"; -import VscodeClipboard from "./VscodeClipboard"; -import VscodeConfiguration from "./VscodeConfiguration"; +import { VscodeClipboard } from "./VscodeClipboard"; +import { VscodeConfiguration } from "./VscodeConfiguration"; import { forwardEvent, vscodeOnDidChangeTextDocument } from "./VscodeEvents"; -import VscodeFlashHandler from "./VscodeFlashHandler"; -import VscodeHighlights, { HighlightStyle } from "./VscodeHighlights"; +import { VscodeFlashHandler } from "./VscodeFlashHandler"; +import { HighlightStyle, VscodeHighlights } from "./VscodeHighlights"; import { VscodeNotebookEditorImpl } from "./VscodeIdeNotebook"; -import VscodeKeyValueStore from "./VscodeKeyValueStore"; -import VscodeMessages from "./VscodeMessages"; +import { VscodeKeyValueStore } from "./VscodeKeyValueStore"; +import { VscodeMessages } from "./VscodeMessages"; import { vscodeRunMode } from "./VscodeRunMode"; import { vscodeShowQuickPick } from "./vscodeShowQuickPick"; import { VscodeTextDocument } from "./VscodeTextDocument"; diff --git a/packages/app-vscode/src/ide/vscode/VscodeKeyValueStore.ts b/packages/app-vscode/src/ide/vscode/VscodeKeyValueStore.ts index 2d1f13d55a..74f38aa20e 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeKeyValueStore.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeKeyValueStore.ts @@ -9,7 +9,7 @@ import { VERSION_KEY } from "../../ReleaseNotes"; import { DONT_SHOW_TALON_UPDATE_MESSAGE_KEY } from "../../ScopeTreeProvider"; import { PERFORMED_PR_1868_SHAPE_UPDATE_INIT_KEY } from "./hats/performPr1868ShapeUpdateInit"; -export default class VscodeKeyValueStore implements KeyValueStore { +export class VscodeKeyValueStore implements KeyValueStore { constructor(private extensionContext: ExtensionContext) { // Mark all keys for synchronization extensionContext.globalState.setKeysForSync([ diff --git a/packages/app-vscode/src/ide/vscode/VscodeMessages.ts b/packages/app-vscode/src/ide/vscode/VscodeMessages.ts index 0a3e955401..6bdfc72991 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeMessages.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeMessages.ts @@ -2,7 +2,7 @@ import { window } from "vscode"; import type { MessageId, Messages } from "@cursorless/lib-common"; import { MessageType } from "@cursorless/lib-common"; -export default class VscodeMessages implements Messages { +export class VscodeMessages implements Messages { async showMessage( type: MessageType, _id: MessageId, diff --git a/packages/app-vscode/src/ide/vscode/VscodeOpenLink.ts b/packages/app-vscode/src/ide/vscode/VscodeOpenLink.ts index 2be5a6a86a..3210e5a9bc 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeOpenLink.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeOpenLink.ts @@ -4,7 +4,7 @@ import { Selection } from "@cursorless/lib-common"; import { toVscodePositionOrRange } from "@cursorless/lib-vscode-common"; import type { VscodeTextEditor } from "./VscodeTextEditor"; -export default async function vscodeOpenLink( +export async function vscodeOpenLink( editor: VscodeTextEditor, range: Range, { openAside }: OpenLinkOptions, diff --git a/packages/app-vscode/src/ide/vscode/VscodeTextDocument.ts b/packages/app-vscode/src/ide/vscode/VscodeTextDocument.ts index 5ddba2dd39..4009859b91 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeTextDocument.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeTextDocument.ts @@ -14,7 +14,7 @@ import { toVscodePosition, toVscodeRange, } from "@cursorless/lib-vscode-common"; -import VscodeTextLine from "./VscodeTextLine"; +import { VscodeTextLine } from "./VscodeTextLine"; export class VscodeTextDocument implements TextDocument { get uri(): URI { diff --git a/packages/app-vscode/src/ide/vscode/VscodeTextEditor.ts b/packages/app-vscode/src/ide/vscode/VscodeTextEditor.ts index dd1e4850ba..44546c8370 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeTextEditor.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeTextEditor.ts @@ -20,12 +20,12 @@ import { toVscodeSelection, } from "@cursorless/lib-vscode-common"; import { isDiffEditorOriginal } from "./isDiffEditorOriginal"; -import vscodeEdit from "./VscodeEdit"; -import vscodeFocusEditor from "./VscodeFocusEditor"; +import { vscodeEdit } from "./VscodeEdit"; +import { vscodeFocusEditor } from "./VscodeFocusEditor"; import { vscodeFold, vscodeUnfold } from "./VscodeFold"; import type { VscodeIDE } from "./VscodeIDE"; import { vscodeInsertSnippet } from "./VscodeInsertSnippets"; -import vscodeOpenLink from "./VscodeOpenLink"; +import { vscodeOpenLink } from "./VscodeOpenLink"; import { vscodeRevealLine } from "./VscodeRevealLine"; import { VscodeTextDocument } from "./VscodeTextDocument"; import { vscodeToggleBreakpoint } from "./VscodeToggleBreakpoint"; diff --git a/packages/app-vscode/src/ide/vscode/VscodeTextLine.ts b/packages/app-vscode/src/ide/vscode/VscodeTextLine.ts index 71a9acaebe..e13bc0c011 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeTextLine.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeTextLine.ts @@ -3,7 +3,7 @@ import type { TextLine } from "@cursorless/lib-common"; import { Position, Range } from "@cursorless/lib-common"; import { fromVscodeRange } from "@cursorless/lib-vscode-common"; -export default class VscodeTextLine implements TextLine { +export class VscodeTextLine implements TextLine { constructor(private line: vscode.TextLine) {} get lineNumber(): number { diff --git a/packages/app-vscode/src/ide/vscode/hats/VscodeHatRenderer.ts b/packages/app-vscode/src/ide/vscode/hats/VscodeHatRenderer.ts index 9bfa656a3c..7657d51887 100644 --- a/packages/app-vscode/src/ide/vscode/hats/VscodeHatRenderer.ts +++ b/packages/app-vscode/src/ide/vscode/hats/VscodeHatRenderer.ts @@ -13,10 +13,12 @@ import type { VscodeApi } from "@cursorless/lib-vscode-common"; import type { HatShape, VscodeHatStyleName } from "../hatStyles.types"; import { HAT_SHAPES } from "../hatStyles.types"; import { vscodeGetConfigurationString } from "../VscodeConfiguration"; -import type VscodeEnabledHatStyleManager from "../VscodeEnabledHatStyleManager"; -import type { ExtendedHatStyleMap } from "../VscodeEnabledHatStyleManager"; +import type { + ExtendedHatStyleMap, + VscodeEnabledHatStyleManager, +} from "../VscodeEnabledHatStyleManager"; import type { FontMeasurements } from "./FontMeasurements"; -import getHatThemeColors from "./getHatThemeColors"; +import { getHatThemeColors } from "./getHatThemeColors"; import { performPr1868ShapeUpdateInit } from "./performPr1868ShapeUpdateInit"; import type { IndividualHatAdjustmentMap } from "./shapeAdjustments"; import { @@ -60,7 +62,7 @@ interface SvgInfo { * hats. The decision about which hat styles should be available is up to * {@link VscodeEnabledHatStyles} */ -export default class VscodeHatRenderer { +export class VscodeHatRenderer { private decorationMap!: HatDecorationMap; private disposables: vscode.Disposable[] = []; private notifier: Notifier = new Notifier(); diff --git a/packages/app-vscode/src/ide/vscode/hats/VscodeHats.ts b/packages/app-vscode/src/ide/vscode/hats/VscodeHats.ts index dbfe93f03b..fa58766197 100644 --- a/packages/app-vscode/src/ide/vscode/hats/VscodeHats.ts +++ b/packages/app-vscode/src/ide/vscode/hats/VscodeHats.ts @@ -13,11 +13,11 @@ import { Notifier } from "@cursorless/lib-common"; import type { VscodeApi } from "@cursorless/lib-vscode-common"; import { toVscodeRange } from "@cursorless/lib-vscode-common"; import type { VscodeHatStyleName } from "../hatStyles.types"; -import VscodeEnabledHatStyleManager from "../VscodeEnabledHatStyleManager"; +import { VscodeEnabledHatStyleManager } from "../VscodeEnabledHatStyleManager"; import type { VscodeIDE } from "../VscodeIDE"; import type { VscodeTextEditor } from "../VscodeTextEditor"; import type { FontMeasurements } from "./FontMeasurements"; -import VscodeHatRenderer from "./VscodeHatRenderer"; +import { VscodeHatRenderer } from "./VscodeHatRenderer"; export class VscodeHats implements Hats { private enabledHatStyleManager: VscodeEnabledHatStyleManager; diff --git a/packages/app-vscode/src/ide/vscode/hats/getHatThemeColors.ts b/packages/app-vscode/src/ide/vscode/hats/getHatThemeColors.ts index aae1262558..8164c7e640 100644 --- a/packages/app-vscode/src/ide/vscode/hats/getHatThemeColors.ts +++ b/packages/app-vscode/src/ide/vscode/hats/getHatThemeColors.ts @@ -7,7 +7,7 @@ interface OldDecorationColorSetting { highContrast: string; } -export default function getHatThemeColors(colorName: HatColor) { +export function getHatThemeColors(colorName: HatColor) { const oldStyleColorSetting = vscode.workspace .getConfiguration("cursorless.colors") .get(colorName); diff --git a/packages/app-vscode/src/ide/vscode/textLine.vscode.test.ts b/packages/app-vscode/src/ide/vscode/textLine.vscode.test.ts index afd1cafd32..fc2ad2e60f 100644 --- a/packages/app-vscode/src/ide/vscode/textLine.vscode.test.ts +++ b/packages/app-vscode/src/ide/vscode/textLine.vscode.test.ts @@ -1,6 +1,6 @@ import * as assert from "node:assert/strict"; import { getReusableEditor } from "@cursorless/lib-vscode-common"; -import VscodeTextLine from "./VscodeTextLine"; +import { VscodeTextLine } from "./VscodeTextLine"; /** * Each test is of the form: diff --git a/packages/app-vscode/src/keyboard/KeyboardCommandHandler.ts b/packages/app-vscode/src/keyboard/KeyboardCommandHandler.ts index 1dcf9349e9..5342ae49cf 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommandHandler.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommandHandler.ts @@ -11,8 +11,10 @@ import type { SimpleKeyboardActionDescriptor, SpecificKeyboardActionDescriptor, } from "./KeyboardActionType"; -import type { TargetingMode } from "./KeyboardCommandsTargeted"; -import type KeyboardCommandsTargeted from "./KeyboardCommandsTargeted"; +import type { + TargetingMode, + KeyboardCommandsTargeted, +} from "./KeyboardCommandsTargeted"; import type { ModalVscodeCommandDescriptor } from "./TokenTypes"; /** diff --git a/packages/app-vscode/src/keyboard/KeyboardCommands.ts b/packages/app-vscode/src/keyboard/KeyboardCommands.ts index 9d70306114..008e23f381 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommands.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommands.ts @@ -1,9 +1,9 @@ import type { ExtensionContext } from "vscode"; import type { VscodeApi } from "@cursorless/lib-vscode-common"; import type { StatusBarItem } from "../StatusBarItem"; -import KeyboardCommandsModal from "./KeyboardCommandsModal"; -import KeyboardCommandsTargeted from "./KeyboardCommandsTargeted"; -import KeyboardHandler from "./KeyboardHandler"; +import { KeyboardCommandsModal } from "./KeyboardCommandsModal"; +import { KeyboardCommandsTargeted } from "./KeyboardCommandsTargeted"; +import { KeyboardHandler } from "./KeyboardHandler"; export class KeyboardCommands { targeted: KeyboardCommandsTargeted; diff --git a/packages/app-vscode/src/keyboard/KeyboardCommandsModal.ts b/packages/app-vscode/src/keyboard/KeyboardCommandsModal.ts index c3122fc009..df8de3f8d3 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommandsModal.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommandsModal.ts @@ -8,15 +8,15 @@ import grammar from "./grammar/generated/grammar"; import { getAcceptableTokenTypes } from "./grammar/getAcceptableTokenTypes"; import { KeyboardCommandHandler } from "./KeyboardCommandHandler"; import { KeyboardCommandsModalLayer } from "./KeyboardCommandsModalLayer"; -import type KeyboardCommandsTargeted from "./KeyboardCommandsTargeted"; +import type { KeyboardCommandsTargeted } from "./KeyboardCommandsTargeted"; import { KeyboardConfig } from "./KeyboardConfig"; -import type KeyboardHandler from "./KeyboardHandler"; +import type { KeyboardHandler } from "./KeyboardHandler"; import type { KeyDescriptor, TokenTypeKeyMapMap } from "./TokenTypeHelpers"; /** * Defines a mode to use with a modal version of Cursorless keyboard. */ -export default class KeyboardCommandsModal { +export class KeyboardCommandsModal { /** * This disposable is returned by {@link KeyboardHandler.pushListener}, and is * used to relinquich control of the keyboard. If this disposable is diff --git a/packages/app-vscode/src/keyboard/KeyboardCommandsModalLayer.ts b/packages/app-vscode/src/keyboard/KeyboardCommandsModalLayer.ts index 67ae8e97aa..0d98777491 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommandsModalLayer.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommandsModalLayer.ts @@ -2,7 +2,7 @@ import type TrieSearch from "trie-search"; import * as vscode from "vscode"; import type { KeyValuePair } from "./buildSuffixTrie"; import { buildSuffixTrie } from "./buildSuffixTrie"; -import type KeyboardHandler from "./KeyboardHandler"; +import type { KeyboardHandler } from "./KeyboardHandler"; /** * Defines a single keyboard layer to use with a modal version of Cursorless diff --git a/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts b/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts index dd7419c5f5..3b3af38608 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts @@ -12,8 +12,8 @@ import { runCursorlessCommand } from "@cursorless/lib-vscode-common"; import { getStyleName } from "../ide/vscode/hats/getStyleName"; import type { HatColor, HatShape } from "../ide/vscode/hatStyles.types"; import type { SimpleKeyboardActionDescriptor } from "./KeyboardActionType"; -import type KeyboardCommandsModal from "./KeyboardCommandsModal"; -import type KeyboardHandler from "./KeyboardHandler"; +import type { KeyboardCommandsModal } from "./KeyboardCommandsModal"; +import type { KeyboardHandler } from "./KeyboardHandler"; export type TargetingMode = | "replace" @@ -46,7 +46,7 @@ interface PerformActionOpts { * keyboard interface. The commands set highlights and allow you to perform * actions on highlighted targets. */ -export default class KeyboardCommandsTargeted { +export class KeyboardCommandsTargeted { private modal!: KeyboardCommandsModal; constructor(private keyboardHandler: KeyboardHandler) { diff --git a/packages/app-vscode/src/keyboard/KeyboardHandler.ts b/packages/app-vscode/src/keyboard/KeyboardHandler.ts index d142bd81e4..65be18a6b2 100644 --- a/packages/app-vscode/src/keyboard/KeyboardHandler.ts +++ b/packages/app-vscode/src/keyboard/KeyboardHandler.ts @@ -79,7 +79,7 @@ interface TypeCommandArg { * will take over the keyboard, unless the stack is empty, which will give * keyboard control back to VSCode. */ -export default class KeyboardHandler { +export class KeyboardHandler { private listeners: ListenerEntry[] = []; private activeListener: ListenerEntry | undefined; private typeCommandDisposable?: Disposable; diff --git a/packages/app-web-docs/docusaurus.config.mts b/packages/app-web-docs/docusaurus.config.mts index eef2759b63..0e053fdc32 100644 --- a/packages/app-web-docs/docusaurus.config.mts +++ b/packages/app-web-docs/docusaurus.config.mts @@ -214,4 +214,5 @@ const config: Config = { }, }; +// oxlint-disable-next-line import/no-default-export export default config; diff --git a/packages/app-web-docs/sidebar.js b/packages/app-web-docs/sidebar.js index 7da6acc93d..0d47f677c8 100644 --- a/packages/app-web-docs/sidebar.js +++ b/packages/app-web-docs/sidebar.js @@ -6,4 +6,5 @@ const config = { contributing: [{ type: "autogenerated", dirName: "contributing" }], }; +// oxlint-disable-next-line import/no-default-export export default config; diff --git a/packages/app-web-docs/src/plugins/scope-tests-plugin.ts b/packages/app-web-docs/src/plugins/scope-tests-plugin.ts index 51f35f2f15..9b02bcf59f 100644 --- a/packages/app-web-docs/src/plugins/scope-tests-plugin.ts +++ b/packages/app-web-docs/src/plugins/scope-tests-plugin.ts @@ -17,6 +17,7 @@ import type { // oxlint-disable-next-line unicorn/prefer-import-meta-properties const __dirname = path.dirname(fileURLToPath(import.meta.url)); +// oxlint-disable-next-line import/no-default-export export default function prepareAssetsPlugin( _context: LoadContext, _options: PluginOptions, diff --git a/packages/app-web-docs/src/theme/Root.tsx b/packages/app-web-docs/src/theme/Root.tsx index 97663ef68f..f8f7b64a5a 100644 --- a/packages/app-web-docs/src/theme/Root.tsx +++ b/packages/app-web-docs/src/theme/Root.tsx @@ -13,6 +13,7 @@ function syncBootstrapTheme() { root.dataset.bsTheme = theme; } +// oxlint-disable-next-line import/no-default-export export default function Root({ children }: Props): React.ReactNode { useEffect(() => { syncBootstrapTheme(); diff --git a/packages/app-web/vite.config.ts b/packages/app-web/vite.config.ts index 78e913e2ae..02382a09df 100644 --- a/packages/app-web/vite.config.ts +++ b/packages/app-web/vite.config.ts @@ -17,6 +17,7 @@ import { YOUTUBE_SLUG, } from "./src/constants"; +// oxlint-disable-next-line import/no-default-export export default defineConfig((): UserConfig => { return { build: { diff --git a/packages/lib-cheatsheet-local/jest.config.ts b/packages/lib-cheatsheet-local/jest.config.ts index f87a863629..7cd495c91f 100644 --- a/packages/lib-cheatsheet-local/jest.config.ts +++ b/packages/lib-cheatsheet-local/jest.config.ts @@ -13,4 +13,5 @@ const config: Config = { }, }; +// oxlint-disable-next-line import/no-default-export export default config; diff --git a/packages/lib-cheatsheet-local/src/test/styleMock.ts b/packages/lib-cheatsheet-local/src/test/styleMock.ts index b64ee9216b..dc3cdc07e5 100644 --- a/packages/lib-cheatsheet-local/src/test/styleMock.ts +++ b/packages/lib-cheatsheet-local/src/test/styleMock.ts @@ -1,2 +1,2 @@ -// oxlint-disable-next-line import/no-anonymous-default-export +// oxlint-disable-next-line import/no-anonymous-default-export, import/no-default-export export default {}; diff --git a/packages/lib-cheatsheet-local/vite.config.ts b/packages/lib-cheatsheet-local/vite.config.ts index b8a358c68c..572edcab3e 100644 --- a/packages/lib-cheatsheet-local/vite.config.ts +++ b/packages/lib-cheatsheet-local/vite.config.ts @@ -9,6 +9,7 @@ import { vitePreactAlias, } from "@cursorless/lib-common/vite"; +// oxlint-disable-next-line import/no-default-export export default defineConfig((): UserConfig => { return { build: { diff --git a/packages/lib-cheatsheet/jest.config.ts b/packages/lib-cheatsheet/jest.config.ts index f87a863629..7cd495c91f 100644 --- a/packages/lib-cheatsheet/jest.config.ts +++ b/packages/lib-cheatsheet/jest.config.ts @@ -13,4 +13,5 @@ const config: Config = { }, }; +// oxlint-disable-next-line import/no-default-export export default config; diff --git a/packages/lib-cheatsheet/src/lib/Cheatsheet.tsx b/packages/lib-cheatsheet/src/lib/Cheatsheet.tsx index 059d6035d8..8b8be08f76 100644 --- a/packages/lib-cheatsheet/src/lib/Cheatsheet.tsx +++ b/packages/lib-cheatsheet/src/lib/Cheatsheet.tsx @@ -2,12 +2,12 @@ import { useEffect } from "preact/hooks"; import { QuestionCircleFill } from "react-bootstrap-icons"; import "./cheatsheet.css"; import type { CheatsheetInfo } from "./cheatsheet.types"; -import CheatsheetLegendSection from "./CheatsheetLegendSection"; -import CheatsheetListSection from "./CheatsheetListSection"; -import CheatsheetNotesSection from "./CheatsheetNotesSection"; +import { CheatsheetLegendSection } from "./CheatsheetLegendSection"; +import { CheatsheetListSection } from "./CheatsheetListSection"; +import { CheatsheetNotesSection } from "./CheatsheetNotesSection"; import { applyBootstrapTheme } from "./utils/applyBootstrapTheme"; import { cheatsheetLegendData } from "./utils/cheatsheetLegendData"; -import SmartLink from "./utils/SmartLink"; +import { SmartLink } from "./utils/SmartLink"; type Props = { cheatsheetInfo: CheatsheetInfo; diff --git a/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx b/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx index b0378ad596..e010be379b 100644 --- a/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx +++ b/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx @@ -1,14 +1,14 @@ import type { JSX } from "preact"; import type { CheatsheetLegend } from "./cheatsheet.types"; import { formatCaptures } from "./utils/formatCaptures"; -import SmartLink from "./utils/SmartLink"; -import useIsHighlighted from "./utils/useIsHighlighted"; +import { SmartLink } from "./utils/SmartLink"; +import { useIsHighlighted } from "./utils/useIsHighlighted"; type Props = { data: CheatsheetLegend; }; -export default function CheatsheetLegendSection({ data }: Props): JSX.Element { +export function CheatsheetLegendSection({ data }: Props): JSX.Element { const isHighlighted = useIsHighlighted("legend"); return ( diff --git a/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx b/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx index 9d6db7359b..82ef4488bb 100644 --- a/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx +++ b/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx @@ -1,13 +1,13 @@ import type { JSX } from "preact"; import type { CheatsheetSection, Variation } from "./cheatsheet.types"; import { formatCaptures } from "./utils/formatCaptures"; -import useIsHighlighted from "./utils/useIsHighlighted"; +import { useIsHighlighted } from "./utils/useIsHighlighted"; type Props = { section: CheatsheetSection; }; -export default function CheatsheetListSection({ section }: Props): JSX.Element { +export function CheatsheetListSection({ section }: Props): JSX.Element { const isHighlighted = useIsHighlighted(section.id); const variations = section.items.flatMap((item) => item.variations); diff --git a/packages/lib-cheatsheet/src/lib/CheatsheetNotesSection.tsx b/packages/lib-cheatsheet/src/lib/CheatsheetNotesSection.tsx index 1ec7b2b6b9..139bd584e4 100644 --- a/packages/lib-cheatsheet/src/lib/CheatsheetNotesSection.tsx +++ b/packages/lib-cheatsheet/src/lib/CheatsheetNotesSection.tsx @@ -1,7 +1,7 @@ import type { JSX } from "preact"; -import SmartLink from "./utils/SmartLink"; +import { SmartLink } from "./utils/SmartLink"; -export default function CheatsheetNotesSection(): JSX.Element { +export function CheatsheetNotesSection(): JSX.Element { return (
See the{" "} diff --git a/packages/lib-cheatsheet/src/lib/utils/SmartLink.tsx b/packages/lib-cheatsheet/src/lib/utils/SmartLink.tsx index 8c83a6c89d..32577636b9 100644 --- a/packages/lib-cheatsheet/src/lib/utils/SmartLink.tsx +++ b/packages/lib-cheatsheet/src/lib/utils/SmartLink.tsx @@ -15,7 +15,7 @@ type SmartLinkProps = { * internal * @returns SmartLink component */ -export default function SmartLink({ +export function SmartLink({ to, children, noFormatting = false, diff --git a/packages/lib-cheatsheet/src/lib/utils/formatCaptures.tsx b/packages/lib-cheatsheet/src/lib/utils/formatCaptures.tsx index b7a7d09518..304a679d05 100644 --- a/packages/lib-cheatsheet/src/lib/utils/formatCaptures.tsx +++ b/packages/lib-cheatsheet/src/lib/utils/formatCaptures.tsx @@ -1,5 +1,5 @@ import type { ComponentChildren } from "preact"; -import SmartLink from "./SmartLink"; +import { SmartLink } from "./SmartLink"; export function formatCaptures(input: string): ComponentChildren[] { const parts: ComponentChildren[] = []; diff --git a/packages/lib-cheatsheet/src/lib/utils/useIsHighlighted.ts b/packages/lib-cheatsheet/src/lib/utils/useIsHighlighted.ts index 2ee0badeca..1d64784528 100644 --- a/packages/lib-cheatsheet/src/lib/utils/useIsHighlighted.ts +++ b/packages/lib-cheatsheet/src/lib/utils/useIsHighlighted.ts @@ -9,7 +9,7 @@ const isBrowser = typeof window !== "undefined"; * @param id The id to match the hash against * @returns Boolean indicating whether the hash matches the given id */ -export default function useIsHighlighted(id: string): boolean { +export function useIsHighlighted(id: string): boolean { if (isBrowser) { const hash = useHash(); return hash === `#${id}`; diff --git a/packages/lib-cheatsheet/src/test/styleMock.ts b/packages/lib-cheatsheet/src/test/styleMock.ts index b64ee9216b..dc3cdc07e5 100644 --- a/packages/lib-cheatsheet/src/test/styleMock.ts +++ b/packages/lib-cheatsheet/src/test/styleMock.ts @@ -1,2 +1,2 @@ -// oxlint-disable-next-line import/no-anonymous-default-export +// oxlint-disable-next-line import/no-anonymous-default-export, import/no-default-export export default {}; diff --git a/packages/lib-common/src/ide/fake/FakeClipboard.ts b/packages/lib-common/src/ide/fake/FakeClipboard.ts index e730267885..5c5013e8d2 100644 --- a/packages/lib-common/src/ide/fake/FakeClipboard.ts +++ b/packages/lib-common/src/ide/fake/FakeClipboard.ts @@ -1,6 +1,6 @@ import type { Clipboard } from "../types/Clipboard"; -export default class FakeClipboard implements Clipboard { +export class FakeClipboard implements Clipboard { private clipboardContents: string = ""; readText(): Promise { diff --git a/packages/lib-common/src/ide/fake/FakeConfiguration.ts b/packages/lib-common/src/ide/fake/FakeConfiguration.ts index 0638b8c6b9..cdb3bd1477 100644 --- a/packages/lib-common/src/ide/fake/FakeConfiguration.ts +++ b/packages/lib-common/src/ide/fake/FakeConfiguration.ts @@ -14,7 +14,7 @@ interface ConfigurationScopeValues { values: Partial; } -export default class FakeConfiguration implements Configuration { +export class FakeConfiguration implements Configuration { private notifier = new Notifier(); private mocks: CursorlessConfiguration = { ...CONFIGURATION_DEFAULTS, diff --git a/packages/lib-common/src/ide/fake/FakeIDE.ts b/packages/lib-common/src/ide/fake/FakeIDE.ts index a419ead536..b5fcf64fbe 100644 --- a/packages/lib-common/src/ide/fake/FakeIDE.ts +++ b/packages/lib-common/src/ide/fake/FakeIDE.ts @@ -21,10 +21,10 @@ import type { import type { Messages } from "../types/Messages"; import type { QuickPickOptions } from "../types/QuickPickOptions"; import { FakeCapabilities } from "./FakeCapabilities"; -import FakeClipboard from "./FakeClipboard"; -import FakeConfiguration from "./FakeConfiguration"; -import FakeKeyValueStore from "./FakeKeyValueStore"; -import FakeMessages from "./FakeMessages"; +import { FakeClipboard } from "./FakeClipboard"; +import { FakeConfiguration } from "./FakeConfiguration"; +import { FakeKeyValueStore } from "./FakeKeyValueStore"; +import { FakeMessages } from "./FakeMessages"; export class FakeIDE implements EmittableIDE { configuration = new FakeConfiguration(); diff --git a/packages/lib-common/src/ide/fake/FakeKeyValueStore.ts b/packages/lib-common/src/ide/fake/FakeKeyValueStore.ts index df7d537e1c..758931cfb3 100644 --- a/packages/lib-common/src/ide/fake/FakeKeyValueStore.ts +++ b/packages/lib-common/src/ide/fake/FakeKeyValueStore.ts @@ -5,7 +5,7 @@ import type { } from "../types/KeyValueStore"; import { KEY_VALUE_STORE_DEFAULTS } from "../types/KeyValueStore"; -export default class FakeKeyValueStore implements KeyValueStore { +export class FakeKeyValueStore implements KeyValueStore { private readonly data: KeyValueStoreData = { ...KEY_VALUE_STORE_DEFAULTS }; get(key: K): KeyValueStoreData[K] { diff --git a/packages/lib-common/src/ide/fake/FakeMessages.ts b/packages/lib-common/src/ide/fake/FakeMessages.ts index 9329dbf43f..65860fe99f 100644 --- a/packages/lib-common/src/ide/fake/FakeMessages.ts +++ b/packages/lib-common/src/ide/fake/FakeMessages.ts @@ -1,6 +1,6 @@ import type { MessageId, Messages, MessageType } from "../types/Messages"; -export default class FakeMessages implements Messages { +export class FakeMessages implements Messages { showMessage( _type: MessageType, _id: MessageId, diff --git a/packages/lib-common/src/ide/normalized/NormalizedIDE.ts b/packages/lib-common/src/ide/normalized/NormalizedIDE.ts index 3e0cded064..5a592d9438 100644 --- a/packages/lib-common/src/ide/normalized/NormalizedIDE.ts +++ b/packages/lib-common/src/ide/normalized/NormalizedIDE.ts @@ -1,8 +1,8 @@ import type { GeneralizedRange } from "../../types/GeneralizedRange"; import type { TextEditor } from "../../types/TextEditor"; -import type FakeConfiguration from "../fake/FakeConfiguration"; +import type { FakeConfiguration } from "../fake/FakeConfiguration"; import type { FakeIDE } from "../fake/FakeIDE"; -import type FakeKeyValueStore from "../fake/FakeKeyValueStore"; +import type { FakeKeyValueStore } from "../fake/FakeKeyValueStore"; import { PassthroughIDE } from "../PassthroughIDE"; import type { FlashDescriptor } from "../types/FlashDescriptor"; import type { IDE } from "../types/ide.types"; diff --git a/packages/lib-common/src/ide/spy/SpyIDE.ts b/packages/lib-common/src/ide/spy/SpyIDE.ts index 49013fea69..69d0b00c98 100644 --- a/packages/lib-common/src/ide/spy/SpyIDE.ts +++ b/packages/lib-common/src/ide/spy/SpyIDE.ts @@ -5,7 +5,7 @@ import { PassthroughIDE } from "../PassthroughIDE"; import type { FlashDescriptor } from "../types/FlashDescriptor"; import type { HighlightId, IDE } from "../types/ide.types"; import type { Message } from "./SpyMessages"; -import SpyMessages from "./SpyMessages"; +import { SpyMessages } from "./SpyMessages"; interface Highlight { highlightId: HighlightId | undefined; diff --git a/packages/lib-common/src/ide/spy/SpyMessages.ts b/packages/lib-common/src/ide/spy/SpyMessages.ts index d1f652fb4a..f0546143f1 100644 --- a/packages/lib-common/src/ide/spy/SpyMessages.ts +++ b/packages/lib-common/src/ide/spy/SpyMessages.ts @@ -10,7 +10,7 @@ export interface Message { id: MessageId; } -export default class SpyMessages implements Messages { +export class SpyMessages implements Messages { private shownMessages: Message[] = []; constructor(private original: Messages) {} diff --git a/packages/lib-engine/src/actions/Actions.ts b/packages/lib-engine/src/actions/Actions.ts index d703f9b339..1a2abb6f58 100644 --- a/packages/lib-engine/src/actions/Actions.ts +++ b/packages/lib-engine/src/actions/Actions.ts @@ -5,21 +5,21 @@ import type { ModifierStageFactory } from "../processTargets/ModifierStageFactor import type { ActionRecord } from "./actions.types"; import { BreakLine } from "./BreakLine"; import { Bring, Move, Swap } from "./BringMoveSwap"; -import Call from "./Call"; -import Clear from "./Clear"; +import { Call } from "./Call"; +import { Clear } from "./Clear"; import { CopyToClipboard } from "./CopyToClipboard"; import { CutToClipboard } from "./CutToClipboard"; -import Deselect from "./Deselect"; +import { Deselect } from "./Deselect"; import { EditNew } from "./EditNew"; import { EditNewAfter, EditNewBefore } from "./EditNewLineAction"; -import ExecuteCommand from "./ExecuteCommand"; +import { ExecuteCommand } from "./ExecuteCommand"; import { FindInDocument, FindInWorkspace } from "./Find"; import { FlashTargets } from "./FlashTargets"; -import FollowLink from "./FollowLink"; -import GenerateSnippet from "./GenerateSnippet"; -import GetTargets from "./GetTargets"; -import GetText from "./GetText"; -import Highlight from "./Highlight"; +import { FollowLink } from "./FollowLink"; +import { GenerateSnippet } from "./GenerateSnippet"; +import { GetTargets } from "./GetTargets"; +import { GetText } from "./GetText"; +import { Highlight } from "./Highlight"; import { Decrement, Increment } from "./incrementDecrement"; import { IndentLine, OutdentLine } from "./IndentLine"; import { InsertCopyAfter, InsertCopyBefore } from "./InsertCopy"; @@ -28,12 +28,12 @@ import { InsertEmptyLineBefore, InsertEmptyLinesAround, } from "./InsertEmptyLines"; -import InsertSnippet from "./InsertSnippet"; -import JoinLines from "./JoinLines"; +import { InsertSnippet } from "./InsertSnippet"; +import { JoinLines } from "./JoinLines"; import { PasteFromClipboard } from "./PasteFromClipboard"; -import Remove from "./Remove"; -import Replace from "./Replace"; -import Rewrap from "./Rewrap"; +import { Remove } from "./Remove"; +import { Replace } from "./Replace"; +import { Rewrap } from "./Rewrap"; import { ScrollToBottom, ScrollToCenter, ScrollToTop } from "./Scroll"; import { AddSelection, @@ -44,7 +44,7 @@ import { SetSelectionBefore, } from "./SetSelection"; import { SetSpecialTarget } from "./SetSpecialTarget"; -import ShowParseTree from "./ShowParseTree"; +import { ShowParseTree } from "./ShowParseTree"; import { ExtractVariable, Fold, @@ -63,9 +63,9 @@ import { Unfold, } from "./SimpleIdeCommandActions"; import { Random, Reverse, Sort } from "./Sort"; -import ToggleBreakpoint from "./ToggleBreakpoint"; -import Wrap from "./Wrap"; -import WrapWithSnippet from "./WrapWithSnippet"; +import { ToggleBreakpoint } from "./ToggleBreakpoint"; +import { Wrap } from "./Wrap"; +import { WrapWithSnippet } from "./WrapWithSnippet"; /** * Keeps a map from action names to objects that implement the given action diff --git a/packages/lib-engine/src/actions/Call.ts b/packages/lib-engine/src/actions/Call.ts index d78ef4d94d..617bb43b53 100644 --- a/packages/lib-engine/src/actions/Call.ts +++ b/packages/lib-engine/src/actions/Call.ts @@ -3,7 +3,7 @@ import { ensureSingleTarget } from "../util/targetUtils"; import type { Actions } from "./Actions"; import type { ActionReturnValue } from "./actions.types"; -export default class Call { +export class Call { constructor(private actions: Actions) { this.run = this.run.bind(this); } diff --git a/packages/lib-engine/src/actions/Clear.ts b/packages/lib-engine/src/actions/Clear.ts index 4e8e75cc73..39ee8582d8 100644 --- a/packages/lib-engine/src/actions/Clear.ts +++ b/packages/lib-engine/src/actions/Clear.ts @@ -5,7 +5,7 @@ import { ensureSingleEditor } from "../util/targetUtils"; import type { Actions } from "./Actions"; import type { SimpleAction, ActionReturnValue } from "./actions.types"; -export default class Clear implements SimpleAction { +export class Clear implements SimpleAction { constructor( private ide: IDE, private actions: Actions, diff --git a/packages/lib-engine/src/actions/Deselect.ts b/packages/lib-engine/src/actions/Deselect.ts index 919d44b6b1..3ca0a3a3e1 100644 --- a/packages/lib-engine/src/actions/Deselect.ts +++ b/packages/lib-engine/src/actions/Deselect.ts @@ -3,7 +3,7 @@ import type { Target } from "../typings/target.types"; import { runOnTargetsForEachEditor } from "../util/targetUtils"; import type { SimpleAction, ActionReturnValue } from "./actions.types"; -export default class Deselect implements SimpleAction { +export class Deselect implements SimpleAction { constructor(private ide: IDE) { this.run = this.run.bind(this); } diff --git a/packages/lib-engine/src/actions/ExecuteCommand.ts b/packages/lib-engine/src/actions/ExecuteCommand.ts index 789b99dbb8..0f868ca9aa 100644 --- a/packages/lib-engine/src/actions/ExecuteCommand.ts +++ b/packages/lib-engine/src/actions/ExecuteCommand.ts @@ -11,7 +11,7 @@ import { CallbackAction } from "./CallbackAction"; * {@link ExecuteCommandOptions.restoreSelection restoreSelection} is `true`. Internally, most * of the heavy lifting is done by {@link CallbackAction}. */ -export default class ExecuteCommand { +export class ExecuteCommand { private callbackAction: CallbackAction; constructor( diff --git a/packages/lib-engine/src/actions/FollowLink.ts b/packages/lib-engine/src/actions/FollowLink.ts index 8f7cb83f65..b7c81a58c7 100644 --- a/packages/lib-engine/src/actions/FollowLink.ts +++ b/packages/lib-engine/src/actions/FollowLink.ts @@ -8,7 +8,7 @@ import { } from "../util/targetUtils"; import type { ActionReturnValue, SimpleAction } from "./actions.types"; -export default class FollowLink implements SimpleAction { +export class FollowLink implements SimpleAction { constructor( private ide: IDE, private options: OpenLinkOptions, diff --git a/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts b/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts index e457e19968..a30f423467 100644 --- a/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts +++ b/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts @@ -51,7 +51,7 @@ import type { Offsets } from "./Offsets"; * 8. Open a new document in the snippets dir to hold the new snippet. * 9. Insert the meta snippet so that the user can construct their snippet. */ -export default class GenerateSnippet { +export class GenerateSnippet { constructor( private ide: IDE, private snippets: Snippets, diff --git a/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts b/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts index 16b26c4b35..c18a649c94 100644 --- a/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts +++ b/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts @@ -14,7 +14,7 @@ interface Substitution { * on the final text to replace the random id's with the original strings you * desired. */ -export default class Substituter { +export class Substituter { private substitutions: Substitution[] = []; /** diff --git a/packages/lib-engine/src/actions/GenerateSnippet/index.ts b/packages/lib-engine/src/actions/GenerateSnippet/index.ts index 091a591452..8ed3a17201 100644 --- a/packages/lib-engine/src/actions/GenerateSnippet/index.ts +++ b/packages/lib-engine/src/actions/GenerateSnippet/index.ts @@ -1 +1 @@ -export { default } from "./GenerateSnippet"; +export { GenerateSnippet } from "./GenerateSnippet"; diff --git a/packages/lib-engine/src/actions/GetTargets.ts b/packages/lib-engine/src/actions/GetTargets.ts index 3039c06d1b..ce38234db4 100644 --- a/packages/lib-engine/src/actions/GetTargets.ts +++ b/packages/lib-engine/src/actions/GetTargets.ts @@ -1,7 +1,7 @@ import type { Target } from "../typings/target.types"; import type { ActionReturnValue, SimpleAction } from "./actions.types"; -export default class GetTargets implements SimpleAction { +export class GetTargets implements SimpleAction { constructor() { this.run = this.run.bind(this); } diff --git a/packages/lib-engine/src/actions/GetText.ts b/packages/lib-engine/src/actions/GetText.ts index 50c839182f..f368ad5460 100644 --- a/packages/lib-engine/src/actions/GetText.ts +++ b/packages/lib-engine/src/actions/GetText.ts @@ -4,7 +4,7 @@ import type { Target } from "../typings/target.types"; import { ensureSingleTarget, flashTargets } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class GetText { +export class GetText { constructor(private ide: IDE) { this.run = this.run.bind(this); } diff --git a/packages/lib-engine/src/actions/Highlight.ts b/packages/lib-engine/src/actions/Highlight.ts index d764a69918..cfbf389e18 100644 --- a/packages/lib-engine/src/actions/Highlight.ts +++ b/packages/lib-engine/src/actions/Highlight.ts @@ -6,7 +6,7 @@ import { } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class Highlight { +export class Highlight { constructor(private ide: IDE) { this.run = this.run.bind(this); } diff --git a/packages/lib-engine/src/actions/InsertSnippet.ts b/packages/lib-engine/src/actions/InsertSnippet.ts index 404a410747..16adc3f505 100644 --- a/packages/lib-engine/src/actions/InsertSnippet.ts +++ b/packages/lib-engine/src/actions/InsertSnippet.ts @@ -16,7 +16,7 @@ import { ensureSingleEditor } from "../util/targetUtils"; import type { Actions } from "./Actions"; import type { ActionReturnValue } from "./actions.types"; -export default class InsertSnippet { +export class InsertSnippet { private snippetParser = new SnippetParser(); constructor( diff --git a/packages/lib-engine/src/actions/JoinLines.ts b/packages/lib-engine/src/actions/JoinLines.ts index 2f89d84e7f..fc328ffab5 100644 --- a/packages/lib-engine/src/actions/JoinLines.ts +++ b/packages/lib-engine/src/actions/JoinLines.ts @@ -18,7 +18,7 @@ import { generateMatchesInRange } from "../util/getMatchesInRange"; import { flashTargets, runOnTargetsForEachEditor } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class JoinLines { +export class JoinLines { getFinalStages(): ModifierStage[] { return [this.modifierStageFactory.create(containingLineIfUntypedModifier)]; } diff --git a/packages/lib-engine/src/actions/Remove.ts b/packages/lib-engine/src/actions/Remove.ts index acf3a973e5..2631b03f4d 100644 --- a/packages/lib-engine/src/actions/Remove.ts +++ b/packages/lib-engine/src/actions/Remove.ts @@ -9,7 +9,7 @@ import { flashTargets, runOnTargetsForEachEditor } from "../util/targetUtils"; import { unifyRemovalTargets } from "../util/unifyRanges"; import type { ActionReturnValue, SimpleAction } from "./actions.types"; -export default class Delete implements SimpleAction { +class Delete implements SimpleAction { constructor( private ide: IDE, private rangeUpdater: RangeUpdater, @@ -65,3 +65,5 @@ export default class Delete implements SimpleAction { ); } } + +export { Delete as Remove }; diff --git a/packages/lib-engine/src/actions/Replace.ts b/packages/lib-engine/src/actions/Replace.ts index 4c6ef41605..5e15748daf 100644 --- a/packages/lib-engine/src/actions/Replace.ts +++ b/packages/lib-engine/src/actions/Replace.ts @@ -12,7 +12,7 @@ import type { SelectionWithEditor } from "../typings/Types"; import { flashTargets, runForEachEditor } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class Replace { +export class Replace { constructor( private ide: IDE, private rangeUpdater: RangeUpdater, diff --git a/packages/lib-engine/src/actions/Rewrap.ts b/packages/lib-engine/src/actions/Rewrap.ts index 5405e76e17..f3210efb2f 100644 --- a/packages/lib-engine/src/actions/Rewrap.ts +++ b/packages/lib-engine/src/actions/Rewrap.ts @@ -12,7 +12,7 @@ import { } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class Rewrap { +export class Rewrap { getFinalStages = () => [ getContainingSurroundingPairIfNoBoundaryStage(this.modifierStageFactory), ]; diff --git a/packages/lib-engine/src/actions/ShowParseTree.ts b/packages/lib-engine/src/actions/ShowParseTree.ts index 5d9998dc59..1098288a21 100644 --- a/packages/lib-engine/src/actions/ShowParseTree.ts +++ b/packages/lib-engine/src/actions/ShowParseTree.ts @@ -5,7 +5,7 @@ import type { Target } from "../typings/target.types"; import { flashTargets } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class InjectedShowParseTree { +class InjectedShowParseTree { constructor( private ide: IDE, private treeSitter: TreeSitter, @@ -33,6 +33,8 @@ export default class InjectedShowParseTree { } } +export { InjectedShowParseTree as ShowParseTree }; + function parseTree( document: TextDocument, tree: Tree, diff --git a/packages/lib-engine/src/actions/ToggleBreakpoint.ts b/packages/lib-engine/src/actions/ToggleBreakpoint.ts index aeb7975f80..4aec18ac2e 100644 --- a/packages/lib-engine/src/actions/ToggleBreakpoint.ts +++ b/packages/lib-engine/src/actions/ToggleBreakpoint.ts @@ -10,7 +10,7 @@ import { } from "../util/targetUtils"; import type { ActionReturnValue, SimpleAction } from "./actions.types"; -export default class ToggleBreakpoint implements SimpleAction { +export class ToggleBreakpoint implements SimpleAction { getFinalStages = () => [ this.modifierStageFactory.create(containingLineIfUntypedModifier), ]; diff --git a/packages/lib-engine/src/actions/Wrap.ts b/packages/lib-engine/src/actions/Wrap.ts index a617a5da06..f37cafecfe 100644 --- a/packages/lib-engine/src/actions/Wrap.ts +++ b/packages/lib-engine/src/actions/Wrap.ts @@ -11,7 +11,7 @@ import type { Target } from "../typings/target.types"; import { runOnTargetsForEachEditor } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class Wrap { +export class Wrap { constructor( private ide: IDE, private rangeUpdater: RangeUpdater, diff --git a/packages/lib-engine/src/actions/WrapWithSnippet.ts b/packages/lib-engine/src/actions/WrapWithSnippet.ts index b8c0c4bb27..9fd68ec9ef 100644 --- a/packages/lib-engine/src/actions/WrapWithSnippet.ts +++ b/packages/lib-engine/src/actions/WrapWithSnippet.ts @@ -12,7 +12,7 @@ import type { Target } from "../typings/target.types"; import { ensureSingleEditor, flashTargets } from "../util/targetUtils"; import type { ActionReturnValue } from "./actions.types"; -export default class WrapWithSnippet { +export class WrapWithSnippet { private snippetParser = new SnippetParser(); constructor( diff --git a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts index 1a242cc1d0..a92d180cc4 100644 --- a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts +++ b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts @@ -9,7 +9,7 @@ import type { } from "@cursorless/lib-common"; import { LATEST_VERSION, OutdatedExtensionError } from "@cursorless/lib-common"; import { getPartialTargetDescriptors } from "../../util/getPartialTargetDescriptors"; -import canonicalizeTargetsInPlace from "./canonicalizeTargetsInPlace"; +import { canonicalizeTargetsInPlace } from "./canonicalizeTargetsInPlace"; import { upgradeV0ToV1 } from "./upgradeV0ToV1"; import { upgradeV1ToV2 } from "./upgradeV1ToV2"; import { upgradeV2ToV3 } from "./upgradeV2ToV3"; diff --git a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeTargetsInPlace.ts b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeTargetsInPlace.ts index 7612880a75..86bedb5110 100644 --- a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeTargetsInPlace.ts +++ b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeTargetsInPlace.ts @@ -39,7 +39,7 @@ function canonicalizeColorsInPlace( } } -export default function canonicalizeTargetsInPlace( +export function canonicalizeTargetsInPlace( partialTargets: PartialTargetDescriptor[], ): void { getPartialPrimitiveTargets(partialTargets).forEach((target) => { diff --git a/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/canonicalizeActionName.ts b/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/canonicalizeActionName.ts index 7210e948ad..04c179fd67 100644 --- a/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/canonicalizeActionName.ts +++ b/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/canonicalizeActionName.ts @@ -30,7 +30,7 @@ const actionAliasToCanonicalName: Record = { wrap: "wrapWithPairedDelimiter", }; -export default function canonicalizeActionName(actionName: string) { +export function canonicalizeActionName(actionName: string) { const canonicalName = actionAliasToCanonicalName[actionName] ?? actionName; if (!actionNames.includes(canonicalName)) { diff --git a/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/upgradeV5ToV6.ts b/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/upgradeV5ToV6.ts index 3ae5d018b3..886a0dd528 100644 --- a/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/upgradeV5ToV6.ts +++ b/packages/lib-engine/src/core/commandVersionUpgrades/upgradeV5ToV6/upgradeV5ToV6.ts @@ -29,7 +29,7 @@ import type { ReplaceWith, WrapWithSnippetArg, } from "@cursorless/lib-common"; -import canonicalizeActionName from "./canonicalizeActionName"; +import { canonicalizeActionName } from "./canonicalizeActionName"; export function upgradeV5ToV6(command: CommandV5): EnforceUndefined { return { diff --git a/packages/lib-engine/src/core/updateSelections/getOffsetsForDeleteOrReplace.ts b/packages/lib-engine/src/core/updateSelections/getOffsetsForDeleteOrReplace.ts index cc99b3dfec..3bdb11e703 100644 --- a/packages/lib-engine/src/core/updateSelections/getOffsetsForDeleteOrReplace.ts +++ b/packages/lib-engine/src/core/updateSelections/getOffsetsForDeleteOrReplace.ts @@ -26,7 +26,7 @@ import type { * @param rangeInfo The range to compute new offsets for * @returns The new offsets for the given range */ -export default function getOffsetsForDeleteOrReplace( +export function getOffsetsForDeleteOrReplace( changeEventInfo: ChangeEventInfo, rangeInfo: FullRangeInfo, ): RangeOffsets { diff --git a/packages/lib-engine/src/core/updateSelections/getOffsetsForEmptyRangeInsert.ts b/packages/lib-engine/src/core/updateSelections/getOffsetsForEmptyRangeInsert.ts index ac3f225de0..519216dfe4 100644 --- a/packages/lib-engine/src/core/updateSelections/getOffsetsForEmptyRangeInsert.ts +++ b/packages/lib-engine/src/core/updateSelections/getOffsetsForEmptyRangeInsert.ts @@ -31,7 +31,7 @@ import type { * @param rangeInfo The range to compute new offsets for * @returns The new offsets for the given range */ -export default function getOffsetsForEmptyRangeInsert( +export function getOffsetsForEmptyRangeInsert( changeEventInfo: ChangeEventInfo, rangeInfo: FullRangeInfo, ): RangeOffsets { diff --git a/packages/lib-engine/src/core/updateSelections/getOffsetsForNonEmptyRangeInsert.ts b/packages/lib-engine/src/core/updateSelections/getOffsetsForNonEmptyRangeInsert.ts index 418ea4a89e..c22aaf78cb 100644 --- a/packages/lib-engine/src/core/updateSelections/getOffsetsForNonEmptyRangeInsert.ts +++ b/packages/lib-engine/src/core/updateSelections/getOffsetsForNonEmptyRangeInsert.ts @@ -31,7 +31,7 @@ import type { * @param rangeInfo The range to compute new offsets for * @returns The new offsets for the given range */ -export default function getOffsetsForNonEmptyRangeInsert( +export function getOffsetsForNonEmptyRangeInsert( changeEventInfo: ChangeEventInfo, rangeInfo: FullRangeInfo, ): RangeOffsets { diff --git a/packages/lib-engine/src/core/updateSelections/updateRangeInfos.ts b/packages/lib-engine/src/core/updateSelections/updateRangeInfos.ts index 7952b20e17..9dc23d83af 100644 --- a/packages/lib-engine/src/core/updateSelections/updateRangeInfos.ts +++ b/packages/lib-engine/src/core/updateSelections/updateRangeInfos.ts @@ -5,9 +5,9 @@ import type { FullRangeInfo, ChangeEventInfo, } from "../../typings/updateSelections"; -import getOffsetsForDeleteOrReplace from "./getOffsetsForDeleteOrReplace"; -import getOffsetsForEmptyRangeInsert from "./getOffsetsForEmptyRangeInsert"; -import getOffsetsForNonEmptyRangeInsert from "./getOffsetsForNonEmptyRangeInsert"; +import { getOffsetsForDeleteOrReplace } from "./getOffsetsForDeleteOrReplace"; +import { getOffsetsForEmptyRangeInsert } from "./getOffsetsForEmptyRangeInsert"; +import { getOffsetsForNonEmptyRangeInsert } from "./getOffsetsForNonEmptyRangeInsert"; import { getUpdatedText } from "./getUpdatedText"; /** diff --git a/packages/lib-engine/src/scripts/transformRecordedTests/moveFile.ts b/packages/lib-engine/src/scripts/transformRecordedTests/moveFile.ts index 1727ca19fe..904861e96c 100644 --- a/packages/lib-engine/src/scripts/transformRecordedTests/moveFile.ts +++ b/packages/lib-engine/src/scripts/transformRecordedTests/moveFile.ts @@ -8,7 +8,7 @@ import type { TestCaseFixture } from "@cursorless/lib-common"; * Can be used to organize files into directories based on eg language id * @param file The file to move */ -export default async function moveFile(file: string) { +export async function moveFile(file: string) { const buffer = await fsp.readFile(file); const inputFixture = yaml.load(buffer.toString()) as TestCaseFixture; const parent = path.dirname(file); diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimClipboard.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimClipboard.ts index 16ef08e6ce..123a6cc768 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimClipboard.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimClipboard.ts @@ -2,7 +2,7 @@ import type { NeovimClient } from "neovim"; import type { Clipboard } from "@cursorless/lib-common"; import { getClipboard, setClipboard } from "../../neovimApi"; -export default class NeovimClipboard implements Clipboard { +export class NeovimClipboard implements Clipboard { constructor(private client: NeovimClient) {} async readText(): Promise { diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimConfiguration.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimConfiguration.ts index c262dfa4bf..480c1e1b46 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimConfiguration.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimConfiguration.ts @@ -14,7 +14,7 @@ interface ConfigurationScopeValues { values: Partial; } -export default class NeovimConfiguration implements Configuration { +export class NeovimConfiguration implements Configuration { private notifier = new Notifier(); private mocks: CursorlessConfiguration = { ...CONFIGURATION_DEFAULTS, diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimEdit.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimEdit.ts index 5b935a244e..1fbbe2625a 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimEdit.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimEdit.ts @@ -9,7 +9,7 @@ import type { import { getNeovimRegistry } from "@cursorless/lib-neovim-registry"; import type { NeovimIDE } from "./NeovimIDE"; -export default async function neovimEdit( +export async function neovimEdit( client: NeovimClient, neovimIDE: NeovimIDE, window: Window, diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimIDE.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimIDE.ts index 7d1df9e579..4f17880259 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimIDE.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimIDE.ts @@ -33,14 +33,14 @@ import { windowGetVisibleRanges, } from "../../neovimApi"; import { NeovimCapabilities } from "./NeovimCapabilities"; -import NeovimClipboard from "./NeovimClipboard"; -import NeovimConfiguration from "./NeovimConfiguration"; +import { NeovimClipboard } from "./NeovimClipboard"; +import { NeovimConfiguration } from "./NeovimConfiguration"; import { neovimOnDidChangeTextDocument, neovimOnDidOpenTextDocument, } from "./NeovimEvents"; -import NeovimKeyValueStore from "./NeovimKeyValueStore"; -import NeovimMessages from "./NeovimMessages"; +import { NeovimKeyValueStore } from "./NeovimKeyValueStore"; +import { NeovimMessages } from "./NeovimMessages"; import { NeovimTextDocument } from "./NeovimTextDocument"; import { NeovimTextEditor } from "./NeovimTextEditor"; diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimKeyValueStore.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimKeyValueStore.ts index 4e0ca45fef..fcb4fbc9b4 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimKeyValueStore.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimKeyValueStore.ts @@ -5,7 +5,7 @@ import type { } from "@cursorless/lib-common"; import { KEY_VALUE_STORE_DEFAULTS } from "@cursorless/lib-common"; -export default class NeovimKeyValueStore implements KeyValueStore { +export class NeovimKeyValueStore implements KeyValueStore { private readonly data: KeyValueStoreData = { ...KEY_VALUE_STORE_DEFAULTS }; get(key: K): KeyValueStoreData[K] { diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimMessages.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimMessages.ts index 6d5dc41afe..7fdc4aaec6 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimMessages.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimMessages.ts @@ -1,6 +1,6 @@ import type { MessageId, Messages, MessageType } from "@cursorless/lib-common"; -export default class NeovimMessages implements Messages { +export class NeovimMessages implements Messages { showMessage( _type: MessageType, _id: MessageId, diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts index 17806e4c46..dd350609dc 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts @@ -2,7 +2,7 @@ import path from "node:path"; import type { URI } from "vscode-uri"; import type { EndOfLine, TextDocument, TextLine } from "@cursorless/lib-common"; import { Position, Range } from "@cursorless/lib-common"; -import NeovimTextLine from "./NeovimTextLine"; +import { NeovimTextLine } from "./NeovimTextLine"; export class NeovimTextDocument implements TextDocument { private _uri: URI; diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimTextEditor.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimTextEditor.ts index 7d2f45a56d..503d53c389 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimTextEditor.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimTextEditor.ts @@ -12,7 +12,7 @@ import type { } from "@cursorless/lib-common"; import { bufferSetSelections } from "../../neovimApi"; import { neovimClipboardCopy, neovimClipboardPaste } from "../../neovimHelpers"; -import neovimEdit from "./NeovimEdit"; +import { neovimEdit } from "./NeovimEdit"; import type { NeovimIDE } from "./NeovimIDE"; import type { NeovimTextDocument } from "./NeovimTextDocument"; diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimTextLine.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimTextLine.ts index 823125061c..78ab395129 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimTextLine.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimTextLine.ts @@ -1,7 +1,7 @@ import type { TextLine } from "@cursorless/lib-common"; import { Range } from "@cursorless/lib-common"; -export default class NeovimTextLine implements TextLine { +export class NeovimTextLine implements TextLine { private readonly _lineNumber: number; private readonly _text: string; private readonly _isLastLine: boolean; diff --git a/packages/lib-vscode-tutorial-webview/vite.config.ts b/packages/lib-vscode-tutorial-webview/vite.config.ts index 1281a918fd..26591a16d7 100644 --- a/packages/lib-vscode-tutorial-webview/vite.config.ts +++ b/packages/lib-vscode-tutorial-webview/vite.config.ts @@ -3,6 +3,7 @@ import type { UserConfig } from "vite"; import purgeCss from "vite-plugin-purgecss"; import { vitePreactAlias } from "@cursorless/lib-common/vite"; +// oxlint-disable-next-line import/no-default-export export default defineConfig((): UserConfig => { return { build: { diff --git a/packages/test-runner/src/runners/extensionTestsNeovim.ts b/packages/test-runner/src/runners/extensionTestsNeovim.ts index ac42e61467..ceae185b90 100644 --- a/packages/test-runner/src/runners/extensionTestsNeovim.ts +++ b/packages/test-runner/src/runners/extensionTestsNeovim.ts @@ -35,6 +35,7 @@ export async function run(plugin: NvimPlugin): Promise { * - Register the functions that are exposed to Neovim. * Note that these function need to start with a capital letter to be callable from Neovim. */ +// oxlint-disable-next-line import/no-default-export export default function entry(plugin: NvimPlugin) { plugin.registerFunction("TestRunnerRun", () => run(plugin), { sync: false, diff --git a/stylelint.config.mjs b/stylelint.config.mjs index aef29bc567..55cddfa45e 100644 --- a/stylelint.config.mjs +++ b/stylelint.config.mjs @@ -6,4 +6,5 @@ const config = { }, }; +// oxlint-disable-next-line import/no-default-export export default config; From 74806d82bfcb052fbfa9280a402c0edc278dc441 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 21:49:27 +0200 Subject: [PATCH 3/9] Enable unicorn/no-array-reduce --- oxlint.config.mts | 1 - packages/lib-common/src/util/uniqWithHash.ts | 17 +++++---- .../src/core/getPreferredSnippet.ts | 14 +++++--- .../getDelimiterOccurrences.ts | 14 ++++---- .../src/scopeProviders/getIterationRange.ts | 8 +++-- packages/lib-sentence-parser/src/sbd.ts | 35 +++++++++---------- 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index 0853a51b07..cb1b793af2 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -6,7 +6,6 @@ const temporarilyDisabled = [ "eslint/no-param-reassign", "eslint/prefer-template", "typescript/no-unsafe-type-assertion", - "unicorn/no-array-reduce", "react/rules-of-hooks", ]; diff --git a/packages/lib-common/src/util/uniqWithHash.ts b/packages/lib-common/src/util/uniqWithHash.ts index 5e01782395..fa689a7d65 100644 --- a/packages/lib-common/src/util/uniqWithHash.ts +++ b/packages/lib-common/src/util/uniqWithHash.ts @@ -28,20 +28,23 @@ export function uniqWithHash( /* Keep track of which sets have multiple items, so that we can uniq them. */ const needsUniq: string[] = []; - const hashToItems: Map = array.reduce((acc, item) => { + const hashToItems = new Map(); + + for (const item of array) { const key = hash(item); - const items = acc.get(key); + const items = hashToItems.get(key); + if (items == null) { - acc.set(key, [item]); - return acc; + hashToItems.set(key, [item]); + continue; } - acc.get(key)!.push(item); + items.push(item); + if (items.length === 2) { needsUniq.push(key); } - return acc; - }, new Map()); + } // Another common case: Everything is unique. if (needsUniq.length === 0) { diff --git a/packages/lib-engine/src/core/getPreferredSnippet.ts b/packages/lib-engine/src/core/getPreferredSnippet.ts index 8713200552..1958319227 100644 --- a/packages/lib-engine/src/core/getPreferredSnippet.ts +++ b/packages/lib-engine/src/core/getPreferredSnippet.ts @@ -91,12 +91,18 @@ function findSnippetWithFewestLanguages< } // Find the snippet with the fewest languages - return snippets.reduce((prev, curr) => { - if (prev.languages == null || curr.languages == null) { + let preferredSnippet = snippets[0]; + + for (const snippet of snippets.slice(1)) { + if (preferredSnippet.languages == null || snippet.languages == null) { throw new Error( "Snippet must have languages defined to find the one with the fewest languages", ); } - return curr.languages.length < prev.languages.length ? curr : prev; - }); + if (snippet.languages.length < preferredSnippet.languages.length) { + preferredSnippet = snippet; + } + } + + return preferredSnippet; } diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/getDelimiterOccurrences.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/getDelimiterOccurrences.ts index 5059528a14..c5f05cd3ca 100644 --- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/getDelimiterOccurrences.ts +++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/getDelimiterOccurrences.ts @@ -40,12 +40,14 @@ export function getDelimiterOccurrences( getSortedCaptures(capturesMap.textFragment), ); - const delimiterTextToDelimiterInfoMap = individualDelimiters.reduce< - Record - >((acc, individualDelimiter) => { - (acc[individualDelimiter.text] ??= []).push(individualDelimiter); - return acc; - }, {}); + const delimiterTextToDelimiterInfoMap: Record = + {}; + + for (const individualDelimiter of individualDelimiters) { + (delimiterTextToDelimiterInfoMap[individualDelimiter.text] ??= []).push( + individualDelimiter, + ); + } const regexMatches = matchAllIterator( document.getText(), diff --git a/packages/lib-engine/src/scopeProviders/getIterationRange.ts b/packages/lib-engine/src/scopeProviders/getIterationRange.ts index 9498792683..ba6af32843 100644 --- a/packages/lib-engine/src/scopeProviders/getIterationRange.ts +++ b/packages/lib-engine/src/scopeProviders/getIterationRange.ts @@ -25,9 +25,11 @@ export function getIterationRange( return editor.document.range; } - let visibleRange = editor.visibleRanges.reduce((acc, range) => - acc.union(range), - ); + let visibleRange = editor.visibleRanges[0]; + + for (const range of editor.visibleRanges.slice(1)) { + visibleRange = visibleRange.union(range); + } visibleRange = editor.document.range.intersection( visibleRange.with( diff --git a/packages/lib-sentence-parser/src/sbd.ts b/packages/lib-sentence-parser/src/sbd.ts index dd4c7f34e6..71a01139c2 100644 --- a/packages/lib-sentence-parser/src/sbd.ts +++ b/packages/lib-sentence-parser/src/sbd.ts @@ -206,27 +206,24 @@ export function getSentences( return s.length > 0; }); - const result = sentences.slice(1).reduce( - (out, sentence) => { - const lastSentence = out[out.length - 1]; - - // Single words, could be "enumeration lists" - if (lastSentence.length === 1 && /^.{1,2}[.]$/.test(lastSentence[0])) { - // Check if there is a next sentence - // It should not be another list item - if (!/[.]/.test(sentence[0])) { - out.pop(); - out.push(lastSentence.concat(sentence)); - return out; - } + const result = [sentences[0]]; + + for (const sentence of sentences.slice(1)) { + const lastSentence = result[result.length - 1]; + + // Single words, could be "enumeration lists" + if (lastSentence.length === 1 && /^.{1,2}[.]$/.test(lastSentence[0])) { + // Check if there is a next sentence + // It should not be another list item + if (!/[.]/.test(sentence[0])) { + result.pop(); + result.push(lastSentence.concat(sentence)); + continue; } + } - out.push(sentence); - - return out; - }, - [sentences[0]], - ); + result.push(sentence); + } // join tokens back together return result.map((sentence, ii) => { From 22d686f9fd98ff584e5a7a178e56422b1415ecd6 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:26:12 +0200 Subject: [PATCH 4/9] Added eslint/no-param-reassign --- oxlint.config.mts | 1 - .../app-vscode/src/ide/vscode/VscodeFold.ts | 4 +- .../src/keyboard/KeyboardCommandsTargeted.ts | 6 +- .../src/scripts/hatAdjustments/lib.ts | 4 +- .../src/tooling/viteHtmlParamsPlugin.ts | 9 ++- .../lib-engine/src/actions/BringMoveSwap.ts | 12 ++-- .../GenerateSnippet/GenerateSnippet.ts | 13 ++-- .../actions/GenerateSnippet/Substituter.ts | 5 +- packages/lib-engine/src/actions/Remove.ts | 6 +- packages/lib-engine/src/core/HatAllocator.ts | 4 +- .../canonicalizeAndValidateCommand.ts | 26 ++++---- .../queryPredicateOperators.ts | 20 +++--- .../processTargets/TargetPipelineRunner.ts | 12 ++-- .../SentenceScopeHandler/SentenceSegmenter.ts | 10 +-- .../processTargets/targets/ParagraphTarget.ts | 14 +++-- .../src/scopeProviders/ScopeRangeProvider.ts | 3 +- .../src/testUtil/serializeScopeFixture.ts | 8 +-- packages/lib-engine/src/util/rangeUtils.ts | 5 +- .../src/ide/neovim/NeovimTextDocument.ts | 62 ++++++++++--------- packages/lib-sentence-parser/src/Match.ts | 8 +-- packages/lib-sentence-parser/src/sbd.ts | 6 +- packages/lib-tutorial/src/TutorialImpl.ts | 11 ++-- packages/lib-tutorial/src/setupStep.ts | 5 +- .../CursorlessCommandComponentParser.ts | 31 +++++----- 24 files changed, 156 insertions(+), 129 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index cb1b793af2..ee6478533e 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -3,7 +3,6 @@ import { defineConfig } from "oxlint"; // These rules should probably be re-enabled eventually const temporarilyDisabled = [ - "eslint/no-param-reassign", "eslint/prefer-template", "typescript/no-unsafe-type-assertion", "react/rules-of-hooks", diff --git a/packages/app-vscode/src/ide/vscode/VscodeFold.ts b/packages/app-vscode/src/ide/vscode/VscodeFold.ts index 3786c954a8..58c7636686 100644 --- a/packages/app-vscode/src/ide/vscode/VscodeFold.ts +++ b/packages/app-vscode/src/ide/vscode/VscodeFold.ts @@ -22,10 +22,10 @@ export function vscodeUnfold( async function foldOrUnfold( ide: VscodeIDE, editor: VscodeTextEditor, - ranges: Range[] | undefined, + rangesIn: Range[] | undefined, command: "editor.fold" | "editor.unfold", ): Promise { - ranges = ranges ?? editor.selections; + let ranges = rangesIn ?? editor.selections; const singleLineRanges = ranges.filter((range) => range.isSingleLine); const multiLineRanges = ranges.filter((range) => !range.isSingleLine); diff --git a/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts b/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts index 3b3af38608..8749539ca9 100644 --- a/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts +++ b/packages/app-vscode/src/keyboard/KeyboardCommandsTargeted.ts @@ -73,11 +73,11 @@ export class KeyboardCommandsTargeted { targetDecoratedMark = async ({ color = "default", shape = "default", - character, + character: characterIn, mode = "replace", }: TargetDecoratedMarkArgument) => { - character = - character ?? + const character = + characterIn ?? (await this.keyboardHandler.awaitSingleKeypress({ cursorStyle: vscode.TextEditorCursorStyle.Underline, whenClauseContext: "cursorless.keyboard.targeted.awaitingHatCharacter", diff --git a/packages/app-vscode/src/scripts/hatAdjustments/lib.ts b/packages/app-vscode/src/scripts/hatAdjustments/lib.ts index ecd14ecc46..6a7d9a9ec7 100644 --- a/packages/app-vscode/src/scripts/hatAdjustments/lib.ts +++ b/packages/app-vscode/src/scripts/hatAdjustments/lib.ts @@ -1,4 +1,4 @@ export function postProcessValue(value: number) { - value = Math.round(value * 10_000) / 10_000; - return value === 0 ? undefined : value; + const roundedValue = Math.round(value * 10_000) / 10_000; + return roundedValue === 0 ? undefined : roundedValue; } diff --git a/packages/lib-common/src/tooling/viteHtmlParamsPlugin.ts b/packages/lib-common/src/tooling/viteHtmlParamsPlugin.ts index 0776a359c7..521973afe2 100644 --- a/packages/lib-common/src/tooling/viteHtmlParamsPlugin.ts +++ b/packages/lib-common/src/tooling/viteHtmlParamsPlugin.ts @@ -4,14 +4,17 @@ export function viteHtmlParams(params: Record) { enforce: "post", transformIndexHtml(html: string): string { + let output = html; + for (const [key, value] of Object.entries(params)) { const pattern = `__${key}__`; - if (!html.includes(pattern)) { + if (!output.includes(pattern)) { throw new Error(`Expected index.html to contain pattern ${pattern}`); } - html = html.replaceAll(pattern, value); + output = output.replaceAll(pattern, value); } - return html; + + return output; }, }; } diff --git a/packages/lib-engine/src/actions/BringMoveSwap.ts b/packages/lib-engine/src/actions/BringMoveSwap.ts index 07d8ec6fb4..ac5c7f2a71 100644 --- a/packages/lib-engine/src/actions/BringMoveSwap.ts +++ b/packages/lib-engine/src/actions/BringMoveSwap.ts @@ -287,14 +287,14 @@ export class Bring extends BringMoveSwap { sources: Target[], destinations: Destination[], ): Promise { - sources = broadcastSource(sources, destinations); + const broadcastSources = broadcastSource(sources, destinations); await this.decorateTargets( - sources, + broadcastSources, destinations.map((d) => d.target), ); - const edits = this.getEditsBringMove(sources, destinations); + const edits = this.getEditsBringMove(broadcastSources, destinations); const markEntries = await this.performEditsAndComputeThatMark(edits); @@ -322,14 +322,14 @@ export class Move extends BringMoveSwap { sources: Target[], destinations: Destination[], ): Promise { - sources = broadcastSource(sources, destinations); + const broadcastSources = broadcastSource(sources, destinations); await this.decorateTargets( - sources, + broadcastSources, destinations.map((d) => d.target), ); - const edits = this.getEditsBringMove(sources, destinations); + const edits = this.getEditsBringMove(broadcastSources, destinations); const markEntries = await this.performEditsAndComputeThatMark(edits); diff --git a/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts b/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts index a30f423467..bdb8e8949c 100644 --- a/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts +++ b/packages/lib-engine/src/actions/GenerateSnippet/GenerateSnippet.ts @@ -79,14 +79,16 @@ export class GenerateSnippet { // win the race and have the input box ready for them void flashTargets(this.ide, targets, FlashStyle.referenced); - if (snippetName == null) { - snippetName = await this.ide.showInputBox({ + let resolvedSnippetName = snippetName; + + if (resolvedSnippetName == null) { + resolvedSnippetName = await this.ide.showInputBox({ prompt: "Name of snippet", placeHolder: "helloWorld", }); // User cancelled; do nothing - if (!snippetName) { + if (!resolvedSnippetName) { return {}; } } @@ -146,7 +148,7 @@ export class GenerateSnippet { } else { // Otherwise, we create and open a new document for the snippet editableEditor = this.ide.getEditableTextEditor( - await this.snippets.openNewSnippetFile(snippetName, directory), + await this.snippets.openNewSnippetFile(resolvedSnippetName, directory), ); snippetFile = parseSnippetFile(editableEditor.document.getText()); } @@ -178,7 +180,8 @@ export class GenerateSnippet { }; const snippet: Snippet = { - name: header?.name === snippetName ? undefined : snippetName, + name: + header?.name === resolvedSnippetName ? undefined : resolvedSnippetName, phrases, languages: getSnippetLanguages(editor, header), body: snippetLines, diff --git a/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts b/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts index c18a649c94..65b485c4de 100644 --- a/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts +++ b/packages/lib-engine/src/actions/GenerateSnippet/Substituter.ts @@ -48,14 +48,15 @@ export class Substituter { * desired */ makeSubstitutions(text: string) { + let output = text; this.substitutions.forEach(({ to, randomId, isQuoted }) => { const from = isQuoted ? `"${randomId}"` : randomId; // NB: We use split / join instead of replace because the latter doesn't // handle dollar signs well - text = text.split(from).join(to); + output = output.split(from).join(to); }); - return text; + return output; } } diff --git a/packages/lib-engine/src/actions/Remove.ts b/packages/lib-engine/src/actions/Remove.ts index 2631b03f4d..2e6cb6f9d0 100644 --- a/packages/lib-engine/src/actions/Remove.ts +++ b/packages/lib-engine/src/actions/Remove.ts @@ -23,19 +23,19 @@ class Delete implements SimpleAction { { showDecorations = true } = {}, ): Promise { // Unify overlapping targets because of overlapping leading and trailing delimiters. - targets = unifyRemovalTargets(targets); + const unifiedTargets = unifyRemovalTargets(targets); if (showDecorations) { await flashTargets( this.ide, - targets, + unifiedTargets, FlashStyle.pendingDelete, (target) => target.getRemovalHighlightRange(), ); } const thatTargets = flatten( - await runOnTargetsForEachEditor(targets, this.runForEditor), + await runOnTargetsForEachEditor(unifiedTargets, this.runForEditor), ); return { thatTargets }; diff --git a/packages/lib-engine/src/core/HatAllocator.ts b/packages/lib-engine/src/core/HatAllocator.ts index ce8f71dcc8..efd1ce1f96 100644 --- a/packages/lib-engine/src/core/HatAllocator.ts +++ b/packages/lib-engine/src/core/HatAllocator.ts @@ -59,7 +59,7 @@ export class HatAllocator { const activeMap = await this.context.getActiveMap(); // Forced graphemes won't have been normalized - forceTokenHats = forceTokenHats?.map((tokenHat) => ({ + const normalizedForceTokenHats = forceTokenHats?.map((tokenHat) => ({ ...tokenHat, grapheme: this.tokenGraphemeSplitter.normalizeGrapheme(tokenHat.grapheme), })); @@ -69,7 +69,7 @@ export class HatAllocator { ide: this.ide, tokenGraphemeSplitter: this.tokenGraphemeSplitter, enabledHatStyles: this.hats.enabledHatStyles, - forceTokenHats, + forceTokenHats: normalizedForceTokenHats, oldTokenHats: activeMap.tokenHats, hatStability: this.ide.configuration.getOwnConfiguration( "experimental.hatStability", diff --git a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts index a92d180cc4..047c3f013b 100644 --- a/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts +++ b/packages/lib-engine/src/core/commandVersionUpgrades/canonicalizeAndValidateCommand.ts @@ -48,41 +48,43 @@ export function upgradeCommand( command: Command, minimumVersion: V, ): Command & { version: V } { - if (command.version > LATEST_VERSION) { + let upgradedCommand = command; + + if (upgradedCommand.version > LATEST_VERSION) { throw new OutdatedExtensionError(); } - while (command.version < minimumVersion) { - switch (command.version) { + while (upgradedCommand.version < minimumVersion) { + switch (upgradedCommand.version) { case 0: - command = upgradeV0ToV1(command); + upgradedCommand = upgradeV0ToV1(upgradedCommand); break; case 1: - command = upgradeV1ToV2(command); + upgradedCommand = upgradeV1ToV2(upgradedCommand); break; case 2: - command = upgradeV2ToV3(command); + upgradedCommand = upgradeV2ToV3(upgradedCommand); break; case 3: - command = upgradeV3ToV4(command); + upgradedCommand = upgradeV3ToV4(upgradedCommand); break; case 4: - command = upgradeV4ToV5(command); + upgradedCommand = upgradeV4ToV5(upgradedCommand); break; case 5: - command = upgradeV5ToV6(command); + upgradedCommand = upgradeV5ToV6(upgradedCommand); break; case 6: - command = upgradeV6ToV7(command); + upgradedCommand = upgradeV6ToV7(upgradedCommand); break; default: throw new Error( - `Can't upgrade from unknown version ${command.version}`, + `Can't upgrade from unknown version ${upgradedCommand.version}`, ); } } - return command as Command & { + return upgradedCommand as Command & { version: V; }; } diff --git a/packages/lib-engine/src/languages/TreeSitterQuery/queryPredicateOperators.ts b/packages/lib-engine/src/languages/TreeSitterQuery/queryPredicateOperators.ts index c003b692a1..0e742a8607 100644 --- a/packages/lib-engine/src/languages/TreeSitterQuery/queryPredicateOperators.ts +++ b/packages/lib-engine/src/languages/TreeSitterQuery/queryPredicateOperators.ts @@ -136,18 +136,24 @@ class ChildRange extends QueryPredicateOperator { run( capture: MutableQueryCapture, startIndex: number, - endIndex?: number, + endIndex = -1, excludeStart?: boolean, excludeEnd?: boolean, ) { const children = getNode(capture).children; + const start = children.at(startIndex); + const end = children.at(endIndex); - startIndex = startIndex < 0 ? children.length + startIndex : startIndex; - endIndex = endIndex == null ? -1 : endIndex; - endIndex = endIndex < 0 ? children.length + endIndex : endIndex; - - const start = children[startIndex]; - const end = children[endIndex]; + if (start == null) { + throw new Error( + `Start index ${startIndex} is out of bounds for node with ${children.length} children`, + ); + } + if (end == null) { + throw new Error( + `End index ${endIndex} is out of bounds for node with ${children.length} children`, + ); + } setRange( capture, diff --git a/packages/lib-engine/src/processTargets/TargetPipelineRunner.ts b/packages/lib-engine/src/processTargets/TargetPipelineRunner.ts index 780802530f..c23f308d07 100644 --- a/packages/lib-engine/src/processTargets/TargetPipelineRunner.ts +++ b/packages/lib-engine/src/processTargets/TargetPipelineRunner.ts @@ -314,12 +314,16 @@ export function processModifierStages( const options: ModifierStateOptions = { multipleTargets: targets.length > 1, }; - modifierStages.forEach((stage) => { - targets = targets.flatMap((target) => stage.run(target, options)); - }); + let currentTargets = targets; + + for (const stage of modifierStages) { + currentTargets = currentTargets.flatMap((target) => + stage.run(target, options), + ); + } // Then return the output from the final stage - return targets; + return currentTargets; } function getExcludedScope( diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SentenceScopeHandler/SentenceSegmenter.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SentenceScopeHandler/SentenceSegmenter.ts index 57191dd546..16575312e6 100644 --- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SentenceScopeHandler/SentenceSegmenter.ts +++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SentenceScopeHandler/SentenceSegmenter.ts @@ -48,6 +48,8 @@ function createSegment( sentence: string, index: number, ): MatchedText | undefined { + let segmentText = sentence; + let segmentIndex = index; const leadingOffsetMatch = matchRegex(leadingOffsetRegex, sentence); if (leadingOffsetMatch == null) { @@ -57,13 +59,13 @@ function createSegment( const leadingOffset = leadingOffsetMatch.index!; if (leadingOffset !== 0) { - index += leadingOffset; - sentence = sentence.slice(leadingOffset); + segmentIndex += leadingOffset; + segmentText = segmentText.slice(leadingOffset); } return { - text: sentence.trimEnd(), - index, + text: segmentText.trimEnd(), + index: segmentIndex, }; } diff --git a/packages/lib-engine/src/processTargets/targets/ParagraphTarget.ts b/packages/lib-engine/src/processTargets/targets/ParagraphTarget.ts index 44d95ec22d..eee4893370 100644 --- a/packages/lib-engine/src/processTargets/targets/ParagraphTarget.ts +++ b/packages/lib-engine/src/processTargets/targets/ParagraphTarget.ts @@ -140,23 +140,25 @@ function getTrailingDelimiterRange(editor: TextEditor, contentRange: Range) { } function getPreviousNonEmptyLine(document: TextDocument, line: TextLine) { - while (line.lineNumber > 0) { - const previousLine = document.lineAt(line.lineNumber - 1); + let currentLine = line; + while (currentLine.lineNumber > 0) { + const previousLine = document.lineAt(currentLine.lineNumber - 1); if (!previousLine.isEmptyOrWhitespace) { return previousLine; } - line = previousLine; + currentLine = previousLine; } return null; } function getNextNonEmptyLine(document: TextDocument, line: TextLine) { - while (line.lineNumber + 1 < document.lineCount) { - const nextLine = document.lineAt(line.lineNumber + 1); + let currentLine = line; + while (currentLine.lineNumber + 1 < document.lineCount) { + const nextLine = document.lineAt(currentLine.lineNumber + 1); if (!nextLine.isEmptyOrWhitespace) { return nextLine; } - line = nextLine; + currentLine = nextLine; } return null; } diff --git a/packages/lib-engine/src/scopeProviders/ScopeRangeProvider.ts b/packages/lib-engine/src/scopeProviders/ScopeRangeProvider.ts index 64f892a6da..7ae3457644 100644 --- a/packages/lib-engine/src/scopeProviders/ScopeRangeProvider.ts +++ b/packages/lib-engine/src/scopeProviders/ScopeRangeProvider.ts @@ -65,10 +65,11 @@ export class ScopeRangeProvider { // Need to have a non empty intersection with the scopes if (range.isEmpty) { const offset = editor.document.offsetAt(range.start); - range = new Range( + const targetRange = new Range( editor.document.positionAt(offset - 1), editor.document.positionAt(offset + 1), ); + return getScopeRanges(editor, scopeHandler, targetRange); } return getScopeRanges(editor, scopeHandler, range); diff --git a/packages/lib-engine/src/testUtil/serializeScopeFixture.ts b/packages/lib-engine/src/testUtil/serializeScopeFixture.ts index 1fd7e67347..53fed85019 100644 --- a/packages/lib-engine/src/testUtil/serializeScopeFixture.ts +++ b/packages/lib-engine/src/testUtil/serializeScopeFixture.ts @@ -72,9 +72,7 @@ function serializeScope( } // If we're going to add a target number we need a scope number as well. - if (scopeNumber == null) { - scopeNumber = 1; - } + const resolvedScopeNumber = scopeNumber ?? 1; // If we have multiple targets or the domain is not equal to the content range: add domain last return [ @@ -82,14 +80,14 @@ function serializeScope( serializeTarget({ codeLines, target, - scopeNumber, + scopeNumber: resolvedScopeNumber, targetNumber: index + 1, }), ), "", serializeHeader({ header: "Domain", - scopeNumber, + scopeNumber: resolvedScopeNumber, targetNumber: undefined, range: domain, }), diff --git a/packages/lib-engine/src/util/rangeUtils.ts b/packages/lib-engine/src/util/rangeUtils.ts index 71b82f2eb1..f547751aaf 100644 --- a/packages/lib-engine/src/util/rangeUtils.ts +++ b/packages/lib-engine/src/util/rangeUtils.ts @@ -64,10 +64,11 @@ export function strictlyContains( * Make union between range and additional optional ranges */ export function union(range: Range, ...unionWith: (Range | undefined)[]) { + let result = range; for (const r of unionWith) { if (r != null) { - range = range.union(r); + result = result.union(r); } } - return range; + return result; } diff --git a/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts b/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts index dd350609dc..0d256e079d 100644 --- a/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts +++ b/packages/lib-neovim-common/src/ide/neovim/NeovimTextDocument.ts @@ -93,19 +93,19 @@ export class NeovimTextDocument implements TextDocument { } public offsetAt(position: Position): number { - position = this._validatePosition(position); + const validatedPosition = this._validatePosition(position); this._ensureLineStarts(); return ( - this._lineStarts!.getPrefixSum(position.line - 1) + position.character + this._lineStarts!.getPrefixSum(validatedPosition.line - 1) + + validatedPosition.character ); } public positionAt(offset: number): Position { - offset = Math.floor(offset); - offset = Math.max(0, offset); + const normalizedOffset = Math.max(0, Math.floor(offset)); this._ensureLineStarts(); - const out = this._lineStarts!.getIndexOf(offset); + const out = this._lineStarts!.getIndexOf(normalizedOffset); const lineLength = this._lines[out.index].length; @@ -121,30 +121,32 @@ export class NeovimTextDocument implements TextDocument { return this._cachedTextValue; } - range = this._validateRange(range); + const validatedRange = this._validateRange(range); - if (range.isEmpty) { + if (validatedRange.isEmpty) { return ""; } - if (range.isSingleLine) { - return this._lines[range.start.line].slice( - range.start.character, - range.end.character, + if (validatedRange.isSingleLine) { + return this._lines[validatedRange.start.line].slice( + validatedRange.start.character, + validatedRange.end.character, ); } const lineEnding = this._eol, - startLineIndex = range.start.line, - endLineIndex = range.end.line, + startLineIndex = validatedRange.start.line, + endLineIndex = validatedRange.end.line, resultLines: string[] = [ - this._lines[startLineIndex].slice(range.start.character), + this._lines[startLineIndex].slice(validatedRange.start.character), ]; for (let i = startLineIndex + 1; i < endLineIndex; i++) { resultLines.push(this._lines[i]); } - resultLines.push(this._lines[endLineIndex].slice(0, range.end.character)); + resultLines.push( + this._lines[endLineIndex].slice(0, validatedRange.end.character), + ); return resultLines.join(lineEnding); } @@ -272,13 +274,14 @@ export class PrefixSumComputer { return 0; } - index = toUint32(index); - return this._getPrefixSum(index); + return this._getPrefixSum(toUint32(index)); } private _getPrefixSum(index: number): number { - if (index <= this.prefixSumValidIndex[0]) { - return this.prefixSum[index]; + const boundedIndex = Math.min(index, this.values.length - 1); + + if (boundedIndex <= this.prefixSumValidIndex[0]) { + return this.prefixSum[boundedIndex]; } let startIndex = this.prefixSumValidIndex[0] + 1; @@ -287,19 +290,18 @@ export class PrefixSumComputer { startIndex++; } - if (index >= this.values.length) { - index = this.values.length - 1; - } - - for (let i = startIndex; i <= index; i++) { + for (let i = startIndex; i <= boundedIndex; i++) { this.prefixSum[i] = this.prefixSum[i - 1] + this.values[i]; } - this.prefixSumValidIndex[0] = Math.max(this.prefixSumValidIndex[0], index); - return this.prefixSum[index]; + this.prefixSumValidIndex[0] = Math.max( + this.prefixSumValidIndex[0], + boundedIndex, + ); + return this.prefixSum[boundedIndex]; } public getIndexOf(sum: number): PrefixSumIndexOfResult { - sum = Math.floor(sum); + const normalizedSum = Math.floor(sum); // Compute all sums (to get a fully valid prefixSum) this.getTotalSum(); @@ -317,16 +319,16 @@ export class PrefixSumComputer { midStop = this.prefixSum[mid]; midStart = midStop - this.values[mid]; - if (sum < midStart) { + if (normalizedSum < midStart) { high = mid - 1; - } else if (sum >= midStop) { + } else if (normalizedSum >= midStop) { low = mid + 1; } else { break; } } - return new PrefixSumIndexOfResult(mid, sum - midStart); + return new PrefixSumIndexOfResult(mid, normalizedSum - midStart); } } diff --git a/packages/lib-sentence-parser/src/Match.ts b/packages/lib-sentence-parser/src/Match.ts index 0d33088e8c..cf695bc198 100644 --- a/packages/lib-sentence-parser/src/Match.ts +++ b/packages/lib-sentence-parser/src/Match.ts @@ -181,11 +181,9 @@ export function isNameAbbreviation(wordCount: number, words: string[]) { } export function isNumber(str: string, dotPos?: number) { - if (dotPos) { - str = str.slice(dotPos - 1, dotPos + 2); - } - - return !Number.isNaN(Number(str)); + const value = + dotPos != null && dotPos > 0 ? str.slice(dotPos - 1, dotPos + 2) : str; + return !Number.isNaN(Number(value)); } // Phone number matching diff --git a/packages/lib-sentence-parser/src/sbd.ts b/packages/lib-sentence-parser/src/sbd.ts index 71a01139c2..354e84aaed 100644 --- a/packages/lib-sentence-parser/src/sbd.ts +++ b/packages/lib-sentence-parser/src/sbd.ts @@ -23,13 +23,15 @@ const defaultOptions: SentenceParserOptions = { // Split the entry into sentences. export function getSentences( - text: string, + inputText: string, userOptions?: SentenceParserOptions, ) { - if (!text) { + if (!inputText) { return []; } + let text = inputText; + if (!whiteSpaceCheck.test(text)) { // whitespace-only string has no sentences return []; diff --git a/packages/lib-tutorial/src/TutorialImpl.ts b/packages/lib-tutorial/src/TutorialImpl.ts index dcdafa5bf2..ddfe2e1253 100644 --- a/packages/lib-tutorial/src/TutorialImpl.ts +++ b/packages/lib-tutorial/src/TutorialImpl.ts @@ -198,15 +198,16 @@ export class TutorialImpl implements Tutorial, CommandRunnerDecorator { } async start(tutorialId: TutorialId | number): Promise { - if (typeof tutorialId === "number") { - tutorialId = this.rawTutorials[tutorialId].id; - } + const resolvedTutorialId = + typeof tutorialId === "number" + ? this.rawTutorials[tutorialId].id + : tutorialId; const { tutorialContent, state } = await loadTutorial( this.contentProvider, - tutorialId, + resolvedTutorialId, this.customSpokenFormGenerator, - this.getRawTutorial(tutorialId), + this.getRawTutorial(resolvedTutorialId), this.ide.keyValueStore, this.hats, ); diff --git a/packages/lib-tutorial/src/setupStep.ts b/packages/lib-tutorial/src/setupStep.ts index 42b0032885..70581486c1 100644 --- a/packages/lib-tutorial/src/setupStep.ts +++ b/packages/lib-tutorial/src/setupStep.ts @@ -58,11 +58,12 @@ export async function setupStep( async function applySnapshot( ide: IDE, hatTokenMap: HatTokenMap, - editor: TextEditor | undefined, + editorIn: TextEditor | undefined, snapshot: TestCaseSnapshot, languageId: string, ): Promise { - const retry = editor != null; + const retry = editorIn != null; + let editor = editorIn; try { if (editor == null) { diff --git a/packages/lib-tutorial/src/stepComponentParsers/CursorlessCommandComponentParser.ts b/packages/lib-tutorial/src/stepComponentParsers/CursorlessCommandComponentParser.ts index ef7ad5631c..8e0e608faa 100644 --- a/packages/lib-tutorial/src/stepComponentParsers/CursorlessCommandComponentParser.ts +++ b/packages/lib-tutorial/src/stepComponentParsers/CursorlessCommandComponentParser.ts @@ -93,11 +93,11 @@ function substituteMissingHats( command: CommandLatest, initialState: TestCaseSnapshot, ) { - command = structuredClone(command); + const updatedCommand = structuredClone(command); // Update the hats in the command transformPartialPrimitiveTargets( - getPartialTargetDescriptors(command.action), + getPartialTargetDescriptors(updatedCommand.action), (target) => { if (target.mark?.type !== "decoratedSymbol") { return target; @@ -114,20 +114,21 @@ function substituteMissingHats( ); // Update the hats in the initial state snapshot - if (initialState.marks != null) { - initialState = produce(initialState, (draft) => { - draft.marks = mapKeys(draft.marks, (_value, key) => { - const { hatStyle, character } = splitKey(key); - if (enabledHatStyles[hatStyle] === undefined) { - return getKey(Object.keys(enabledHatStyles)[0], character); - } - return key; - }); - }); - } + const updatedInitialState = + initialState.marks != null + ? produce(initialState, (draft) => { + draft.marks = mapKeys(draft.marks, (_value, key) => { + const { hatStyle, character } = splitKey(key); + if (enabledHatStyles[hatStyle] === undefined) { + return getKey(Object.keys(enabledHatStyles)[0], character); + } + return key; + }); + }) + : initialState; return { - command, - initialState, + command: updatedCommand, + initialState: updatedInitialState, }; } From 77c539c7d529711a0440ccd751f6bd6db79560ac Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:40:51 +0200 Subject: [PATCH 5/9] Enable eslint/prefer-template --- oxlint.config.mts | 1 - packages/app-vscode/src/ScopeTreeProvider.ts | 2 +- .../grammar/getAcceptableTokenTypes.test.ts | 4 ++-- .../src/keyboard/grammar/keyboardLexer.ts | 2 +- .../app-web-docs/src/docs/components/Header.tsx | 4 +--- .../src/docs/contributing/MissingLanguageScopes.tsx | 2 +- .../src/lib/CheatsheetLegendSection.tsx | 2 +- .../src/lib/CheatsheetListSection.tsx | 2 +- packages/lib-common/src/testUtil/serialize.ts | 11 +++++++---- packages/lib-engine/src/actions/BreakLine.ts | 2 +- packages/lib-engine/src/actions/Call.ts | 2 +- .../lib-engine/src/actions/incrementDecrement.ts | 7 +++---- .../generateSpokenForm/generateSpokenForm.test.ts | 2 +- .../lib-engine/src/languages/LanguageDefinitions.ts | 3 +-- .../TreeSitterQuery/checkCaptureStartEnd.ts | 12 ++++++------ .../CollectionItemTextualScopeHandler.ts | 2 +- .../SurroundingPairScopeHandler.ts | 2 +- .../lib-engine/src/testUtil/serializeTargetRange.ts | 13 +++++++------ packages/lib-node-common/src/Cheatsheet.ts | 3 ++- .../src/FileSystemCommandHistoryStorage.ts | 2 +- 20 files changed, 40 insertions(+), 40 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index ee6478533e..de141ab148 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -3,7 +3,6 @@ import { defineConfig } from "oxlint"; // These rules should probably be re-enabled eventually const temporarilyDisabled = [ - "eslint/prefer-template", "typescript/no-unsafe-type-assertion", "react/rules-of-hooks", ]; diff --git a/packages/app-vscode/src/ScopeTreeProvider.ts b/packages/app-vscode/src/ScopeTreeProvider.ts index 9b2fce400c..761b418844 100644 --- a/packages/app-vscode/src/ScopeTreeProvider.ts +++ b/packages/app-vscode/src/ScopeTreeProvider.ts @@ -329,7 +329,7 @@ class ScopeSupportTreeItem extends TreeItem { getLanguageExtensionSampleFromLanguageId(languageId); if (fileExtension != null) { this.resourceUri = URI.parse( - "cursorless-dummy://dummy/dummy" + fileExtension, + `cursorless-dummy://dummy/dummy${fileExtension}`, ); } this.setUrl(languageId); diff --git a/packages/app-vscode/src/keyboard/grammar/getAcceptableTokenTypes.test.ts b/packages/app-vscode/src/keyboard/grammar/getAcceptableTokenTypes.test.ts index e10a2421f9..620aa99f11 100644 --- a/packages/app-vscode/src/keyboard/grammar/getAcceptableTokenTypes.test.ts +++ b/packages/app-vscode/src/keyboard/grammar/getAcceptableTokenTypes.test.ts @@ -153,10 +153,10 @@ suite("keyboard.getAcceptableTokenTypes", () => { arg: value.partialArg, }, }; + const json = JSON.stringify(candidates, null, 2); assert.ok( candidates.some((result) => isEqual(result, fullValue)), - "Relevant candidates (note that symbols will be missing):\n" + - JSON.stringify(candidates, null, 2), + `Relevant candidates (note that symbols will be missing):\n${json}`, ); } }); diff --git a/packages/app-vscode/src/keyboard/grammar/keyboardLexer.ts b/packages/app-vscode/src/keyboard/grammar/keyboardLexer.ts index 369103b117..000a6bfb35 100644 --- a/packages/app-vscode/src/keyboard/grammar/keyboardLexer.ts +++ b/packages/app-vscode/src/keyboard/grammar/keyboardLexer.ts @@ -42,7 +42,7 @@ class KeyboardLexer implements nearley.Lexer { } formatError(_token: any, message: string) { - return message + " at index " + (this.index - 1); + return `${message} at index ${this.index - 1}`; } has(_type: keyof TokenTypeKeyMapMap) { diff --git a/packages/app-web-docs/src/docs/components/Header.tsx b/packages/app-web-docs/src/docs/components/Header.tsx index 3b77324854..48ee80aae6 100644 --- a/packages/app-web-docs/src/docs/components/Header.tsx +++ b/packages/app-web-docs/src/docs/components/Header.tsx @@ -36,9 +36,7 @@ function renderHeader( {children} diff --git a/packages/app-web-docs/src/docs/contributing/MissingLanguageScopes.tsx b/packages/app-web-docs/src/docs/contributing/MissingLanguageScopes.tsx index 121ba936c9..9954541e70 100644 --- a/packages/app-web-docs/src/docs/contributing/MissingLanguageScopes.tsx +++ b/packages/app-web-docs/src/docs/contributing/MissingLanguageScopes.tsx @@ -108,7 +108,7 @@ function RenderFacets({ }; return ( -
+
setOpen(!open)}> {title} ({facets.length})
diff --git a/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx b/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx index e010be379b..7e8cf5de4a 100644 --- a/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx +++ b/packages/lib-cheatsheet/src/lib/CheatsheetLegendSection.tsx @@ -14,7 +14,7 @@ export function CheatsheetLegendSection({ data }: Props): JSX.Element { return (

Legend

diff --git a/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx b/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx index 82ef4488bb..5d8d33b1e0 100644 --- a/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx +++ b/packages/lib-cheatsheet/src/lib/CheatsheetListSection.tsx @@ -19,7 +19,7 @@ export function CheatsheetListSection({ section }: Props): JSX.Element { return (

{section.name}

diff --git a/packages/lib-common/src/testUtil/serialize.ts b/packages/lib-common/src/testUtil/serialize.ts index 2666ec7b4a..93cd00e3fd 100644 --- a/packages/lib-common/src/testUtil/serialize.ts +++ b/packages/lib-common/src/testUtil/serialize.ts @@ -59,8 +59,11 @@ function replacer(key: string, value: unknown): unknown { } export function serialize(obj: unknown): string { - return ( - new CustomDump(obj, { noRefs: true, quotingType: '"' }).represent().trim() + - "\n" - ); + const dump = new CustomDump(obj, { + noRefs: true, + quotingType: '"', + }) + .represent() + .trim(); + return `${dump}\n`; } diff --git a/packages/lib-engine/src/actions/BreakLine.ts b/packages/lib-engine/src/actions/BreakLine.ts index 484c6f7589..36071b3200 100644 --- a/packages/lib-engine/src/actions/BreakLine.ts +++ b/packages/lib-engine/src/actions/BreakLine.ts @@ -69,7 +69,7 @@ function getEdits(editor: TextEditor, contentRanges: Range[]): Edit[] { edits.push({ range: replacementRange, - text: "\n" + indentation, + text: `\n${indentation}`, isReplace: !replacementRange.isEmpty, }); } diff --git a/packages/lib-engine/src/actions/Call.ts b/packages/lib-engine/src/actions/Call.ts index 617bb43b53..4cc93bee27 100644 --- a/packages/lib-engine/src/actions/Call.ts +++ b/packages/lib-engine/src/actions/Call.ts @@ -17,7 +17,7 @@ export class Call { // NB: We unwrap and then rewrap the return value here so that we don't include the source mark const { thatSelections: thatMark } = - await this.actions.wrapWithPairedDelimiter.run(args, texts[0] + "(", ")"); + await this.actions.wrapWithPairedDelimiter.run(args, `${texts[0]}(`, ")"); return { thatSelections: thatMark }; } diff --git a/packages/lib-engine/src/actions/incrementDecrement.ts b/packages/lib-engine/src/actions/incrementDecrement.ts index 2aee04d293..f6e34b60d7 100644 --- a/packages/lib-engine/src/actions/incrementDecrement.ts +++ b/packages/lib-engine/src/actions/incrementDecrement.ts @@ -180,10 +180,9 @@ function formatNumberWithUnderscores( for (const match of underscoreMatches) { const index = match.index + offset; if (index < resultWithUnderscores.length) { - resultWithUnderscores = - resultWithUnderscores.slice(0, index) + - "_" + - resultWithUnderscores.slice(index); + const prefix = resultWithUnderscores.slice(0, index); + const suffix = resultWithUnderscores.slice(index); + resultWithUnderscores = `${prefix}_${suffix}`; } } diff --git a/packages/lib-engine/src/generateSpokenForm/generateSpokenForm.test.ts b/packages/lib-engine/src/generateSpokenForm/generateSpokenForm.test.ts index 0c8d5758ee..ff3cd662a9 100644 --- a/packages/lib-engine/src/generateSpokenForm/generateSpokenForm.test.ts +++ b/packages/lib-engine/src/generateSpokenForm/generateSpokenForm.test.ts @@ -80,7 +80,7 @@ async function runTest(file: string) { ); assert.ok(hatMapSpokenForm.type === "success"); assert.ok(hatMapSpokenForm.spokenForms.length === 1); - generatedSpokenForm.spokenForms[0] += " " + hatMapSpokenForm.spokenForms[0]; + generatedSpokenForm.spokenForms[0] += ` ${hatMapSpokenForm.spokenForms[0]}`; } if (shouldUpdateFixtures()) { diff --git a/packages/lib-engine/src/languages/LanguageDefinitions.ts b/packages/lib-engine/src/languages/LanguageDefinitions.ts index 03748ab883..9ee0f2276c 100644 --- a/packages/lib-engine/src/languages/LanguageDefinitions.ts +++ b/packages/lib-engine/src/languages/LanguageDefinitions.ts @@ -146,8 +146,7 @@ export class LanguageDefinitionsImpl implements LanguageDefinitions { if (definition == null) { throw new Error( - "Expected language definition entry is missing for languageId " + - languageId, + `Expected language definition entry is missing for languageId ${languageId}`, ); } diff --git a/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts b/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts index 9e9626d9c2..2ff97efeaf 100644 --- a/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts +++ b/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts @@ -61,9 +61,9 @@ export function checkCaptureStartEnd( void showError( messages, "TreeSitterQuery.checkCaptures.mixRegularStartEnd", - `Please do not mix regular captures and start/end captures: ${captures.map( - ({ name, range }) => name + " " + range.toString(), - )}`, + `Please do not mix regular captures and start/end captures: ${captures.map( + ({ name, range }) => `${name} ${range.toString()}`, + )}`, ); shownError = true; } @@ -73,9 +73,9 @@ export function checkCaptureStartEnd( void showError( messages, "TreeSitterQuery.checkCaptures.duplicate", - `A capture with the same name may only appear once in a single pattern: ${captures.map( - ({ name, range }) => name + " " + range.toString(), - )}`, + `A capture with the same name may only appear once in a single pattern: ${captures.map( + ({ name, range }) => `${name} ${range.toString()}`, + )}`, ); shownError = true; } diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemTextualScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemTextualScopeHandler.ts index f5162ecbba..ef102f2ae5 100644 --- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemTextualScopeHandler.ts +++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemTextualScopeHandler.ts @@ -45,7 +45,7 @@ export class CollectionItemTextualScopeHandler extends BaseScopeHandler { hints: ScopeIteratorRequirements, ): Iterable { const isEveryScope = isEveryScopeModifier(hints); - const cacheKey = "CollectionItemTextualScopeHandler_" + isEveryScope; + const cacheKey = `CollectionItemTextualScopeHandler_${isEveryScope}`; if (!scopeHandlerCache.isValid(cacheKey, editor.document)) { const scopes = this.getScopes(editor, isEveryScope); diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/SurroundingPairScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/SurroundingPairScopeHandler.ts index 45622d0a15..fdc45dbdbf 100644 --- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/SurroundingPairScopeHandler.ts +++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SurroundingPairScopeHandler/SurroundingPairScopeHandler.ts @@ -41,7 +41,7 @@ export class SurroundingPairScopeHandler extends BaseScopeHandler { direction: Direction, hints: ScopeIteratorRequirements, ): Iterable { - const cacheKey = "SurroundingPairScopeHandler_" + this.scopeType.delimiter; + const cacheKey = `SurroundingPairScopeHandler_${this.scopeType.delimiter}`; if (!scopeHandlerCache.isValid(cacheKey, editor.document)) { const delimiterOccurrences = getDelimiterOccurrences( diff --git a/packages/lib-engine/src/testUtil/serializeTargetRange.ts b/packages/lib-engine/src/testUtil/serializeTargetRange.ts index c6c3198134..05b4a68bed 100644 --- a/packages/lib-engine/src/testUtil/serializeTargetRange.ts +++ b/packages/lib-engine/src/testUtil/serializeTargetRange.ts @@ -38,13 +38,14 @@ export function serializeTargetRange( // Number of characters in the line number + `|` const startIndent = start.line.toString().length + 1; // Add start of range marker above the first code line - const prefix = " ".repeat(startIndent + start.character) + ">"; + const indent = " ".repeat(startIndent + start.character); + const prefix = `${indent}>`; if (range.isSingleLine) { - lines.push(prefix + "-".repeat(end.character - start.character) + "<"); + const dashLine = "-".repeat(end.character - start.character); + lines.push(`${prefix}${dashLine}<`); } else { - lines.push( - prefix + "-".repeat(codeLines[start.line].length - start.character), - ); + const dashLine = "-".repeat(codeLines[start.line].length - start.character); + lines.push(`${prefix}${dashLine}`); } // Output the range with each line prefixed by `n| `, eg: @@ -62,7 +63,7 @@ export function serializeTargetRange( if (!range.isSingleLine) { // Number of characters in the line number + `|` + whitespace const endIndent = end.line.toString().length + 2; - lines.push(" ".repeat(endIndent) + "-".repeat(end.character) + "<"); + lines.push(`${" ".repeat(endIndent)}${"-".repeat(end.character)}<`); } return lines.join("\n"); diff --git a/packages/lib-node-common/src/Cheatsheet.ts b/packages/lib-node-common/src/Cheatsheet.ts index 00b9606ffd..baac962a45 100644 --- a/packages/lib-node-common/src/Cheatsheet.ts +++ b/packages/lib-node-common/src/Cheatsheet.ts @@ -65,7 +65,8 @@ export async function updateDefaults(spokenFormInfo: CheatsheetInfo) { }); }); - await writeFile(defaultsPath, JSON.stringify(outputObject, null, 2) + "\n"); + const json = JSON.stringify(outputObject, null, 2); + await writeFile(defaultsPath, `${json}\n`); } // FIXME: Stop duplicating these types once we have #945 diff --git a/packages/lib-node-common/src/FileSystemCommandHistoryStorage.ts b/packages/lib-node-common/src/FileSystemCommandHistoryStorage.ts index 2802ab8c06..2e2a5bfe5f 100644 --- a/packages/lib-node-common/src/FileSystemCommandHistoryStorage.ts +++ b/packages/lib-node-common/src/FileSystemCommandHistoryStorage.ts @@ -13,7 +13,7 @@ export class FileSystemCommandHistoryStorage implements CommandHistoryStorage { fileName: string, entry: CommandHistoryEntry, ): Promise { - const data = JSON.stringify(entry) + "\n"; + const data = `${JSON.stringify(entry)}\n`; const file = path.join(this.dir, fileName); await fs.mkdir(this.dir, { recursive: true }); await fs.appendFile(file, data, "utf8"); From 8045ee1285119d2b420723e80971e22012a52650 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:48:07 +0200 Subject: [PATCH 6/9] Enable react/rules-of-hooks --- oxlint.config.mts | 30 +++++++++++-------- .../test-neovim-e2e/src/endToEndTestSetup.ts | 2 +- .../test-vscode-e2e/src/endToEndTestSetup.ts | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index de141ab148..87f4370704 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -2,10 +2,7 @@ import type { OxlintConfig } from "oxlint"; import { defineConfig } from "oxlint"; // These rules should probably be re-enabled eventually -const temporarilyDisabled = [ - "typescript/no-unsafe-type-assertion", - "react/rules-of-hooks", -]; +const temporarilyDisabled = ["typescript/no-unsafe-type-assertion"]; const disabledRules = [ ...temporarilyDisabled, @@ -187,6 +184,11 @@ export default defineConfig({ }, overrides: [ + { + files: ["**/*.{ts,cts,mts,tsx}"], + plugins: [...plugins, "typescript"], + }, + { files: ["**/*.js"], rules: { @@ -195,8 +197,17 @@ export default defineConfig({ }, { - files: ["**/*.{ts,cts,mts,tsx}"], - plugins: [...plugins, "typescript"], + files: ["**/*.ts"], + rules: { + "react/rules-of-hooks": "off", + }, + }, + + { + files: ["**/*.test.ts"], + rules: { + "eslint/func-names": "off", + }, }, { @@ -235,13 +246,6 @@ export default defineConfig({ }, }, - { - files: ["*.test.ts", "endToEndTestSetup.ts"], - rules: { - "eslint/func-names": "off", - }, - }, - { files: ["packages/lib-common/src/types/command/**/*.ts"], rules: { diff --git a/packages/test-neovim-e2e/src/endToEndTestSetup.ts b/packages/test-neovim-e2e/src/endToEndTestSetup.ts index 385c0e17f6..c3b49898be 100644 --- a/packages/test-neovim-e2e/src/endToEndTestSetup.ts +++ b/packages/test-neovim-e2e/src/endToEndTestSetup.ts @@ -30,7 +30,7 @@ export function endToEndTestSetup(suite: Mocha.Suite) { let spy: SpyIDE | undefined; let neovimIDE: NeovimIDE; - setup(function (this: Context) { + setup(function endToEndTestSetupInner(this: Context) { const title = this.test!.fullTitle(); retryCount = title === previousTestTitle ? retryCount + 1 : 0; previousTestTitle = title; diff --git a/packages/test-vscode-e2e/src/endToEndTestSetup.ts b/packages/test-vscode-e2e/src/endToEndTestSetup.ts index 9765006f2e..30286a37c8 100644 --- a/packages/test-vscode-e2e/src/endToEndTestSetup.ts +++ b/packages/test-vscode-e2e/src/endToEndTestSetup.ts @@ -36,7 +36,7 @@ export function endToEndTestSetup( let injectIde: (ide: IDE) => void; let spyIde: SpyIDE | undefined; - setup(async function (this: Context) { + setup(async function endToEndTestSetupInner(this: Context) { const title = this.test!.fullTitle(); retryCount = title === previousTestTitle ? retryCount + 1 : 0; previousTestTitle = title; From a0c4719e0af9cd5ed5a730868468bd65df52f5c7 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:49:06 +0200 Subject: [PATCH 7/9] Enable typescript/no-unsafe-type-assertion --- oxlint.config.mts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index 87f4370704..2f89b0d7ce 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -1,11 +1,7 @@ import type { OxlintConfig } from "oxlint"; import { defineConfig } from "oxlint"; -// These rules should probably be re-enabled eventually -const temporarilyDisabled = ["typescript/no-unsafe-type-assertion"]; - const disabledRules = [ - ...temporarilyDisabled, "eslint/arrow-body-style", "eslint/capitalized-comments", "eslint/class-methods-use-this", From c5b24b837092e957c0edd3ee4f888083ecfd5fa3 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:52:15 +0200 Subject: [PATCH 8/9] Small clean up --- oxlint.config.mts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/oxlint.config.mts b/oxlint.config.mts index 2f89b0d7ce..0dc1cf779e 100644 --- a/oxlint.config.mts +++ b/oxlint.config.mts @@ -1,7 +1,15 @@ import type { OxlintConfig } from "oxlint"; import { defineConfig } from "oxlint"; +// These rules should probably be re-enabled eventually +const temporarilyDisabledRules = [ + "unicorn/no-array-for-each", + "unicorn/no-array-reverse", + "unicorn/no-array-sort", +]; + const disabledRules = [ + ...temporarilyDisabledRules, "eslint/arrow-body-style", "eslint/capitalized-comments", "eslint/class-methods-use-this", @@ -59,9 +67,6 @@ const disabledRules = [ "typescript/strict-void-return", "unicorn/filename-case", "unicorn/no-array-callback-reference", - "unicorn/no-array-for-each", - "unicorn/no-array-reverse", - "unicorn/no-array-sort", "unicorn/no-lonely-if", "unicorn/no-null", "unicorn/no-object-as-default-parameter", From 55aaf255e8011b5e21f4b40f00b72acd2b767f9d Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 23 Apr 2026 22:53:49 +0200 Subject: [PATCH 9/9] format --- .../TreeSitterQuery/checkCaptureStartEnd.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts b/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts index 2ff97efeaf..dfbc18db5c 100644 --- a/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts +++ b/packages/lib-engine/src/languages/TreeSitterQuery/checkCaptureStartEnd.ts @@ -61,9 +61,9 @@ export function checkCaptureStartEnd( void showError( messages, "TreeSitterQuery.checkCaptures.mixRegularStartEnd", - `Please do not mix regular captures and start/end captures: ${captures.map( - ({ name, range }) => `${name} ${range.toString()}`, - )}`, + `Please do not mix regular captures and start/end captures: ${captures.map( + ({ name, range }) => `${name} ${range.toString()}`, + )}`, ); shownError = true; } @@ -73,9 +73,9 @@ export function checkCaptureStartEnd( void showError( messages, "TreeSitterQuery.checkCaptures.duplicate", - `A capture with the same name may only appear once in a single pattern: ${captures.map( - ({ name, range }) => `${name} ${range.toString()}`, - )}`, + `A capture with the same name may only appear once in a single pattern: ${captures.map( + ({ name, range }) => `${name} ${range.toString()}`, + )}`, ); shownError = true; }