diff --git a/src/rmarkdown/index.ts b/src/rmarkdown/index.ts index 061226696..4fa2818f4 100644 --- a/src/rmarkdown/index.ts +++ b/src/rmarkdown/index.ts @@ -36,7 +36,10 @@ export class RMarkdownCodeLensProvider implements vscode.CodeLensProvider { private readonly currentCellBottom: vscode.TextEditorDecorationType; private onDidChangeTextEditorSelectionHandler: vscode.Disposable | undefined; - constructor() { + constructor( + private readonly getVisibleTextEditors: () => readonly vscode.TextEditor[] = () => + vscode.window.visibleTextEditors, + ) { this.decoration = vscode.window.createTextEditorDecorationType({ isWholeLine: true, backgroundColor: config().get('rmarkdown.chunkBackgroundColor'), @@ -76,7 +79,7 @@ export class RMarkdownCodeLensProvider implements vscode.CodeLensProvider { } private highlightCurrentChunk(chunks: RMarkdownChunk[], document: vscode.TextDocument) { - for (const editor of vscode.window.visibleTextEditors) { + for (const editor of this.getVisibleTextEditors()) { if (editor.document.uri.toString() === document.uri.toString()) { const lines = document.getText().split(/\r?\n/); const currentLine = editor.selection.active.line; @@ -102,6 +105,9 @@ export class RMarkdownCodeLensProvider implements vscode.CodeLensProvider { ), ); editor.setDecorations(this.currentCellBottom, [currentChunkEnd]); + } else { + editor.setDecorations(this.currentCellTop, []); + editor.setDecorations(this.currentCellBottom, []); } } } @@ -109,7 +115,7 @@ export class RMarkdownCodeLensProvider implements vscode.CodeLensProvider { private highlightChunks(chunks: RMarkdownChunk[], document: vscode.TextDocument) { const chunkRanges = chunks.map((chunk) => chunk.chunkRange); - for (const editor of vscode.window.visibleTextEditors) { + for (const editor of this.getVisibleTextEditors()) { if (editor.document.uri.toString() === document.uri.toString()) { editor.setDecorations(this.decoration, chunkRanges); } diff --git a/src/test/suite/rmarkdownDecoration.test.ts b/src/test/suite/rmarkdownDecoration.test.ts new file mode 100644 index 000000000..0f756cfb5 --- /dev/null +++ b/src/test/suite/rmarkdownDecoration.test.ts @@ -0,0 +1,31 @@ +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +import { RMarkdownCodeLensProvider } from '../../rmarkdown'; + +suite('R Markdown chunk decorations', () => { + test('clears current chunk borders when the document has no chunks', async () => { + const document = { + languageId: 'r', + uri: vscode.Uri.parse('untitled:rmarkdown-decoration-test'), + getText: () => 'x <- 1', + } as vscode.TextDocument; + + const decorationCalls: Array = []; + const editor = { + document, + selection: new vscode.Selection(0, 0, 0, 0), + setDecorations: ( + _decorationType: vscode.TextEditorDecorationType, + ranges: readonly vscode.Range[], + ) => decorationCalls.push(ranges), + } as unknown as vscode.TextEditor; + const provider = new RMarkdownCodeLensProvider(() => [editor]); + try { + provider.provideCodeLenses(document, new vscode.CancellationTokenSource().token); + assert.deepStrictEqual(decorationCalls, [[], []]); + } finally { + provider.dispose(); + } + }); +});