diff --git a/src/commands/preview.ts b/src/commands/preview.ts index 070ce88..3a14b49 100644 --- a/src/commands/preview.ts +++ b/src/commands/preview.ts @@ -11,9 +11,12 @@ import { oilPreviewProvider } from "../providers/providers"; import { logger } from "../logger"; import { isUpdatePreviewDisabled } from "./disableUpdatePreview"; -export async function preview(overrideEnabled: boolean = false) { +export async function preview( + overrideEnabled: boolean = false, + editorOverride?: vscode.TextEditor +) { logger.trace("Previewing file or directory..."); - const activeEditor = vscode.window.activeTextEditor; + const activeEditor = editorOverride ?? vscode.window.activeTextEditor; if (!activeEditor) { vscode.window.showErrorMessage("No active editor found."); @@ -58,8 +61,15 @@ export async function preview(overrideEnabled: boolean = false) { targetPath = path.join(uriPathToDiskPath(currentFolderPath), fileName); } + await previewTargetPath(targetPath, overrideEnabled); +} + +export async function previewTargetPath( + targetPath: string, + overrideEnabled: boolean = false +) { if (!fs.existsSync(targetPath)) { - vscode.window.showErrorMessage(`"${fileName}" does not exist.`); + vscode.window.showErrorMessage(`"${path.basename(targetPath)}" does not exist.`); return; } @@ -177,6 +187,7 @@ async function previewDirectory(directoryPath: string) { const previewUri = vscode.Uri.parse( `${OIL_PREVIEW_SCHEME}://oil-preview/${previewName}` ); + const previousPreviewUri = getPreviewState().previewUri; // Write content to the virtual file oilPreviewProvider.writeFile(previewUri, Buffer.from(directoryContent)); @@ -203,6 +214,20 @@ async function previewDirectory(directoryPath: string) { }; setPreviewState(newPreviewState); + if (previousPreviewUri && previousPreviewUri.toString() !== previewUri.toString()) { + const previousPreviewTab = vscode.window.tabGroups.all + .flatMap((group) => group.tabs) + .find( + (tab) => + tab.input instanceof vscode.TabInputText && + tab.input.uri.toString() === previousPreviewUri.toString() + ); + if (previousPreviewTab) { + await vscode.window.tabGroups.close(previousPreviewTab); + } + oilPreviewProvider.delete(previousPreviewUri); + } + // Start listening for cursor movements if not already listening if (!getPreviewState().cursorListenerDisposable) { logger.trace("Starting cursor listener for preview updates..."); diff --git a/src/commands/select.ts b/src/commands/select.ts index acbd917..31035f4 100644 --- a/src/commands/select.ts +++ b/src/commands/select.ts @@ -14,7 +14,7 @@ import { updateDisableUpdatePreview } from "./disableUpdatePreview"; import { logger } from "../logger"; import { onDidSaveTextDocument } from "../handlers/onDidSaveTextDocument"; import { getPreviewState } from "../state/previewState"; -import { preview } from "./preview"; +import { preview, previewTargetPath } from "./preview"; const cursorInitChar = 5; // 5 characters for "/000 " @@ -141,7 +141,7 @@ export async function select({ const editor = await vscode.window.showTextDocument(newDoc, { viewColumn: viewColumn || activeEditor.viewColumn, preview: false, - preserveFocus: activeEditor.document.isDirty, + preserveFocus: false, }); // Close the old document after the new one is shown (only if same column) @@ -156,7 +156,11 @@ export async function select({ // Use setTimeout to ensure the editor content is updated setTimeout(() => { - const editorForSelection = vscode.window.activeTextEditor; + // Use the editor returned by showTextDocument instead of the global + // activeTextEditor. Opening/updating the side preview can briefly make + // another editor active, which makes the preview-by-default flow racey + // in CI and leaves the cursor on "../". + const editorForSelection = editor; if (editorForSelection) { // Find the line with the directory name (with trailing slash) const docText = editorForSelection.document.getText(); @@ -191,9 +195,17 @@ export async function select({ // Default to first line if not found editorForSelection.selection = new vscode.Selection(0, 0, 0, 0); } - updateDisableUpdatePreview(false); if (getPreviewState().previewEnabled) { - preview(true); + void previewTargetPath(currentFileDiskPath, true) + .catch((error) => { + logger.error( + "Failed to update preview after navigating up:", + error + ); + }) + .finally(() => updateDisableUpdatePreview(false)); + } else { + updateDisableUpdatePreview(false); } } }, 50); @@ -204,7 +216,12 @@ export async function select({ updateDisableUpdatePreview(false); // Manually update preview if enabled if (getPreviewState().previewEnabled) { - preview(true); + void preview(true, editor).catch((error) => { + logger.error( + "Failed to update preview after entering directory:", + error + ); + }); } }, 50); }