diff --git a/src/commands.ts b/src/commands.ts index 79f4303e59..9ed29e4b64 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -1798,9 +1798,13 @@ ${contents} }; context.subscriptions.push( - vscode.commands.registerCommand('pr.markFileAsViewed', async (treeNode: FileChangeNode | vscode.Uri | undefined) => { + vscode.commands.registerCommand('pr.markFileAsViewed', async (treeNodeOrOptions: FileChangeNode | vscode.Uri | { dontCloseFile: boolean } | undefined, options?: { dontCloseFile: boolean }) => { try { - if (treeNode === undefined) { + let treeNode: FileChangeNode | vscode.Uri | undefined; + if (treeNodeOrOptions instanceof FileChangeNode || treeNodeOrOptions instanceof vscode.Uri) { + treeNode = treeNodeOrOptions; + } else { + options = treeNodeOrOptions ?? options; // Use the active editor to enable keybindings treeNode = vscode.window.activeTextEditor?.document.uri; } @@ -1810,16 +1814,18 @@ ${contents} } else if (treeNode) { // When the argument is a uri it came from the editor menu and we should also close the file // Do the close first to improve perceived performance of marking as viewed. - const tab = vscode.window.tabGroups.activeTabGroup.activeTab; - if (tab) { - let compareUri: vscode.Uri | undefined = undefined; - if (tab.input instanceof vscode.TabInputTextDiff) { - compareUri = tab.input.modified; - } else if (tab.input instanceof vscode.TabInputText) { - compareUri = tab.input.uri; - } - if (compareUri && treeNode.toString() === compareUri.toString()) { - vscode.window.tabGroups.close(tab); + if (!options?.dontCloseFile) { + const tab = vscode.window.tabGroups.activeTabGroup.activeTab; + if (tab) { + let compareUri: vscode.Uri | undefined = undefined; + if (tab.input instanceof vscode.TabInputTextDiff) { + compareUri = tab.input.modified; + } else if (tab.input instanceof vscode.TabInputText) { + compareUri = tab.input.uri; + } + if (compareUri && treeNode.toString() === compareUri.toString()) { + vscode.window.tabGroups.close(tab); + } } } diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 3038c33295..e9c45abbe2 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -1,7 +1,36 @@ import { default as assert } from 'assert'; +import * as vscode from 'vscode'; import { parseDiffHunk } from '../common/diffHunk'; describe('Extension Tests', function () { + describe('markFileAsViewed', () => { + async function assertCommandKeepsTabOpen(getArgs: (uri: vscode.Uri) => unknown[]) { + const document = await vscode.workspace.openTextDocument({ content: 'test' }); + await vscode.window.showTextDocument(document); + const tab = vscode.window.tabGroups.activeTabGroup.activeTab; + assert.ok(tab); + + try { + await vscode.commands.executeCommand('pr.markFileAsViewed', ...getArgs(document.uri)); + assert.strictEqual(vscode.window.tabGroups.activeTabGroup.activeTab, tab); + } finally { + await vscode.window.tabGroups.close(tab); + } + } + + it('should keep the active editor open with keybinding options', async () => { + await assertCommandKeepsTabOpen(() => [{ dontCloseFile: true }]); + }); + + it('should keep the active editor open with options as the second argument', async () => { + await assertCommandKeepsTabOpen(() => [undefined, { dontCloseFile: true }]); + }); + + it('should keep the active editor open with a URI and options', async () => { + await assertCommandKeepsTabOpen(uri => [uri, { dontCloseFile: true }]); + }); + }); + describe('parseDiffHunk', () => { it('should handle empty string', () => { const diffHunk = parseDiffHunk('');