From 7088347040c7bb9526449e38d2f023ee186528c5 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 11:04:33 +0100 Subject: [PATCH 1/2] remove commented code --- .../transformRecordedTests/moveFile.ts | 1 - .../{TestEditor.ts => TestTextEditor.ts} | 2 +- .../src/testUtil/createTestEnvironment.ts | 4 +- .../src/ide/TalonJsIDE.ts | 4 +- ...{TalonJsEditor.ts => TalonJsTextEditor.ts} | 2 +- .../src/ide/createTextEditor.ts | 13 +++-- .../src/suite/recorded.neovim.test.ts | 4 +- .../VscodeFancyRangeHighlighter.ts | 4 +- .../VscodeFancyRangeHighlighterRenderer.ts | 4 +- .../VscodeIterationScopeVisualizer.ts | 4 +- .../VscodeScopeRenderer.ts | 4 +- .../VscodeScopeTargetVisualizer.ts | 4 +- .../src/ide/vscode/VscodeEvents.ts | 4 +- .../src/ide/vscode/VscodeFileSystem.ts | 1 - .../src/ide/vscode/VscodeFocusEditor.ts | 6 +-- .../src/ide/vscode/VscodeFold.ts | 8 +-- .../src/ide/vscode/VscodeHighlights.ts | 4 +- .../src/ide/vscode/VscodeIDE.ts | 25 +++++----- .../src/ide/vscode/VscodeIdeNotebook.ts | 4 +- .../src/ide/vscode/VscodeInsertSnippets.ts | 4 +- .../src/ide/vscode/VscodeOpenLink.ts | 6 +-- .../src/ide/vscode/VscodeRevealLine.ts | 4 +- ...tDocumentImpl.ts => VscodeTextDocument.ts} | 6 +-- ...eTextEditorImpl.ts => VscodeTextEditor.ts} | 6 +-- ...scodeTextLineImpl.ts => VscodeTextLine.ts} | 2 +- .../src/ide/vscode/VscodeToggleBreakpoint.ts | 4 +- .../src/ide/vscode/hats/VscodeHats.ts | 4 +- .../src/ide/vscode/textLine.vscode.test.ts | 4 +- .../src/ide/vscode/toVscodeEditor.ts | 4 +- packages/neovim-common/src/getExtensionApi.ts | 19 ------- .../src/ide/neovim/NeovimEdit.ts | 9 ---- .../neovim-common/src/ide/neovim/NeovimIDE.ts | 29 +++++------ ...tDocumentImpl.ts => NeovimTextDocument.ts} | 49 ++----------------- ...mTextEditorImpl.ts => NeovimTextEditor.ts} | 14 +++--- ...eovimTextLineImpl.ts => NeovimTextLine.ts} | 17 +------ packages/neovim-common/src/index.ts | 6 +-- packages/neovim-common/src/neovimApi.ts | 2 - packages/neovim-common/src/neovimHelpers.ts | 4 +- .../src/testUtil/openNewEditor.ts | 8 +-- 39 files changed, 105 insertions(+), 198 deletions(-) rename packages/cursorless-engine/src/testUtil/{TestEditor.ts => TestTextEditor.ts} (98%) rename packages/cursorless-everywhere-talon-core/src/ide/{TalonJsEditor.ts => TalonJsTextEditor.ts} (98%) rename packages/cursorless-vscode/src/ide/vscode/{VscodeTextDocumentImpl.ts => VscodeTextDocument.ts} (91%) rename packages/cursorless-vscode/src/ide/vscode/{VscodeTextEditorImpl.ts => VscodeTextEditor.ts} (97%) rename packages/cursorless-vscode/src/ide/vscode/{VscodeTextLineImpl.ts => VscodeTextLine.ts} (94%) rename packages/neovim-common/src/ide/neovim/{NeovimTextDocumentImpl.ts => NeovimTextDocument.ts} (81%) rename packages/neovim-common/src/ide/neovim/{NeovimTextEditorImpl.ts => NeovimTextEditor.ts} (94%) rename packages/neovim-common/src/ide/neovim/{NeovimTextLineImpl.ts => NeovimTextLine.ts} (59%) diff --git a/packages/cursorless-engine/src/scripts/transformRecordedTests/moveFile.ts b/packages/cursorless-engine/src/scripts/transformRecordedTests/moveFile.ts index 8a00c41440..d54c18aa04 100644 --- a/packages/cursorless-engine/src/scripts/transformRecordedTests/moveFile.ts +++ b/packages/cursorless-engine/src/scripts/transformRecordedTests/moveFile.ts @@ -22,6 +22,5 @@ export default async function moveFile(file: string) { const childDir = path.join(parent, childDirName); await mkdir(childDir, { recursive: true }); const outputPath = path.join(childDir, path.basename(file)); - // console.log(`${file} => ${outputPath}`); await rename(file, outputPath); } diff --git a/packages/cursorless-engine/src/testUtil/TestEditor.ts b/packages/cursorless-engine/src/testUtil/TestTextEditor.ts similarity index 98% rename from packages/cursorless-engine/src/testUtil/TestEditor.ts rename to packages/cursorless-engine/src/testUtil/TestTextEditor.ts index 4e13e55164..5fe91765c6 100644 --- a/packages/cursorless-engine/src/testUtil/TestEditor.ts +++ b/packages/cursorless-engine/src/testUtil/TestTextEditor.ts @@ -12,7 +12,7 @@ import type { TextEditorOptions, } from "@cursorless/common"; -export class TestEditor implements EditableTextEditor { +export class TestTextEditor implements EditableTextEditor { options: TextEditorOptions = { tabSize: 4, insertSpaces: true, diff --git a/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts b/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts index 07f46ff94c..da06d0b926 100644 --- a/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts +++ b/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts @@ -9,7 +9,7 @@ import { FakeIDE, InMemoryTextDocument, Selection } from "@cursorless/common"; import { FileSystemRawTreeSitterQueryProvider } from "@cursorless/node-common"; import { URI } from "vscode-uri"; import { createCursorlessEngine } from ".."; -import { TestEditor } from "./TestEditor"; +import { TestTextEditor } from "./TestTextEditor"; import { TestFileSystem } from "./TestFileSystem"; import { TestTreeSitter } from "./TestTreeSitter"; @@ -58,7 +58,7 @@ function createNewEditor( const document = new InMemoryTextDocument(uri, languageId, content); const visibleRanges = [document.range]; const selections = [new Selection(0, 0, 0, 0)]; - const editor = new TestEditor(id, document, visibleRanges, selections); + const editor = new TestTextEditor(id, document, visibleRanges, selections); return editor; } diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts index f98d104789..c6d5bfb206 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts @@ -31,7 +31,7 @@ import { flashRanges } from "./flashRanges"; import { TalonJsCapabilities } from "./TalonJsCapabilities"; import { TalonJsClipboard } from "./TalonJsClipboard"; import { TalonJsConfiguration } from "./TalonJsConfiguration"; -import { TalonJsEditor } from "./TalonJsEditor"; +import { TalonJsTextEditor } from "./TalonJsTextEditor"; import { TalonJsKeyValueStore } from "./TalonJsKeyValueStore"; import { TalonJsMessages } from "./TalonJsMessages"; @@ -87,7 +87,7 @@ export class TalonJsIDE implements IDE { } getEditableTextEditor(editor: TextEditor): EditableTextEditor { - if (editor instanceof TalonJsEditor) { + if (editor instanceof TalonJsTextEditor) { return editor; } throw Error(`Unsupported text editor type: ${editor}`); diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts similarity index 98% rename from packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts rename to packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts index 9dcac1e9c2..a0fb6b3570 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsEditor.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts @@ -17,7 +17,7 @@ import { setSelections } from "./setSelections"; import type { TalonJsIDE } from "./TalonJsIDE"; import { talonJsPerformEdits } from "./talonJsPerformEdits"; -export class TalonJsEditor implements EditableTextEditor { +export class TalonJsTextEditor implements EditableTextEditor { options: TextEditorOptions = { tabSize: 4, insertSpaces: true, diff --git a/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts b/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts index 7eb632ad7b..2b59ed631e 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts @@ -3,7 +3,7 @@ import { InMemoryTextDocument, Selection } from "@cursorless/common"; import { URI } from "vscode-uri"; import type { Talon } from "../types/talon.types"; import type { EditorState, SelectionOffsets } from "../types/types"; -import { TalonJsEditor } from "./TalonJsEditor"; +import { TalonJsTextEditor } from "./TalonJsTextEditor"; import type { TalonJsIDE } from "./TalonJsIDE"; let nextId = 0; @@ -12,7 +12,7 @@ export function createTextEditor( talon: Talon, ide: TalonJsIDE, editorState: EditorState, -): TalonJsEditor { +): TalonJsTextEditor { const id = String(nextId++); const uri = URI.parse(`talon-js://${id}`); const languageId = editorState.languageId ?? "plaintext"; @@ -22,7 +22,14 @@ export function createTextEditor( createSelection(document, selection), ); - return new TalonJsEditor(talon, ide, id, document, visibleRanges, selections); + return new TalonJsTextEditor( + talon, + ide, + id, + document, + visibleRanges, + selections, + ); } export function createSelection( diff --git a/packages/cursorless-neovim-e2e/src/suite/recorded.neovim.test.ts b/packages/cursorless-neovim-e2e/src/suite/recorded.neovim.test.ts index fcbd5b62d3..96bc4542c3 100644 --- a/packages/cursorless-neovim-e2e/src/suite/recorded.neovim.test.ts +++ b/packages/cursorless-neovim-e2e/src/suite/recorded.neovim.test.ts @@ -3,7 +3,7 @@ import { asyncSafety } from "@cursorless/common"; import { getRecordedTestPaths, runRecordedTest } from "@cursorless/node-common"; import type { NeovimIDE, - NeovimTextEditorImpl, + NeovimTextEditor, NewEditorOptions, } from "@cursorless/neovim-common"; import { @@ -64,7 +64,7 @@ async function openNewTestEditor( neovimIDE: NeovimIDE, content: string, { openBeside = false }: NewEditorOptions = {}, -): Promise { +): Promise { // open a new buffer // @see: https://vi.stackexchange.com/questions/8345/a-built-in-way-to-make-vim-open-a-new-buffer-with-file await client.command(":enew"); diff --git a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts index d53c0bb1d4..a2ed5ca91c 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighter.ts @@ -6,7 +6,7 @@ import { } from "@cursorless/common"; import { flatmap } from "itertools"; import { range as lodashRange } from "lodash-es"; -import type { VscodeTextEditorImpl } from "../../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../../VscodeTextEditor"; import type { RangeTypeColors } from "../RangeTypeColors"; import { VscodeFancyRangeHighlighterRenderer } from "./VscodeFancyRangeHighlighterRenderer"; import type { DifferentiatedStyledRange } from "./decorationStyle.types"; @@ -31,7 +31,7 @@ export class VscodeFancyRangeHighlighter { this.renderer = new VscodeFancyRangeHighlighterRenderer(colors); } - setRanges(editor: VscodeTextEditorImpl, ranges: GeneralizedRange[]) { + setRanges(editor: VscodeTextEditor, ranges: GeneralizedRange[]) { const decoratedRanges: Iterable = flatmap( // We first generate a list of differentiated ranges, which are ranges // where any ranges that are touching have different differentiation diff --git a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighterRenderer.ts b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighterRenderer.ts index 8d36fee6d6..aeb2d188ab 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighterRenderer.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeFancyRangeHighlighter/VscodeFancyRangeHighlighterRenderer.ts @@ -10,7 +10,7 @@ import { toVscodeRange } from "@cursorless/vscode-common"; import type { DecorationRenderOptions, TextEditorDecorationType } from "vscode"; import { DecorationRangeBehavior } from "vscode"; import { vscodeApi } from "../../../../vscodeApi"; -import type { VscodeTextEditorImpl } from "../../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../../VscodeTextEditor"; import type { RangeTypeColors } from "../RangeTypeColors"; import type { DifferentiatedStyle, @@ -47,7 +47,7 @@ export class VscodeFancyRangeHighlighterRenderer { * which looks bad. */ setRanges( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, decoratedRanges: DifferentiatedStyledRangeList[], ): void { /** diff --git a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeIterationScopeVisualizer.ts b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeIterationScopeVisualizer.ts index d8b25979d7..e497d9e7ea 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeIterationScopeVisualizer.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeIterationScopeVisualizer.ts @@ -1,6 +1,6 @@ import type { Disposable, ScopeSupport, TextEditor } from "@cursorless/common"; import { toCharacterRange } from "@cursorless/common"; -import type { VscodeTextEditorImpl } from "../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../VscodeTextEditor"; import { VscodeScopeVisualizer } from "./VscodeScopeVisualizer"; export class VscodeIterationScopeVisualizer extends VscodeScopeVisualizer { @@ -12,7 +12,7 @@ export class VscodeIterationScopeVisualizer extends VscodeScopeVisualizer { return this.scopeProvider.onDidChangeIterationScopeRanges( (editor, iterationScopeRanges) => { this.renderer.setScopes( - editor as VscodeTextEditorImpl, + editor as VscodeTextEditor, iterationScopeRanges.map(({ domain, ranges }) => ({ domain: toCharacterRange(domain), nestedRanges: ranges.map(({ range }) => toCharacterRange(range)), diff --git a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeRenderer.ts b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeRenderer.ts index fbba4bfc96..cc5dcdada6 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeRenderer.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeRenderer.ts @@ -1,6 +1,6 @@ import type { Disposable, GeneralizedRange } from "@cursorless/common"; import { isGeneralizedRangeEqual } from "@cursorless/common"; -import type { VscodeTextEditorImpl } from "../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../VscodeTextEditor"; import type { RangeTypeColors } from "./RangeTypeColors"; import { VscodeFancyRangeHighlighter } from "./VscodeFancyRangeHighlighter"; import { blendRangeTypeColors } from "./blendRangeTypeColors"; @@ -38,7 +38,7 @@ export class VscodeScopeRenderer implements Disposable { ); } - setScopes(editor: VscodeTextEditorImpl, scopes: RendererScope[]) { + setScopes(editor: VscodeTextEditor, scopes: RendererScope[]) { const domainRanges: GeneralizedRange[] = []; const allNestedRanges: GeneralizedRange[] = []; const domainEqualsNestedRanges: GeneralizedRange[] = []; diff --git a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeTargetVisualizer.ts b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeTargetVisualizer.ts index 4105a3cc7a..0ca38f1529 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeTargetVisualizer.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VSCodeScopeVisualizer/VscodeScopeTargetVisualizer.ts @@ -7,7 +7,7 @@ import type { } from "@cursorless/common"; import { toCharacterRange } from "@cursorless/common"; import { VscodeScopeVisualizer } from "./VscodeScopeVisualizer"; -import type { VscodeTextEditorImpl } from "../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../VscodeTextEditor"; abstract class VscodeScopeTargetVisualizer extends VscodeScopeVisualizer { protected abstract getTargetRange( @@ -22,7 +22,7 @@ abstract class VscodeScopeTargetVisualizer extends VscodeScopeVisualizer { return this.scopeProvider.onDidChangeScopeRanges( (editor, scopeRanges) => { this.renderer.setScopes( - editor as VscodeTextEditorImpl, + editor as VscodeTextEditor, scopeRanges.map(({ domain, targets }) => ({ domain: toCharacterRange(domain), nestedRanges: targets.map((target) => this.getTargetRange(target)), diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeEvents.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeEvents.ts index eb77ddd1ea..5c208fc3ad 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeEvents.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeEvents.ts @@ -7,14 +7,14 @@ import type { } from "@cursorless/common"; import { fromVscodeRange } from "@cursorless/vscode-common"; import * as vscode from "vscode"; -import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; +import { VscodeTextDocument } from "./VscodeTextDocument"; export function vscodeOnDidChangeTextDocument( listener: (event: TextDocumentChangeEvent) => void, ): Disposable { return vscode.workspace.onDidChangeTextDocument((e) => { listener({ - document: new VscodeTextDocumentImpl(e.document), + document: new VscodeTextDocument(e.document), contentChanges: e.contentChanges.map(fromVscodeContentChange), reason: fromVscodeReason(e.reason), }); diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeFileSystem.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeFileSystem.ts index d755068bdd..87a938d440 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeFileSystem.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeFileSystem.ts @@ -78,7 +78,6 @@ export class VscodeFileSystem implements FileSystem { } public watchDir(path: string, onDidChange: PathChangeListener): Disposable { - // return { dispose: () => {} }; // FIXME: Support globs? const watcher = vscode.workspace.createFileSystemWatcher( new vscode.RelativePattern(path, "**"), diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeFocusEditor.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeFocusEditor.ts index 8a0f86ecfe..69c816a011 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeFocusEditor.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeFocusEditor.ts @@ -2,7 +2,7 @@ import { getCellIndex } from "@cursorless/vscode-common"; import type { NotebookDocument, TextEditor } from "vscode"; import { commands, TabInputTextDiff, ViewColumn, window } from "vscode"; import { getNotebookFromCellDocument } from "./notebook/notebook"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; const columnFocusCommands = { [ViewColumn.One]: "workbench.action.focusFirstEditorGroup", @@ -22,7 +22,7 @@ const columnFocusCommands = { * Focus editor. Returns true if selection needs to be set again. */ export default async function vscodeFocusEditor( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ): Promise { const viewColumn = getViewColumn(editor.vscodeEditor); if (viewColumn != null) { @@ -66,7 +66,7 @@ function getViewColumn(editor: TextEditor): ViewColumn | undefined { return tabGroup?.viewColumn; } -async function focusNotebookCell(editor: VscodeTextEditorImpl) { +async function focusNotebookCell(editor: VscodeTextEditor) { const desiredNotebookEditor = getNotebookFromCellDocument( editor.vscodeEditor.document, ); diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeFold.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeFold.ts index d2a0a93546..bc2aebc1eb 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeFold.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeFold.ts @@ -1,11 +1,11 @@ import type { Range } from "@cursorless/common"; import * as vscode from "vscode"; import type { VscodeIDE } from "./VscodeIDE"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export async function vscodeFold( ide: VscodeIDE, - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ranges: Range[] | undefined, ): Promise { return foldOrUnfold(ide, editor, ranges, "editor.fold"); @@ -13,7 +13,7 @@ export async function vscodeFold( export function vscodeUnfold( ide: VscodeIDE, - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ranges: Range[] | undefined, ): Promise { return foldOrUnfold(ide, editor, ranges, "editor.unfold"); @@ -21,7 +21,7 @@ export function vscodeUnfold( async function foldOrUnfold( ide: VscodeIDE, - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ranges: Range[] | undefined, command: "editor.fold" | "editor.unfold", ): Promise { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeHighlights.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeHighlights.ts index 1bcf07f42a..7fd9f9da47 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeHighlights.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeHighlights.ts @@ -7,7 +7,7 @@ import { FlashStyle, isLineRange, partition } from "@cursorless/common"; import type { ExtensionContext } from "vscode"; import * as vscode from "vscode"; import { VscodeHighlightDecorationTypes } from "./VscodeHighlightDecorationTypes"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export enum HighlightStyle { highlight0 = "highlight0", @@ -50,7 +50,7 @@ export default class VscodeHighlights { async setHighlightRanges( style: VscodeStyle, - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ranges: GeneralizedRange[], ) { const [lineRanges, tokenRanges] = partition( diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeIDE.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeIDE.ts index c235ddd0f9..c53cab5ffc 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeIDE.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeIDE.ts @@ -33,8 +33,8 @@ import { VscodeNotebookEditorImpl } from "./VscodeIdeNotebook"; import VscodeKeyValueStore from "./VscodeKeyValueStore"; import VscodeMessages from "./VscodeMessages"; import { vscodeRunMode } from "./VscodeRunMode"; -import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; -import { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import { VscodeTextDocument } from "./VscodeTextDocument"; +import { VscodeTextEditor } from "./VscodeTextEditor"; import { vscodeShowQuickPick } from "./vscodeShowQuickPick"; export class VscodeIDE implements IDE { @@ -55,7 +55,7 @@ export class VscodeIDE implements IDE { this.highlights = new VscodeHighlights(extensionContext); this.flashHandler = new VscodeFlashHandler(this, this.highlights); this.capabilities = new VscodeCapabilities(); - this.editorMap = new WeakMap(); + this.editorMap = new WeakMap(); } showQuickPick( @@ -76,7 +76,7 @@ export class VscodeIDE implements IDE { : HighlightStyle[highlightId as keyof typeof HighlightStyle]; return this.highlights.setHighlightRanges( vscodeHighlightId, - editor as VscodeTextEditorImpl, + editor as VscodeTextEditor, ranges, ); } @@ -101,11 +101,11 @@ export class VscodeIDE implements IDE { return workspace.workspaceFolders; } - get activeTextEditor(): VscodeTextEditorImpl | undefined { + get activeTextEditor(): VscodeTextEditor | undefined { return this.getActiveTextEditor(); } - get activeEditableTextEditor(): VscodeTextEditorImpl | undefined { + get activeEditableTextEditor(): VscodeTextEditor | undefined { return this.getActiveTextEditor(); } @@ -115,7 +115,7 @@ export class VscodeIDE implements IDE { : undefined; } - get visibleTextEditors(): VscodeTextEditorImpl[] { + get visibleTextEditors(): VscodeTextEditor[] { return window.visibleTextEditors.map((e) => this.fromVscodeEditor(e)); } @@ -180,11 +180,11 @@ export class VscodeIDE implements IDE { onDidOpenTextDocument = forwardEvent( workspace.onDidOpenTextDocument, - (document) => new VscodeTextDocumentImpl(document), + (document) => new VscodeTextDocument(document), ); onDidCloseTextDocument = forwardEvent( workspace.onDidCloseTextDocument, - (document) => new VscodeTextDocumentImpl(document), + (document) => new VscodeTextDocument(document), ); onDidChangeActiveTextEditor = forwardEvent( window.onDidChangeActiveTextEditor, @@ -209,12 +209,9 @@ export class VscodeIDE implements IDE { }), ); - public fromVscodeEditor(editor: vscode.TextEditor): VscodeTextEditorImpl { + public fromVscodeEditor(editor: vscode.TextEditor): VscodeTextEditor { if (!this.editorMap.has(editor)) { - this.editorMap.set( - editor, - new VscodeTextEditorImpl(uuid(), this, editor), - ); + this.editorMap.set(editor, new VscodeTextEditor(uuid(), this, editor)); } return this.editorMap.get(editor)!; } diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeIdeNotebook.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeIdeNotebook.ts index b1a11b1186..2cd418593b 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeIdeNotebook.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeIdeNotebook.ts @@ -6,7 +6,7 @@ import type { } from "@cursorless/common"; import type * as vscode from "vscode"; import type { URI } from "vscode-uri"; -import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; +import { VscodeTextDocument } from "./VscodeTextDocument"; export class VscodeNotebookEditorImpl implements NotebookEditor { private notebook: vscode.NotebookDocument; @@ -46,6 +46,6 @@ export class VscodeNotebookCellImpl implements NotebookCell { } get document(): TextDocument { - return new VscodeTextDocumentImpl(this.cell.document); + return new VscodeTextDocument(this.cell.document); } } diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeInsertSnippets.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeInsertSnippets.ts index 67f88878a9..f9ae223cb2 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeInsertSnippets.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeInsertSnippets.ts @@ -1,9 +1,9 @@ import * as vscode from "vscode"; import type { Range } from "@cursorless/common"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export async function vscodeInsertSnippet( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, snippet: string, ranges: Range[] | undefined, ): Promise { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeOpenLink.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeOpenLink.ts index a720e6ee20..0250358ee7 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeOpenLink.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeOpenLink.ts @@ -1,10 +1,10 @@ import * as vscode from "vscode"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; import type { OpenLinkOptions, Range } from "@cursorless/common"; import { toVscodePositionOrRange } from "@cursorless/vscode-common"; export default async function vscodeOpenLink( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, range: Range, { openAside }: OpenLinkOptions, ): Promise { @@ -39,7 +39,7 @@ export default async function vscodeOpenLink( } async function runCommandAtRange( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, command: string, range: Range, ) { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeRevealLine.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeRevealLine.ts index dfedb8fd73..6039b34653 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeRevealLine.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeRevealLine.ts @@ -1,9 +1,9 @@ import * as vscode from "vscode"; import { RevealLineAt } from "@cursorless/common"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export async function vscodeRevealLine( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, lineNumber: number, at: RevealLineAt, ): Promise { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeTextDocumentImpl.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeTextDocument.ts similarity index 91% rename from packages/cursorless-vscode/src/ide/vscode/VscodeTextDocumentImpl.ts rename to packages/cursorless-vscode/src/ide/vscode/VscodeTextDocument.ts index a819673a80..8fcf667620 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeTextDocumentImpl.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeTextDocument.ts @@ -14,9 +14,9 @@ import { import * as path from "node:path"; import type * as vscode from "vscode"; import type { URI } from "vscode-uri"; -import VscodeTextLineImpl from "./VscodeTextLineImpl"; +import VscodeTextLine from "./VscodeTextLine"; -export class VscodeTextDocumentImpl implements TextDocument { +export class VscodeTextDocument implements TextDocument { get uri(): URI { return this.document.uri; } @@ -49,7 +49,7 @@ export class VscodeTextDocumentImpl implements TextDocument { constructor(private document: vscode.TextDocument) {} public lineAt(lineOrPosition: number | Position): TextLine { - return new VscodeTextLineImpl( + return new VscodeTextLine( this.document.lineAt( typeof lineOrPosition === "number" ? lineOrPosition diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditor.ts similarity index 97% rename from packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts rename to packages/cursorless-vscode/src/ide/vscode/VscodeTextEditor.ts index 81128c183e..e98f5bf82e 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditorImpl.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeTextEditor.ts @@ -26,11 +26,11 @@ import type { VscodeIDE } from "./VscodeIDE"; import { vscodeInsertSnippet } from "./VscodeInsertSnippets"; import vscodeOpenLink from "./VscodeOpenLink"; import { vscodeRevealLine } from "./VscodeRevealLine"; -import { VscodeTextDocumentImpl } from "./VscodeTextDocumentImpl"; +import { VscodeTextDocument } from "./VscodeTextDocument"; import { vscodeToggleBreakpoint } from "./VscodeToggleBreakpoint"; import { isDiffEditorOriginal } from "./isDiffEditorOriginal"; -export class VscodeTextEditorImpl implements EditableTextEditor { +export class VscodeTextEditor implements EditableTextEditor { readonly document: TextDocument; constructor( @@ -38,7 +38,7 @@ export class VscodeTextEditorImpl implements EditableTextEditor { private ide: VscodeIDE, private editor: vscode.TextEditor, ) { - this.document = new VscodeTextDocumentImpl(editor.document); + this.document = new VscodeTextDocument(editor.document); } get vscodeEditor(): vscode.TextEditor { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeTextLineImpl.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeTextLine.ts similarity index 94% rename from packages/cursorless-vscode/src/ide/vscode/VscodeTextLineImpl.ts rename to packages/cursorless-vscode/src/ide/vscode/VscodeTextLine.ts index 97f49d82a9..aa5a0976de 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeTextLineImpl.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeTextLine.ts @@ -3,7 +3,7 @@ import { Position, Range } from "@cursorless/common"; import { fromVscodeRange } from "@cursorless/vscode-common"; import type * as vscode from "vscode"; -export default class VscodeTextLineImpl implements TextLine { +export default class VscodeTextLine implements TextLine { constructor(private line: vscode.TextLine) {} get lineNumber(): number { diff --git a/packages/cursorless-vscode/src/ide/vscode/VscodeToggleBreakpoint.ts b/packages/cursorless-vscode/src/ide/vscode/VscodeToggleBreakpoint.ts index 809e673f30..dd2335e091 100644 --- a/packages/cursorless-vscode/src/ide/vscode/VscodeToggleBreakpoint.ts +++ b/packages/cursorless-vscode/src/ide/vscode/VscodeToggleBreakpoint.ts @@ -1,10 +1,10 @@ import type { GeneralizedRange, Position } from "@cursorless/common"; import { toVscodePosition } from "@cursorless/vscode-common"; import * as vscode from "vscode"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export async function vscodeToggleBreakpoint( - editor: VscodeTextEditorImpl, + editor: VscodeTextEditor, ranges?: GeneralizedRange[] | undefined, ): Promise { if (ranges == null) { diff --git a/packages/cursorless-vscode/src/ide/vscode/hats/VscodeHats.ts b/packages/cursorless-vscode/src/ide/vscode/hats/VscodeHats.ts index 8983f01c7d..7c290151b8 100644 --- a/packages/cursorless-vscode/src/ide/vscode/hats/VscodeHats.ts +++ b/packages/cursorless-vscode/src/ide/vscode/hats/VscodeHats.ts @@ -15,7 +15,7 @@ import type { Disposable } from "vscode"; import type { VscodeHatStyleName } from "../hatStyles.types"; import VscodeEnabledHatStyleManager from "../VscodeEnabledHatStyleManager"; import type { VscodeIDE } from "../VscodeIDE"; -import type { VscodeTextEditorImpl } from "../VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "../VscodeTextEditor"; import type { FontMeasurements } from "./FontMeasurements"; import VscodeHatRenderer from "./VscodeHatRenderer"; @@ -113,7 +113,7 @@ export class VscodeHats implements Hats { decorationRanges.forEach((ranges, editor) => { hatStyleNames.forEach((hatStyleName) => { - (editor as VscodeTextEditorImpl).vscodeEditor.setDecorations( + (editor as VscodeTextEditor).vscodeEditor.setDecorations( this.hatRenderer.getDecorationType( hatStyleName as VscodeHatStyleName, )!, diff --git a/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts b/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts index 693bd9ccd7..3aecf37ae3 100644 --- a/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts +++ b/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts @@ -1,6 +1,6 @@ import * as assert from "assert"; import { openNewEditor } from "@cursorless/vscode-common"; -import VscodeTextLineImpl from "./VscodeTextLineImpl"; +import VscodeTextLine from "./VscodeTextLine"; /** * Each test is of the form: @@ -19,7 +19,7 @@ suite("TextLine", function () { whiteSpaceTests.forEach(([text, trimmedStart, trimmedEnd]) => { test(`whitespace '${text}'`, async () => { const editor = await openNewEditor(text); - const line = new VscodeTextLineImpl(editor.document.lineAt(0)); + const line = new VscodeTextLine(editor.document.lineAt(0)); assert.equal(line.rangeTrimmed?.start?.character, trimmedStart); assert.equal(line.rangeTrimmed?.end?.character, trimmedEnd); diff --git a/packages/cursorless-vscode/src/ide/vscode/toVscodeEditor.ts b/packages/cursorless-vscode/src/ide/vscode/toVscodeEditor.ts index ef8fdf79d5..144a9fac61 100644 --- a/packages/cursorless-vscode/src/ide/vscode/toVscodeEditor.ts +++ b/packages/cursorless-vscode/src/ide/vscode/toVscodeEditor.ts @@ -1,10 +1,10 @@ import type { TextEditor } from "@cursorless/common"; import type * as vscode from "vscode"; -import type { VscodeTextEditorImpl } from "./VscodeTextEditorImpl"; +import type { VscodeTextEditor } from "./VscodeTextEditor"; export function toVscodeEditor(editor: TextEditor): vscode.TextEditor { if ("vscodeEditor" in editor) { - return (editor as VscodeTextEditorImpl).vscodeEditor; + return (editor as VscodeTextEditor).vscodeEditor; } throw Error("Can't get vscode editor from non vscode implementation"); } diff --git a/packages/neovim-common/src/getExtensionApi.ts b/packages/neovim-common/src/getExtensionApi.ts index 4602f2ed91..b75a84e9d7 100644 --- a/packages/neovim-common/src/getExtensionApi.ts +++ b/packages/neovim-common/src/getExtensionApi.ts @@ -5,14 +5,6 @@ export interface CursorlessApi { testHelpers: NeovimTestHelpers | undefined; } -// See packages\cursorless-neovim\src\extension.ts:createTreeSitter() for neovim -// export interface ParseTreeApi { -// getNodeAtLocation(location: vscode.Location): Node; -// getTreeForUri(uri: vscode.Uri): Tree; -// loadLanguage: (languageId: string) => Promise; -// getLanguage(languageId: string): Language | undefined; -// } - export async function getExtensionApi(extensionId: string) { const api = getNeovimRegistry().getExtensionApi(extensionId); return api == null ? null : (api as T); @@ -31,14 +23,3 @@ export async function getExtensionApiStrict(extensionId: string) { export const EXTENSION_ID = "pokey.cursorless"; export const getCursorlessApi = () => getExtensionApiStrict(EXTENSION_ID); - -// export const getParseTreeApi = () => -// getExtensionApiStrict("pokey.parse-tree"); - -// See packages/cursorless-neovim/src/NeovimCommandServerApi.ts for neovim implementation -/** - * - * @returns Command server API or null if not installed - */ -// export const getCommandServerApi = () => -// getExtensionApi("pokey.command-server"); diff --git a/packages/neovim-common/src/ide/neovim/NeovimEdit.ts b/packages/neovim-common/src/ide/neovim/NeovimEdit.ts index a9fcc90af5..babf00838a 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimEdit.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimEdit.ts @@ -23,25 +23,16 @@ export default async function neovimEdit( } edits.sort((a, b) => { - // console.debug( - // `a=${JSON.stringify(a.range)}, text='${a.text}', isReplace=${a.isReplace}`, - // ); - // console.debug( - // `b=${JSON.stringify(b.range)}, text='${b.text}', isReplace=${b.isReplace}`, - // ); // We apply the insert/replace edits from the start of the document // as a later one assume the previous ones have already been applied if ((isInsert(a) || isReplace(a)) && (isInsert(b) || isReplace(b))) { - // console.debug("a is insert/replace and b is insert/replace"); return 1; } // We apply the delete edits from the end of the document // to make sure the edit ranges for the remaining ones are stable if (a.range.start.line === b.range.start.line) { - // console.debug("a and b are on the same line"); return b.range.start.character - a.range.start.character; } - // console.debug("a and b are on different lines"); return b.range.start.line - a.range.start.line; }); diff --git a/packages/neovim-common/src/ide/neovim/NeovimIDE.ts b/packages/neovim-common/src/ide/neovim/NeovimIDE.ts index 0dad021d80..0916c44472 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimIDE.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimIDE.ts @@ -29,7 +29,7 @@ import NeovimClipboard from "./NeovimClipboard"; import NeovimConfiguration from "./NeovimConfiguration"; import NeovimKeyValueStore from "./NeovimKeyValueStore"; import NeovimMessages from "./NeovimMessages"; -import { NeovimTextEditorImpl } from "./NeovimTextEditorImpl"; +import { NeovimTextEditor } from "./NeovimTextEditor"; import { getNeovimRegistry } from "@cursorless/neovim-registry"; import { @@ -42,7 +42,7 @@ import { neovimOnDidChangeTextDocument, neovimOnDidOpenTextDocument, } from "./NeovimEvents"; -import { NeovimTextDocumentImpl } from "./NeovimTextDocumentImpl"; +import { NeovimTextDocument } from "./NeovimTextDocument"; export class NeovimIDE implements IDE { readonly configuration: NeovimConfiguration; @@ -68,8 +68,8 @@ export class NeovimIDE implements IDE { this.messages = new NeovimMessages(); this.clipboard = new NeovimClipboard(this.client); this.capabilities = new NeovimCapabilities(); - this.editorMap = new Map(); - this.documentMap = new Map(); + this.editorMap = new Map(); + this.documentMap = new Map(); this.activeWindow = undefined; this.activeBuffer = undefined; } @@ -153,7 +153,7 @@ export class NeovimIDE implements IDE { return undefined; } - get visibleTextEditors(): NeovimTextEditorImpl[] { + get visibleTextEditors(): NeovimTextEditor[] { return Array.from(this.editorMap.values()); } @@ -227,9 +227,7 @@ export class NeovimIDE implements IDE { * * Atm, we only initialize one editor(current window) with one document(current buffer) */ - async updateTextEditor( - minimal: boolean = false, - ): Promise { + async updateTextEditor(minimal: boolean = false): Promise { const window = await this.client.window; const buffer = await window.buffer; const lines = await buffer.lines; @@ -268,19 +266,18 @@ export class NeovimIDE implements IDE { lines: string[], visibleRanges: Range[], selections: Selection[], - ): NeovimTextEditorImpl { + ): NeovimTextEditor { let document = this.getTextDocument(buffer); let editor = this.getTextEditor(window); if (!document) { console.debug( `toNeovimEditor(): creating new document: buffer=${buffer.id}`, ); - document = new NeovimTextDocumentImpl( - URI.parse(`neovim://${buffer.id}`), // URI.parse(`file://${buffer.id}`), + document = new NeovimTextDocument( + URI.parse(`neovim://${buffer.id}`), "plaintext", 1, "\n", - // "\r\n", lines, ); this.documentMap.set(buffer, document); @@ -292,7 +289,7 @@ export class NeovimIDE implements IDE { console.debug( `toNeovimEditor(): creating new editor: window=${window.id}`, ); - editor = new NeovimTextEditorImpl( + editor = new NeovimTextEditor( uuid(), this.client, this, @@ -309,15 +306,11 @@ export class NeovimIDE implements IDE { this.activeBuffer = buffer; this.activeWindow = window; - return this.activeTextEditor as NeovimTextEditorImpl; + return this.activeTextEditor as NeovimTextEditor; } handleCommandError(err: Error) { - // if (err instanceof OutdatedExtensionError) { - // this.showUpdateExtensionErrorMessage(err); - // } else { void showErrorMessage(this.client, err.message); - // } } disposeOnExit(...disposables: Disposable[]): () => void { diff --git a/packages/neovim-common/src/ide/neovim/NeovimTextDocumentImpl.ts b/packages/neovim-common/src/ide/neovim/NeovimTextDocument.ts similarity index 81% rename from packages/neovim-common/src/ide/neovim/NeovimTextDocumentImpl.ts rename to packages/neovim-common/src/ide/neovim/NeovimTextDocument.ts index fc43465368..441a561176 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimTextDocumentImpl.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimTextDocument.ts @@ -1,10 +1,10 @@ import type { EndOfLine, TextDocument, TextLine } from "@cursorless/common"; import { Position, Range } from "@cursorless/common"; import type { URI } from "vscode-uri"; -import NeovimTextLineImpl from "./NeovimTextLineImpl"; +import NeovimTextLine from "./NeovimTextLine"; import path from "node:path"; -export class NeovimTextDocumentImpl implements TextDocument { +export class NeovimTextDocument implements TextDocument { private _uri: URI; private _languageId: string; private _version: number; @@ -32,16 +32,12 @@ export class NeovimTextDocumentImpl implements TextDocument { } get lineCount(): number { - // console.debug(`lineCount(): ${this._lineCount}`); return this._lineCount; } get range(): Range { const { end } = this.lineAt(this.lineCount - 1).range; const range = new Range(0, 0, end.line, end.character); - // console.debug( - // `range(): (${range.start.line},${range.start.character}),(${range.end.line},${range.end.character})`, - // ); return range; } @@ -82,7 +78,6 @@ export class NeovimTextDocumentImpl implements TextDocument { } else if (typeof lineOrPosition === "number") { line = lineOrPosition; } - // console.debug(`lineAt() line=${line}`); if (typeof line !== "number" || line < 0 || Math.floor(line) !== line) { throw new Error("Illegal value for `line`"); @@ -90,7 +85,7 @@ export class NeovimTextDocumentImpl implements TextDocument { // The position is adjusted if it is outside range line = Math.min(line, this._lines.length - 1); - return new NeovimTextLineImpl( + return new NeovimTextLine( line, this._lines[line], line === this._lines.length - 1, @@ -98,23 +93,14 @@ export class NeovimTextDocumentImpl implements TextDocument { } public offsetAt(position: Position): number { - // console.debug( - // `offsetAt() position=(${position.line},${position.character})`, - // ); position = this._validatePosition(position); this._ensureLineStarts(); - // console.debug( - // `offsetAt() returning ${ - // this._lineStarts!.getPrefixSum(position.line - 1) + position.character - // }`, - // ); return ( this._lineStarts!.getPrefixSum(position.line - 1) + position.character ); } public positionAt(offset: number): Position { - // console.debug(`positionAt() offset=${offset}`); offset = Math.floor(offset); offset = Math.max(0, offset); @@ -129,39 +115,19 @@ export class NeovimTextDocumentImpl implements TextDocument { public getText(range?: Range): string { if (range === undefined) { - // console.debug(`getText(all)`); if (this._cachedTextValue == null) { this._cachedTextValue = this._lines.join(this._eol); } - // if (this._lines.length > 10) { - // console.debug( - // `getText() returning multiple lines: '${this._lines.slice(0, 10).join(this._eol)}' \n[stripped...]}`, - // ); - // } else { - // console.debug( - // `getText() returning multiple lines: '${this._cachedTextValue}'`, - // ); - // } return this._cachedTextValue; - } else { - // console.debug( - // `getText(range=(${range?.start.line},${range?.start.character}),(${range?.end.line},${range?.end.character}))`, - // ); } range = this._validateRange(range); if (range.isEmpty) { - // console.debug(`getText() returning empty`); return ""; } if (range.isSingleLine) { - // console.debug( - // `getText() returning single line '${this._lines[ - // range.start.line - // ].substring(range.start.character, range.end.character)}'`, - // ); return this._lines[range.start.line].substring( range.start.character, range.end.character, @@ -182,15 +148,6 @@ export class NeovimTextDocumentImpl implements TextDocument { resultLines.push( this._lines[endLineIndex].substring(0, range.end.character), ); - // if (resultLines.length > 10) { - // console.debug( - // `getText() returning multiple lines: '${resultLines.slice(0, 10).join(lineEnding)}' \n[stripped...]}`, - // ); - // } else { - // console.debug( - // `getText() returning multiple lines: '${resultLines.join(lineEnding)}'`, - // ); - // } return resultLines.join(lineEnding); } diff --git a/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts b/packages/neovim-common/src/ide/neovim/NeovimTextEditor.ts similarity index 94% rename from packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts rename to packages/neovim-common/src/ide/neovim/NeovimTextEditor.ts index f2953bda88..4b510ff8e0 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimTextEditorImpl.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimTextEditor.ts @@ -14,10 +14,10 @@ import { bufferSetSelections } from "../../neovimApi"; import { neovimClipboardCopy, neovimClipboardPaste } from "../../neovimHelpers"; import neovimEdit from "./NeovimEdit"; import type { NeovimIDE } from "./NeovimIDE"; -import type { NeovimTextDocumentImpl } from "./NeovimTextDocumentImpl"; +import type { NeovimTextDocument } from "./NeovimTextDocument"; -export class NeovimTextEditorImpl implements EditableTextEditor { - private _document: NeovimTextDocumentImpl; +export class NeovimTextEditor implements EditableTextEditor { + private _document: NeovimTextDocument; private _selections: Selection[]; private _visibleRanges: Range[]; @@ -26,7 +26,7 @@ export class NeovimTextEditorImpl implements EditableTextEditor { private client: NeovimClient, private neovimIDE: NeovimIDE, private window: Window, - doc: NeovimTextDocumentImpl, + doc: NeovimTextDocument, visibleRanges: Range[], selections: Selection[], ) { @@ -35,16 +35,16 @@ export class NeovimTextEditorImpl implements EditableTextEditor { this._visibleRanges = visibleRanges; } - get document(): NeovimTextDocumentImpl { + get document(): NeovimTextDocument { return this._document; } public updateDocument( visibleRanges: Range[], selections: Selection[], - doc?: NeovimTextDocumentImpl, + doc?: NeovimTextDocument, lines?: string[], - ): NeovimTextDocumentImpl { + ): NeovimTextDocument { if (doc) { this._document = doc; } else if (lines) { diff --git a/packages/neovim-common/src/ide/neovim/NeovimTextLineImpl.ts b/packages/neovim-common/src/ide/neovim/NeovimTextLine.ts similarity index 59% rename from packages/neovim-common/src/ide/neovim/NeovimTextLineImpl.ts rename to packages/neovim-common/src/ide/neovim/NeovimTextLine.ts index 16bf19592f..d6b8e7c542 100644 --- a/packages/neovim-common/src/ide/neovim/NeovimTextLineImpl.ts +++ b/packages/neovim-common/src/ide/neovim/NeovimTextLine.ts @@ -1,15 +1,12 @@ import type { TextLine } from "@cursorless/common"; import { Range } from "@cursorless/common"; -export default class NeovimTextLineImpl implements TextLine { +export default class NeovimTextLine implements TextLine { private readonly _lineNumber: number; private readonly _text: string; private readonly _isLastLine: boolean; constructor(lineNumber: number, text: string, isLastLine: boolean) { - // console.debug( - // `NeovimTextLineImpl(): lineNumber=${lineNumber}, text='${text}', isLastLine=${isLastLine}`, - // ); this._lineNumber = lineNumber; this._text = text; this._isLastLine = isLastLine; @@ -20,29 +17,17 @@ export default class NeovimTextLineImpl implements TextLine { } get text(): string { - // console.debug(`NeovimTextLineImpl.text()='${this._text}'`); return this._text; } get range(): Range { - // console.debug( - // `NeovimTextLineImpl.range(): range=(${this._lineNumber}, 0), (${this._lineNumber}, ${this._text.length})`, - // ); return new Range(this._lineNumber, 0, this._lineNumber, this._text.length); } get rangeIncludingLineBreak(): Range { if (this._isLastLine) { - // console.debug( - // `NeovimTextLineImpl.rangeIncludingLineBreak(): last line=(${this.range.start.line}, ${this.range.start.character}), (${this.range.end.line}, ${this.range.end.character})`, - // ); return this.range; } - // console.debug( - // `NeovimTextLineImpl.rangeIncludingLineBreak(): range=(${ - // this._lineNumber - // }, 0), ${this._lineNumber + 1}, 0})`, - // ); return new Range(this._lineNumber, 0, this._lineNumber + 1, 0); } diff --git a/packages/neovim-common/src/index.ts b/packages/neovim-common/src/index.ts index 48688030bd..db81c29d03 100644 --- a/packages/neovim-common/src/index.ts +++ b/packages/neovim-common/src/index.ts @@ -11,6 +11,6 @@ export * from "./ide/neovim/NeovimEvents"; export * from "./ide/neovim/NeovimKeyValueStore"; export * from "./ide/neovim/NeovimIDE"; export * from "./ide/neovim/NeovimMessages"; -export * from "./ide/neovim/NeovimTextDocumentImpl"; -export * from "./ide/neovim/NeovimTextEditorImpl"; -export * from "./ide/neovim/NeovimTextLineImpl"; +export * from "./ide/neovim/NeovimTextDocument"; +export * from "./ide/neovim/NeovimTextEditor"; +export * from "./ide/neovim/NeovimTextLine"; diff --git a/packages/neovim-common/src/neovimApi.ts b/packages/neovim-common/src/neovimApi.ts index 54fcdc0a71..4aed768eb2 100644 --- a/packages/neovim-common/src/neovimApi.ts +++ b/packages/neovim-common/src/neovimApi.ts @@ -49,7 +49,6 @@ export async function bufferGetSelections( } export async function bufferSetSelections( - // window: Window, client: NeovimClient, selections: Selection[], ) { @@ -69,7 +68,6 @@ export async function bufferSetSelections( `bufferSetSelections() selections=(${selections[0].start.line},${selections[0].start.character}),(${selections[0].end.line},${selections[0].end.character}) luaCode="${luaCode}"`, ); await client.executeLua(luaCode, []); - // console.debug(`bufferSetSelections() done`); } /** diff --git a/packages/neovim-common/src/neovimHelpers.ts b/packages/neovim-common/src/neovimHelpers.ts index 517c619201..2dc11c8687 100644 --- a/packages/neovim-common/src/neovimHelpers.ts +++ b/packages/neovim-common/src/neovimHelpers.ts @@ -5,7 +5,7 @@ import { pasteFromClipboard, setClipboard, } from "@cursorless/neovim-common"; -import type { NeovimTextEditorImpl } from "./ide/neovim/NeovimTextEditorImpl"; +import type { NeovimTextEditor } from "./ide/neovim/NeovimTextEditor"; import type { NeovimClient } from "neovim"; import type { IDE } from "@cursorless/common"; @@ -13,7 +13,7 @@ export async function neovimClipboardCopy( client: NeovimClient, ide: IDE, ): Promise { - const editor = ide.activeTextEditor as NeovimTextEditorImpl; + const editor = ide.activeTextEditor as NeovimTextEditor; const window = await client.window; const selections = await bufferGetSelections(window, client); const data = editor.document.getText(selections[0]); diff --git a/packages/neovim-common/src/testUtil/openNewEditor.ts b/packages/neovim-common/src/testUtil/openNewEditor.ts index 8c428e7310..f74c9bc9c1 100644 --- a/packages/neovim-common/src/testUtil/openNewEditor.ts +++ b/packages/neovim-common/src/testUtil/openNewEditor.ts @@ -1,5 +1,5 @@ -import type { NeovimTextEditorImpl } from ".."; -import type { NeovimTextDocumentImpl } from "../ide/neovim/NeovimTextDocumentImpl"; +import type { NeovimTextEditor } from ".."; +import type { NeovimTextDocument } from "../ide/neovim/NeovimTextDocument"; export interface NewEditorOptions { languageId?: string; @@ -9,12 +9,12 @@ export interface NewEditorOptions { export async function openNewEditor( content: string, _NewEditorOptions = {}, -): Promise { +): Promise { throw new Error("openNewEditor() Not implemented"); } export async function reuseEditor( - editor: NeovimTextDocumentImpl, // vscode.TextEditor, + editor: NeovimTextDocument, // vscode.TextEditor, content: string, _language: string = "plaintext", ) { From 14fc7ac2ab95b9fc0c64db67dd728a56c66c2078 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 13:12:44 +0100 Subject: [PATCH 2/2] Use new text editor --- packages/common/src/ide/fake/FakeIDE.ts | 19 ++- .../InMemoryTextDocument.ts | 0 .../inMemoryTextEditor/InMemoryTextEditor.ts} | 110 +++++++++++++----- .../InMemoryTextLine.ts | 0 .../performEdits.ts | 0 .../test/InMemoryTextDocument.test.ts | 0 .../test/InMemoryTextDocumentEdit.test.ts | 0 .../test/InMemoryTextDocumentLineAt.test.ts | 0 .../test/createTestDocument.ts | 0 packages/common/src/ide/types/events.types.ts | 7 ++ packages/common/src/ide/types/ide.types.ts | 5 + packages/common/src/index.ts | 4 +- packages/common/src/types/Range.ts | 8 ++ packages/common/src/types/RangeOffsets.ts | 4 - packages/common/src/types/Selection.ts | 8 ++ packages/common/src/types/Token.ts | 3 +- .../src/testUtil/createTestEnvironment.ts | 21 +--- .../src/ide/TalonJsIDE.ts | 68 ++++++++--- .../src/ide/createTextEditor.ts | 42 ------- .../src/ide/flashRanges.ts | 3 +- .../src/ide/setSelections.ts | 17 --- .../src/ide/talonJsPerformEdits.ts | 29 ----- .../src/ide/toCharacterRangeOffsets.ts | 7 +- .../src/types/talon.types.ts | 8 +- .../src/types/types.ts | 12 +- .../src/talonMock.ts | 3 +- 26 files changed, 195 insertions(+), 183 deletions(-) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/InMemoryTextDocument.ts (100%) rename packages/{cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts => common/src/ide/inMemoryTextEditor/InMemoryTextEditor.ts} (63%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/InMemoryTextLine.ts (100%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/performEdits.ts (100%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/test/InMemoryTextDocument.test.ts (100%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/test/InMemoryTextDocumentEdit.test.ts (100%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/test/InMemoryTextDocumentLineAt.test.ts (100%) rename packages/common/src/ide/{inMemoryTextDocument => inMemoryTextEditor}/test/createTestDocument.ts (100%) delete mode 100644 packages/common/src/types/RangeOffsets.ts delete mode 100644 packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts delete mode 100644 packages/cursorless-everywhere-talon-core/src/ide/setSelections.ts delete mode 100644 packages/cursorless-everywhere-talon-core/src/ide/talonJsPerformEdits.ts diff --git a/packages/common/src/ide/fake/FakeIDE.ts b/packages/common/src/ide/fake/FakeIDE.ts index f8f41a21b5..58e951cf2e 100644 --- a/packages/common/src/ide/fake/FakeIDE.ts +++ b/packages/common/src/ide/fake/FakeIDE.ts @@ -11,13 +11,14 @@ import type { TextDocumentChangeEvent } from "../types/Events"; import type { FlashDescriptor } from "../types/FlashDescriptor"; import type { QuickPickOptions } from "../types/QuickPickOptions"; import type { + Emit, Event, TextEditorSelectionChangeEvent, TextEditorVisibleRangesChangeEvent, } from "../types/events.types"; import type { Disposable, - IDE, + EmittableIDE, OpenUntitledTextDocumentOptions, RunMode, WorkspaceFolder, @@ -28,7 +29,7 @@ import FakeConfiguration from "./FakeConfiguration"; import FakeKeyValueStore from "./FakeKeyValueStore"; import FakeMessages from "./FakeMessages"; -export class FakeIDE implements IDE { +export class FakeIDE implements EmittableIDE { configuration = new FakeConfiguration(); keyValueStore = new FakeKeyValueStore(); clipboard = new FakeClipboard(); @@ -47,7 +48,7 @@ export class FakeIDE implements IDE { } async flashRanges(_flashDescriptors: FlashDescriptor[]): Promise { - // empty + // Empty } async setHighlightRanges( @@ -55,7 +56,7 @@ export class FakeIDE implements IDE { _editor: TextEditor, _ranges: GeneralizedRange[], ): Promise { - // empty + // Empty } onDidOpenTextDocument: Event = dummyEvent; @@ -68,6 +69,10 @@ export class FakeIDE implements IDE { dummyEvent; onDidChangeTextDocument: Event = dummyEvent; + emitDidChangeTextDocument: Emit = dummyEmit; + emitDidChangeTextEditorSelection: Emit = + dummyEmit; + mockAssetsRoot(_assetsRoot: string) { this.assetsRoot_ = _assetsRoot; } @@ -151,7 +156,11 @@ export class FakeIDE implements IDE { function dummyEvent() { return { dispose() { - // empty + // Empty }, }; } + +function dummyEmit() { + // Empty +} diff --git a/packages/common/src/ide/inMemoryTextDocument/InMemoryTextDocument.ts b/packages/common/src/ide/inMemoryTextEditor/InMemoryTextDocument.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/InMemoryTextDocument.ts rename to packages/common/src/ide/inMemoryTextEditor/InMemoryTextDocument.ts diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts b/packages/common/src/ide/inMemoryTextEditor/InMemoryTextEditor.ts similarity index 63% rename from packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts rename to packages/common/src/ide/inMemoryTextEditor/InMemoryTextEditor.ts index a0fb6b3570..3431b5b86c 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsTextEditor.ts +++ b/packages/common/src/ide/inMemoryTextEditor/InMemoryTextEditor.ts @@ -1,38 +1,79 @@ import type { Edit, EditableTextEditor, + EmittableIDE, GeneralizedRange, - InMemoryTextDocument, OpenLinkOptions, Range, RevealLineAt, - Selection, + SelectionOffsets, SetSelectionsOpts, + TextDocument, TextEditor, TextEditorOptions, } from "@cursorless/common"; -import { selectionsEqual } from "@cursorless/common"; -import type { Talon } from "../types/talon.types"; -import { setSelections } from "./setSelections"; -import type { TalonJsIDE } from "./TalonJsIDE"; -import { talonJsPerformEdits } from "./talonJsPerformEdits"; - -export class TalonJsTextEditor implements EditableTextEditor { - options: TextEditorOptions = { - tabSize: 4, - insertSpaces: true, - }; - - isActive = true; - - constructor( - private talon: Talon, - private ide: TalonJsIDE, - public id: string, - public document: InMemoryTextDocument, - public visibleRanges: Range[], - public selections: Selection[], - ) {} +import { Selection, selectionsEqual } from "@cursorless/common"; +import { URI } from "vscode-uri"; +import { InMemoryTextDocument } from "./InMemoryTextDocument"; + +interface Params { + ide: EmittableIDE; + languageId?: string; + content?: string; + options?: TextEditorOptions; + visibleRanges?: Range[]; + selections?: Selection[] | SelectionOffsets[]; +} + +export class InMemoryTextEditor implements EditableTextEditor { + private static nextId = 0; + + private readonly ide: EmittableIDE; + readonly id: string; + readonly isActive = true; + readonly document: InMemoryTextDocument; + readonly options: TextEditorOptions; + readonly visibleRanges: Range[]; + selections: Selection[]; + + constructor({ + ide, + languageId = "plaintext", + content = "", + visibleRanges, + selections, + options, + }: Params) { + this.ide = ide; + this.id = String(InMemoryTextEditor.nextId++); + const uri = URI.parse(`InMemoryTextEditor://${this.id}`); + this.document = new InMemoryTextDocument(uri, languageId, content); + + if (visibleRanges != null) { + if (visibleRanges.length === 0) { + throw new Error("Visible ranges must be non-empty"); + } + this.visibleRanges = visibleRanges; + } else { + this.visibleRanges = [this.document.range]; + } + + if (selections != null) { + if (selections.length === 0) { + throw new Error("Selections must be non-empty"); + } + this.selections = selections.map((s) => { + return s instanceof Selection ? s : createSelection(this.document, s); + }); + } else { + this.selections = [new Selection(0, 0, 0, 0)]; + } + + this.options = options ?? { + insertSpaces: true, + tabSize: 4, + }; + } isEqual(other: TextEditor): boolean { return this.id === other.id; @@ -42,14 +83,24 @@ export class TalonJsTextEditor implements EditableTextEditor { selections: Selection[], _opts?: SetSelectionsOpts, ): Promise { + if (selections.length === 0) { + throw new Error("Selections must be non-empty"); + } if (!selectionsEqual(this.selections, selections)) { - await setSelections(this.talon, this.document, selections); this.selections = selections; + this.ide.emitDidChangeTextEditorSelection({ + textEditor: this, + selections: selections, + }); } } edit(edits: Edit[]): Promise { - talonJsPerformEdits(this.talon, this.ide, this.document, edits); + const changes = this.document.edit(edits); + this.ide.emitDidChangeTextDocument({ + document: this.document, + contentChanges: changes, + }); return Promise.resolve(true); } @@ -179,3 +230,10 @@ export class TalonJsTextEditor implements EditableTextEditor { throw Error("gitUnstageRange: not implemented"); } } + +function createSelection(document: TextDocument, selection: SelectionOffsets) { + return new Selection( + document.positionAt(selection.anchor), + document.positionAt(selection.active), + ); +} diff --git a/packages/common/src/ide/inMemoryTextDocument/InMemoryTextLine.ts b/packages/common/src/ide/inMemoryTextEditor/InMemoryTextLine.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/InMemoryTextLine.ts rename to packages/common/src/ide/inMemoryTextEditor/InMemoryTextLine.ts diff --git a/packages/common/src/ide/inMemoryTextDocument/performEdits.ts b/packages/common/src/ide/inMemoryTextEditor/performEdits.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/performEdits.ts rename to packages/common/src/ide/inMemoryTextEditor/performEdits.ts diff --git a/packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocument.test.ts b/packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocument.test.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocument.test.ts rename to packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocument.test.ts diff --git a/packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocumentEdit.test.ts b/packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocumentEdit.test.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocumentEdit.test.ts rename to packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocumentEdit.test.ts diff --git a/packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocumentLineAt.test.ts b/packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocumentLineAt.test.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/test/InMemoryTextDocumentLineAt.test.ts rename to packages/common/src/ide/inMemoryTextEditor/test/InMemoryTextDocumentLineAt.test.ts diff --git a/packages/common/src/ide/inMemoryTextDocument/test/createTestDocument.ts b/packages/common/src/ide/inMemoryTextEditor/test/createTestDocument.ts similarity index 100% rename from packages/common/src/ide/inMemoryTextDocument/test/createTestDocument.ts rename to packages/common/src/ide/inMemoryTextEditor/test/createTestDocument.ts diff --git a/packages/common/src/ide/types/events.types.ts b/packages/common/src/ide/types/events.types.ts index aa33c3e5f2..7e9dc57f8b 100644 --- a/packages/common/src/ide/types/events.types.ts +++ b/packages/common/src/ide/types/events.types.ts @@ -29,6 +29,13 @@ export interface Event { ): Disposable; } +/** + * Represents a function that emits an event of type T. + */ +export interface Emit { + (event: T): void; +} + /** * Represents an event describing the change in a {@link TextEditor.selections text editor's selections}. */ diff --git a/packages/common/src/ide/types/ide.types.ts b/packages/common/src/ide/types/ide.types.ts index 354ebd6c14..b61a10745e 100644 --- a/packages/common/src/ide/types/ide.types.ts +++ b/packages/common/src/ide/types/ide.types.ts @@ -248,6 +248,11 @@ export interface IDE { ): Promise; } +export interface EmittableIDE extends IDE { + emitDidChangeTextDocument(event: TextDocumentChangeEvent): void; + emitDidChangeTextEditorSelection(event: TextEditorSelectionChangeEvent): void; +} + export interface WorkspaceFolder { uri: URI; name: string; diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index b6223027a3..69b194422d 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -6,7 +6,8 @@ export * from "./errors"; export * from "./extensionDependencies"; export * from "./FakeCommandServerApi"; export * from "./ide/fake/FakeIDE"; -export * from "./ide/inMemoryTextDocument/InMemoryTextDocument"; +export * from "./ide/inMemoryTextEditor/InMemoryTextDocument"; +export * from "./ide/inMemoryTextEditor/InMemoryTextEditor"; export * from "./ide/normalized/NormalizedIDE"; export * from "./ide/PassthroughIDE"; export * from "./ide/spy/SpyIDE"; @@ -77,7 +78,6 @@ export * from "./types/NotebookEditor"; export * from "./types/Position"; export * from "./types/Range"; export * from "./types/RangeExpansionBehavior"; -export * from "./types/RangeOffsets"; export * from "./types/RevealLineAt"; export * from "./types/ScopeProvider"; export * from "./types/Selection"; diff --git a/packages/common/src/types/Range.ts b/packages/common/src/types/Range.ts index 3939151ac9..536fa82bb9 100644 --- a/packages/common/src/types/Range.ts +++ b/packages/common/src/types/Range.ts @@ -182,3 +182,11 @@ export class Range { return `${this.start.concise()}-${this.end.concise()}`; } } + +/** + * Represents the offsets of a range, where `start` and `end` are zero-based offsets from the start of the document. + */ +export interface RangeOffsets { + start: number; + end: number; +} diff --git a/packages/common/src/types/RangeOffsets.ts b/packages/common/src/types/RangeOffsets.ts deleted file mode 100644 index 32db05311a..0000000000 --- a/packages/common/src/types/RangeOffsets.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface RangeOffsets { - start: number; - end: number; -} diff --git a/packages/common/src/types/Selection.ts b/packages/common/src/types/Selection.ts index 5a5dc838db..8415e9a624 100644 --- a/packages/common/src/types/Selection.ts +++ b/packages/common/src/types/Selection.ts @@ -93,3 +93,11 @@ export class Selection extends Range { return this.concise(); } } + +/** + * Represents the offsets of a selection, where `anchor` and `active` are zero-based offsets from the start of the document. + */ +export interface SelectionOffsets { + anchor: number; + active: number; +} diff --git a/packages/common/src/types/Token.ts b/packages/common/src/types/Token.ts index f88b0b8bf2..d41bfe13a0 100644 --- a/packages/common/src/types/Token.ts +++ b/packages/common/src/types/Token.ts @@ -1,8 +1,7 @@ /** * A token within a text editor */ -import type { Range } from "./Range"; -import type { RangeOffsets } from "./RangeOffsets"; +import type { Range, RangeOffsets } from "./Range"; import type { TextEditor } from "./TextEditor"; /** diff --git a/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts b/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts index da06d0b926..f43cc2934f 100644 --- a/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts +++ b/packages/cursorless-engine/src/testUtil/createTestEnvironment.ts @@ -5,11 +5,9 @@ import type { MessageType, ScopeProvider, } from "@cursorless/common"; -import { FakeIDE, InMemoryTextDocument, Selection } from "@cursorless/common"; +import { FakeIDE, InMemoryTextEditor } from "@cursorless/common"; import { FileSystemRawTreeSitterQueryProvider } from "@cursorless/node-common"; -import { URI } from "vscode-uri"; import { createCursorlessEngine } from ".."; -import { TestTextEditor } from "./TestTextEditor"; import { TestFileSystem } from "./TestFileSystem"; import { TestTreeSitter } from "./TestTreeSitter"; @@ -39,7 +37,7 @@ export async function createTestEnvironment(): Promise { }); const openNewEditor = async (content: string, languageId: string) => { - const editor = createNewEditor(content, languageId); + const editor = new InMemoryTextEditor({ ide, languageId, content }); await languageDefinitions.loadLanguage(languageId); return editor; }; @@ -47,21 +45,6 @@ export async function createTestEnvironment(): Promise { return { openNewEditor, scopeProvider }; } -let nextId = 0; - -function createNewEditor( - content: string, - languageId: string, -): EditableTextEditor { - const id = String(nextId++); - const uri = URI.parse(`talon-js://${id}`); - const document = new InMemoryTextDocument(uri, languageId, content); - const visibleRanges = [document.range]; - const selections = [new Selection(0, 0, 0, 0)]; - const editor = new TestTextEditor(id, document, visibleRanges, selections); - return editor; -} - class TestMessages implements Messages { showMessage( type: MessageType, diff --git a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts index c6d5bfb206..9fb4ba49f5 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/TalonJsIDE.ts @@ -4,9 +4,9 @@ import type { Configuration, Disposable, EditableTextEditor, + EmittableIDE, FlashDescriptor, GeneralizedRange, - IDE, InputBoxOptions, KeyValueStore, Listener, @@ -22,20 +22,18 @@ import type { TextEditorVisibleRangesChangeEvent, WorkspaceFolder, } from "@cursorless/common"; -import { Notifier } from "@cursorless/common"; +import { InMemoryTextEditor, Notifier } from "@cursorless/common"; import { pull } from "lodash-es"; import type { Talon } from "../types/talon.types"; -import type { EditorState } from "../types/types"; -import { createTextEditor } from "./createTextEditor"; +import type { EditorEdit, EditorState } from "../types/types"; import { flashRanges } from "./flashRanges"; import { TalonJsCapabilities } from "./TalonJsCapabilities"; import { TalonJsClipboard } from "./TalonJsClipboard"; import { TalonJsConfiguration } from "./TalonJsConfiguration"; -import { TalonJsTextEditor } from "./TalonJsTextEditor"; import { TalonJsKeyValueStore } from "./TalonJsKeyValueStore"; import { TalonJsMessages } from "./TalonJsMessages"; -export class TalonJsIDE implements IDE { +export class TalonJsIDE implements EmittableIDE { configuration: Configuration; messages: Messages; keyValueStore: KeyValueStore; @@ -47,6 +45,10 @@ export class TalonJsIDE implements IDE { private onDidChangeTextDocumentNotifier: Notifier<[TextDocumentChangeEvent]> = new Notifier(); + private onDidChangeTextEditorSelectionNotifier: Notifier< + [TextEditorSelectionChangeEvent] + > = new Notifier(); + constructor( private talon: Talon, public runMode: RunMode, @@ -87,14 +89,20 @@ export class TalonJsIDE implements IDE { } getEditableTextEditor(editor: TextEditor): EditableTextEditor { - if (editor instanceof TalonJsTextEditor) { + if (editor instanceof InMemoryTextEditor) { return editor; } throw Error(`Unsupported text editor type: ${editor}`); } updateTextEditors(editorState: EditorState) { - this.editors = [createTextEditor(this.talon, this, editorState)]; + const editor = new InMemoryTextEditor({ + ide: this, + languageId: editorState.languageId, + content: editorState.text, + selections: editorState.selections, + }); + this.editors = [editor]; } async findInDocument( @@ -159,9 +167,47 @@ export class TalonJsIDE implements IDE { } emitDidChangeTextDocument(event: TextDocumentChangeEvent) { + const { document, contentChanges } = event; + + const editorEdit: EditorEdit = { + text: document.getText(), + changes: contentChanges.map((change) => ({ + rangeOffset: change.rangeOffset, + rangeLength: change.rangeLength, + text: change.text, + })), + }; + + this.talon.actions.user.cursorless_everywhere_edit_text(editorEdit); + this.onDidChangeTextDocumentNotifier.notifyListeners(event); } + onDidChangeTextEditorSelection( + listener: (event: TextEditorSelectionChangeEvent) => void, + ): Disposable { + return this.onDidChangeTextEditorSelectionNotifier.registerListener( + listener, + ); + } + + emitDidChangeTextEditorSelection( + event: TextEditorSelectionChangeEvent, + ): void { + const { document } = event.textEditor; + + const selectionOffsets = event.selections.map((selection) => ({ + anchor: document.offsetAt(selection.anchor), + active: document.offsetAt(selection.active), + })); + + this.talon.actions.user.cursorless_everywhere_set_selections( + selectionOffsets, + ); + + this.onDidChangeTextEditorSelectionNotifier.notifyListeners(event); + } + onDidOpenTextDocument( _listener: (document: TextDocument) => void, ): Disposable { @@ -186,12 +232,6 @@ export class TalonJsIDE implements IDE { return { dispose: () => {} }; } - onDidChangeTextEditorSelection( - _listener: (event: TextEditorSelectionChangeEvent) => void, - ): Disposable { - return { dispose: () => {} }; - } - onDidChangeTextEditorVisibleRanges( _listener: (event: TextEditorVisibleRangesChangeEvent) => void, ): Disposable { diff --git a/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts b/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts deleted file mode 100644 index 2b59ed631e..0000000000 --- a/packages/cursorless-everywhere-talon-core/src/ide/createTextEditor.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { TextDocument } from "@cursorless/common"; -import { InMemoryTextDocument, Selection } from "@cursorless/common"; -import { URI } from "vscode-uri"; -import type { Talon } from "../types/talon.types"; -import type { EditorState, SelectionOffsets } from "../types/types"; -import { TalonJsTextEditor } from "./TalonJsTextEditor"; -import type { TalonJsIDE } from "./TalonJsIDE"; - -let nextId = 0; - -export function createTextEditor( - talon: Talon, - ide: TalonJsIDE, - editorState: EditorState, -): TalonJsTextEditor { - const id = String(nextId++); - const uri = URI.parse(`talon-js://${id}`); - const languageId = editorState.languageId ?? "plaintext"; - const document = new InMemoryTextDocument(uri, languageId, editorState.text); - const visibleRanges = [document.range]; - const selections = editorState.selections.map((selection) => - createSelection(document, selection), - ); - - return new TalonJsTextEditor( - talon, - ide, - id, - document, - visibleRanges, - selections, - ); -} - -export function createSelection( - document: TextDocument, - selection: SelectionOffsets, -) { - const anchor = document.positionAt(selection.anchor); - const active = document.positionAt(selection.active); - return new Selection(anchor, active); -} diff --git a/packages/cursorless-everywhere-talon-core/src/ide/flashRanges.ts b/packages/cursorless-everywhere-talon-core/src/ide/flashRanges.ts index 124262d1c1..d9d47c635f 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/flashRanges.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/flashRanges.ts @@ -1,6 +1,5 @@ -import type { FlashDescriptor } from "@cursorless/common"; +import type { FlashDescriptor, RangeOffsets } from "@cursorless/common"; import type { Talon } from "../types/talon.types"; -import type { RangeOffsets } from "../types/types"; import { toCharacterRangeOffsets } from "./toCharacterRangeOffsets"; export function flashRanges( diff --git a/packages/cursorless-everywhere-talon-core/src/ide/setSelections.ts b/packages/cursorless-everywhere-talon-core/src/ide/setSelections.ts deleted file mode 100644 index 550fc2f2a2..0000000000 --- a/packages/cursorless-everywhere-talon-core/src/ide/setSelections.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { Selection, TextDocument } from "@cursorless/common"; -import type { Talon } from "../types/talon.types"; - -export function setSelections( - talon: Talon, - document: TextDocument, - selections: Selection[], -): Promise { - const selectionOffsets = selections.map((selection) => ({ - anchor: document.offsetAt(selection.anchor), - active: document.offsetAt(selection.active), - })); - - talon.actions.user.cursorless_everywhere_set_selections(selectionOffsets); - - return Promise.resolve(); -} diff --git a/packages/cursorless-everywhere-talon-core/src/ide/talonJsPerformEdits.ts b/packages/cursorless-everywhere-talon-core/src/ide/talonJsPerformEdits.ts deleted file mode 100644 index 5929686e9c..0000000000 --- a/packages/cursorless-everywhere-talon-core/src/ide/talonJsPerformEdits.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { Edit, InMemoryTextDocument } from "@cursorless/common"; -import type { Talon } from "../types/talon.types"; -import type { EditorEdit } from "../types/types"; -import type { TalonJsIDE } from "./TalonJsIDE"; - -export function talonJsPerformEdits( - talon: Talon, - ide: TalonJsIDE, - document: InMemoryTextDocument, - edits: Edit[], -) { - const changes = document.edit(edits); - - const editorEdit: EditorEdit = { - text: document.text, - changes: changes.map((change) => ({ - rangeOffset: change.rangeOffset, - rangeLength: change.rangeLength, - text: change.text, - })), - }; - - talon.actions.user.cursorless_everywhere_edit_text(editorEdit); - - ide.emitDidChangeTextDocument({ - document, - contentChanges: changes, - }); -} diff --git a/packages/cursorless-everywhere-talon-core/src/ide/toCharacterRangeOffsets.ts b/packages/cursorless-everywhere-talon-core/src/ide/toCharacterRangeOffsets.ts index 2feedd6829..3b32fac3af 100644 --- a/packages/cursorless-everywhere-talon-core/src/ide/toCharacterRangeOffsets.ts +++ b/packages/cursorless-everywhere-talon-core/src/ide/toCharacterRangeOffsets.ts @@ -1,5 +1,8 @@ -import type { GeneralizedRange, TextEditor } from "@cursorless/common"; -import type { RangeOffsets } from "../types/types"; +import type { + GeneralizedRange, + RangeOffsets, + TextEditor, +} from "@cursorless/common"; export function toCharacterRangeOffsets( editor: TextEditor, diff --git a/packages/cursorless-everywhere-talon-core/src/types/talon.types.ts b/packages/cursorless-everywhere-talon-core/src/types/talon.types.ts index 2381484745..65f2d11fd8 100644 --- a/packages/cursorless-everywhere-talon-core/src/types/talon.types.ts +++ b/packages/cursorless-everywhere-talon-core/src/types/talon.types.ts @@ -1,9 +1,5 @@ -import type { - RangeOffsets, - EditorEdit, - EditorState, - SelectionOffsets, -} from "./types"; +import type { RangeOffsets, SelectionOffsets } from "@cursorless/common"; +import type { EditorEdit, EditorState } from "./types"; export type TalonNamespace = "user"; diff --git a/packages/cursorless-everywhere-talon-core/src/types/types.ts b/packages/cursorless-everywhere-talon-core/src/types/types.ts index ba2c8c0fb0..65c1b83387 100644 --- a/packages/cursorless-everywhere-talon-core/src/types/types.ts +++ b/packages/cursorless-everywhere-talon-core/src/types/types.ts @@ -3,22 +3,12 @@ import type { CommandResponse, IDE, NormalizedIDE, + SelectionOffsets, TestHelpers, } from "@cursorless/common"; import type { StoredTargetMap } from "@cursorless/cursorless-engine"; import type { TalonJsIDE } from "../ide/TalonJsIDE"; -export interface SelectionOffsets { - // Document offsets - anchor: number; - active: number; -} - -export interface RangeOffsets { - start: number; - end: number; -} - export interface EditorState { text: string; languageId?: string; diff --git a/packages/cursorless-everywhere-talon-e2e/src/talonMock.ts b/packages/cursorless-everywhere-talon-e2e/src/talonMock.ts index 7d9c97bd13..459c719381 100644 --- a/packages/cursorless-everywhere-talon-e2e/src/talonMock.ts +++ b/packages/cursorless-everywhere-talon-e2e/src/talonMock.ts @@ -1,8 +1,7 @@ +import type { RangeOffsets, SelectionOffsets } from "@cursorless/common"; import type { - RangeOffsets, EditorEdit, EditorState, - SelectionOffsets, Talon, TalonActions, TalonContext,