diff --git a/src/core/HatAllocator.ts b/src/core/HatAllocator.ts index b9c47c5b6fa..f623731f492 100644 --- a/src/core/HatAllocator.ts +++ b/src/core/HatAllocator.ts @@ -24,6 +24,7 @@ export class HatAllocator { this.addDecorationsDebounced = this.addDecorationsDebounced.bind(this); this.toggleDecorations = this.toggleDecorations.bind(this); + this.clearEditorDecorations = this.clearEditorDecorations.bind(this); this.disposalFunctions.push( graph.decorations.registerDecorationChangeListener( diff --git a/src/core/HatTokenMap.ts b/src/core/HatTokenMap.ts index 4a0b0ebadae..44ed544bc2a 100644 --- a/src/core/HatTokenMap.ts +++ b/src/core/HatTokenMap.ts @@ -1,6 +1,5 @@ import { HatStyleName } from "./constants"; import { Graph } from "../typings/Types"; -import { Signal } from "../util/getExtensionApi"; import { IndividualHatMap, ReadOnlyHatMap } from "./IndividualHatMap"; import { HatAllocator } from "./HatAllocator"; diff --git a/src/test/mockPrePhraseGetVersion.ts b/src/test/mockPrePhraseGetVersion.ts index 6ecbcc5ee22..fc9894f3e85 100644 --- a/src/test/mockPrePhraseGetVersion.ts +++ b/src/test/mockPrePhraseGetVersion.ts @@ -1,5 +1,4 @@ import * as sinon from "sinon"; -import { Signal } from "../util/getExtensionApi"; import { Graph } from "../typings/Types"; export function mockPrePhraseGetVersion( @@ -8,12 +7,9 @@ export function mockPrePhraseGetVersion( ) { sinon.replaceGetter(graph, "commandServerApi", () => ({ signals: { - getNamedSignal(name: string) { - return {} as Signal; - }, prePhrase: { getVersion, - } as Signal, + }, }, })); } diff --git a/src/test/openNewEditor.ts b/src/test/openNewEditor.ts new file mode 100644 index 00000000000..d05a3d54ba4 --- /dev/null +++ b/src/test/openNewEditor.ts @@ -0,0 +1,18 @@ +import * as vscode from "vscode"; +import { getParseTreeApi } from "../util/getExtensionApi"; + +export async function openNewEditor( + content: string, + language: string = "plaintext" +) { + await vscode.commands.executeCommand("workbench.action.closeAllEditors"); + + const document = await vscode.workspace.openTextDocument({ + language, + content, + }); + + await (await getParseTreeApi()).loadLanguage(language); + + return await vscode.window.showTextDocument(document); +} diff --git a/src/test/suite/prePhraseSnapshot.test.ts b/src/test/suite/prePhraseSnapshot.test.ts index ceee49f93c7..108d1fc266e 100644 --- a/src/test/suite/prePhraseSnapshot.test.ts +++ b/src/test/suite/prePhraseSnapshot.test.ts @@ -4,6 +4,7 @@ import * as sinon from "sinon"; import { getCursorlessApi } from "../../util/getExtensionApi"; import { selectionToPlainObject } from "../../testUtil/toPlainObject"; import { mockPrePhraseGetVersion } from "../mockPrePhraseGetVersion"; +import { openNewEditor } from "../openNewEditor"; /** * The selections we expect when the pre-phrase snapshot is used @@ -39,16 +40,9 @@ async function runTest( multiplePhrases: boolean, expectedSelections: vscode.Selection[] ) { - const initialContent = "Hello world testing whatever"; - const graph = (await getCursorlessApi()).graph!; - await vscode.commands.executeCommand("workbench.action.closeAllEditors"); - const document = await vscode.workspace.openTextDocument({ - language: "plaintext", - content: initialContent, - }); - const editor = await vscode.window.showTextDocument(document); + const editor = await openNewEditor("Hello world testing whatever"); editor.selections = [new vscode.Selection(0, 0, 0, 0)]; diff --git a/src/test/suite/recorded.test.ts b/src/test/suite/recorded.test.ts index 3edfb813ac1..9096d375449 100644 --- a/src/test/suite/recorded.test.ts +++ b/src/test/suite/recorded.test.ts @@ -17,16 +17,13 @@ import { SerializedMarks, } from "../../testUtil/toPlainObject"; import { walkFilesSync } from "../../testUtil/walkSync"; -import { - getCursorlessApi, - getParseTreeApi, - Signal, -} from "../../util/getExtensionApi"; +import { getCursorlessApi } from "../../util/getExtensionApi"; import { enableDebugLog } from "../../util/debug"; import { extractTargetedMarks } from "../../testUtil/extractTargetedMarks"; import { ReadOnlyHatMap } from "../../core/IndividualHatMap"; import { doTargetsUsePrePhraseSnapshot } from "../../util/doTargetsUsePrePhraseSnapshot"; import { mockPrePhraseGetVersion } from "../mockPrePhraseGetVersion"; +import { openNewEditor } from "../openNewEditor"; function createPosition(position: PositionPlainObject) { return new vscode.Position(position.line, position.character); @@ -61,15 +58,12 @@ async function runTest(file: string) { const excludeFields: string[] = []; const cursorlessApi = await getCursorlessApi(); - const parseTreeApi = await getParseTreeApi(); const graph = cursorlessApi.graph!; - await vscode.commands.executeCommand("workbench.action.closeAllEditors"); - const document = await vscode.workspace.openTextDocument({ - language: fixture.languageId, - content: fixture.initialState.documentContents, - }); - const editor = await vscode.window.showTextDocument(document); + const editor = await openNewEditor( + fixture.initialState.documentContents, + fixture.languageId + ); if (!fixture.initialState.documentContents.includes("\n")) { await editor.edit((editBuilder) => { @@ -77,8 +71,6 @@ async function runTest(file: string) { }); } - await parseTreeApi.loadLanguage(document.languageId); - editor.selections = fixture.initialState.selections.map(createSelection); if (fixture.initialState.thatMark) { diff --git a/src/test/suite/toggleDecorations.test.ts b/src/test/suite/toggleDecorations.test.ts new file mode 100644 index 00000000000..38173e6afe8 --- /dev/null +++ b/src/test/suite/toggleDecorations.test.ts @@ -0,0 +1,36 @@ +import * as assert from "assert"; +import * as vscode from "vscode"; +import * as sinon from "sinon"; +import { getCursorlessApi } from "../../util/getExtensionApi"; +import { openNewEditor } from "../openNewEditor"; + +suite("toggle decorations", async function () { + this.timeout("100s"); + this.retries(3); + + teardown(() => { + sinon.restore(); + }); + + test("toggle decorations", () => runTest()); +}); + +async function runTest() { + const { hatTokenMap } = (await getCursorlessApi()).graph!; + + await openNewEditor("Hello world testing whatever"); + + // Check that hats appear by default + await hatTokenMap.addDecorations(); + assert((await hatTokenMap.getReadableMap(false)).getEntries().length !== 0); + + // Check that hats disappear when turned off + await vscode.commands.executeCommand("cursorless.toggleDecorations"); + await hatTokenMap.addDecorations(); + assert((await hatTokenMap.getReadableMap(false)).getEntries().length === 0); + + // Check that hats reappear when turned back on + await vscode.commands.executeCommand("cursorless.toggleDecorations"); + await hatTokenMap.addDecorations(); + assert((await hatTokenMap.getReadableMap(false)).getEntries().length !== 0); +} diff --git a/src/util/getExtensionApi.ts b/src/util/getExtensionApi.ts index 86ac985609e..f2aea6d43e0 100644 --- a/src/util/getExtensionApi.ts +++ b/src/util/getExtensionApi.ts @@ -18,14 +18,13 @@ export interface ParseTreeApi { loadLanguage: (languageId: string) => Promise; } -export interface Signal { +export interface InboundSignal { getVersion(): Promise; } export interface CommandServerApi { signals: { - getNamedSignal: (name: string) => Signal; - prePhrase: Signal; + prePhrase: InboundSignal; }; }