From 690d416852f9007e16946cf94cd4ff32087c2e71 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 16:26:43 -0700 Subject: [PATCH 01/11] fix: Decorator perf and navigation flashing --- src/commands/select.ts | 92 +++++++++++++++++++++++++++++++++--------- src/decorations.ts | 6 +-- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/src/commands/select.ts b/src/commands/select.ts index ea43211..57e1dba 100644 --- a/src/commands/select.ts +++ b/src/commands/select.ts @@ -104,18 +104,44 @@ export async function select({ const newDoc = await vscode.workspace.openTextDocument(newUri); await vscode.languages.setTextDocumentLanguage(newDoc, "oil"); - // Show the new document in the same editor - const editor = await vscode.window.showTextDocument(newDoc, { - viewColumn: viewColumn || activeEditor.viewColumn, - preview: false, - }); - + let editor: vscode.TextEditor; if (!viewColumn) { - // Close the old document - await vscode.window.showTextDocument(oldUri); - await vscode.commands.executeCommand( - "workbench.action.revertAndCloseActiveEditor" - ); + // For same column, show new document first, then close old one to minimize flash + editor = await vscode.window.showTextDocument(newDoc, { + viewColumn: activeEditor.viewColumn, + preview: false, + }); + + // Close the old document after the new one is shown + // Use a small delay to ensure smooth transition + setTimeout(async () => { + try { + // Find and close the old document tab + const tabs = vscode.window.tabGroups.all.flatMap( + (group) => group.tabs + ); + const oldTab = tabs.find( + (tab) => + tab.input instanceof vscode.TabInputText && + tab.input.uri.toString() === oldUri.toString() + ); + if (oldTab) { + await vscode.window.tabGroups.close(oldTab); + } + } catch (error) { + // Fallback method if tab API fails + await vscode.window.showTextDocument(oldUri); + await vscode.commands.executeCommand( + "workbench.action.revertAndCloseActiveEditor" + ); + } + }, 50); + } else { + // For different column, show new document (old one stays open) + editor = await vscode.window.showTextDocument(newDoc, { + viewColumn: viewColumn, + preview: false, + }); } // Position cursor appropriately @@ -220,16 +246,44 @@ export async function select({ const fileUri = vscode.Uri.file(targetPath); const fileDoc = await vscode.workspace.openTextDocument(fileUri); const viewColumnToUse = viewColumn || activeEditor.viewColumn; + if (!viewColumn) { - await vscode.window.showTextDocument(activeEditor.document.uri); - await vscode.commands.executeCommand( - "workbench.action.revertAndCloseActiveEditor" - ); + // For same column, show new document then close old one + await vscode.window.showTextDocument(fileDoc, { + viewColumn: viewColumnToUse, + preview: false, + }); + + // Close the old oil document after opening the new file + setTimeout(async () => { + try { + // Find and close the old document tab + const tabs = vscode.window.tabGroups.all.flatMap( + (group) => group.tabs + ); + const oldTab = tabs.find( + (tab) => + tab.input instanceof vscode.TabInputText && + tab.input.uri.toString() === activeEditor.document.uri.toString() + ); + if (oldTab) { + await vscode.window.tabGroups.close(oldTab); + } + } catch (error) { + // Fallback method if tab API fails + await vscode.window.showTextDocument(activeEditor.document.uri); + await vscode.commands.executeCommand( + "workbench.action.revertAndCloseActiveEditor" + ); + } + }, 50); + } else { + // For different column, show in new column (old one stays open) + await vscode.window.showTextDocument(fileDoc, { + viewColumn: viewColumnToUse, + preview: false, + }); } - await vscode.window.showTextDocument(fileDoc, { - viewColumn: viewColumnToUse, - preview: false, - }); updateDisableUpdatePreview(false); } catch (error) { vscode.window.showErrorMessage(`Failed to open file.`); diff --git a/src/decorations.ts b/src/decorations.ts index 29feb96..d2b229e 100644 --- a/src/decorations.ts +++ b/src/decorations.ts @@ -4,11 +4,7 @@ import { getNerdFontFileIcon } from "./nerd-fonts"; // Create decoration type for hidden prefix const hiddenPrefixDecoration = vscode.window.createTextEditorDecorationType({ - textDecoration: "none; display: none", - opacity: "0", - letterSpacing: "-100em", - fontWeight: "normal", - fontStyle: "normal", + textDecoration: "none; font-size: 0pt", rangeBehavior: vscode.DecorationRangeBehavior.ClosedClosed, }); From 478e8561a7331b36b789e71826348a9474405566 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:04:18 -0700 Subject: [PATCH 02/11] test: Add wait for 100ms --- src/test/extension.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 9408d37..86b5280 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -373,6 +373,8 @@ suite("oil.code", () => { await saveFile(); + await sleep(100); + await waitForDocumentText(["/000 ../", "/003 oil-file.md"]); await assertProjectFileStructure(["sub-dir/", " oil-file.md"]); From cf5b6252a7ed8ad0d98de7997c2a3182f41def5d Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:31:14 -0700 Subject: [PATCH 03/11] test: simplifying select --- src/commands/select.ts | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/commands/select.ts b/src/commands/select.ts index 57e1dba..835617a 100644 --- a/src/commands/select.ts +++ b/src/commands/select.ts @@ -104,14 +104,11 @@ export async function select({ const newDoc = await vscode.workspace.openTextDocument(newUri); await vscode.languages.setTextDocumentLanguage(newDoc, "oil"); - let editor: vscode.TextEditor; + const editor = await vscode.window.showTextDocument(newDoc, { + viewColumn: viewColumn || activeEditor.viewColumn, + preview: false, + }); if (!viewColumn) { - // For same column, show new document first, then close old one to minimize flash - editor = await vscode.window.showTextDocument(newDoc, { - viewColumn: activeEditor.viewColumn, - preview: false, - }); - // Close the old document after the new one is shown // Use a small delay to ensure smooth transition setTimeout(async () => { @@ -136,12 +133,6 @@ export async function select({ ); } }, 50); - } else { - // For different column, show new document (old one stays open) - editor = await vscode.window.showTextDocument(newDoc, { - viewColumn: viewColumn, - preview: false, - }); } // Position cursor appropriately @@ -248,12 +239,6 @@ export async function select({ const viewColumnToUse = viewColumn || activeEditor.viewColumn; if (!viewColumn) { - // For same column, show new document then close old one - await vscode.window.showTextDocument(fileDoc, { - viewColumn: viewColumnToUse, - preview: false, - }); - // Close the old oil document after opening the new file setTimeout(async () => { try { @@ -277,13 +262,12 @@ export async function select({ ); } }, 50); - } else { - // For different column, show in new column (old one stays open) - await vscode.window.showTextDocument(fileDoc, { - viewColumn: viewColumnToUse, - preview: false, - }); } + // For different column, show in new column (old one stays open) + await vscode.window.showTextDocument(fileDoc, { + viewColumn: viewColumnToUse, + preview: false, + }); updateDisableUpdatePreview(false); } catch (error) { vscode.window.showErrorMessage(`Failed to open file.`); From f884406b3cb2d1bc83983f97948f3d1378ab5c57 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:37:08 -0700 Subject: [PATCH 04/11] test: longer sleep --- src/test/extension.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 86b5280..c271d0a 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -362,7 +362,7 @@ suite("oil.code", () => { editor.selection = new vscode.Selection(position3, position3); await vscode.commands.executeCommand("oil-code.select"); - await sleep(100); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -477,7 +477,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(100); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); From c32b0c2f618898fbc84e89b94b5324e5fff0c462 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:39:55 -0700 Subject: [PATCH 05/11] test: More longer sleep --- src/test/extension.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index c271d0a..32e8551 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -531,7 +531,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(100); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); From 4f6a8fc04cdb466a59ee7f37a76d3a8bb6874dd4 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:43:37 -0700 Subject: [PATCH 06/11] test: Adjust sleeps --- src/test/extension.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 32e8551..199cc5b 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -362,7 +362,7 @@ suite("oil.code", () => { editor.selection = new vscode.Selection(position3, position3); await vscode.commands.executeCommand("oil-code.select"); - await sleep(200); + await sleep(150); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -428,7 +428,7 @@ suite("oil.code", () => { editor.selection = new vscode.Selection(position3, position3); await vscode.commands.executeCommand("oil-code.select"); - await sleep(100); + await sleep(150); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -477,7 +477,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(200); + await sleep(150); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -531,7 +531,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(200); + await sleep(150); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); From 9140da1ceadab1f01ce7a42971fb797c88336087 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:47:20 -0700 Subject: [PATCH 07/11] test: longer sleep --- src/test/extension.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 199cc5b..e4b5d1f 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -362,7 +362,7 @@ suite("oil.code", () => { editor.selection = new vscode.Selection(position3, position3); await vscode.commands.executeCommand("oil-code.select"); - await sleep(150); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -428,7 +428,7 @@ suite("oil.code", () => { editor.selection = new vscode.Selection(position3, position3); await vscode.commands.executeCommand("oil-code.select"); - await sleep(150); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -477,7 +477,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(150); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); @@ -531,7 +531,7 @@ suite("oil.code", () => { new vscode.Position(1, 0) ); await vscode.commands.executeCommand("oil-code.select"); - await sleep(150); + await sleep(200); const editor2 = vscode.window.activeTextEditor; assert.ok(editor2, "No active editor"); From 8e2b1203da32f447fe3692deb7466b46736e6ae9 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 22:58:54 -0700 Subject: [PATCH 08/11] test: longer sleep before save --- src/test/utils/saveFile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/utils/saveFile.ts b/src/test/utils/saveFile.ts index 383bc72..500119b 100644 --- a/src/test/utils/saveFile.ts +++ b/src/test/utils/saveFile.ts @@ -1,7 +1,8 @@ import * as vscode from "vscode"; +import { sleep } from "./sleep"; export async function saveFile() { - await new Promise((resolve) => setTimeout(resolve, 100)); + await sleep(200); await vscode.commands.executeCommand("workbench.action.files.save"); From b4dbd918b01df8852b9fa1cb7ca6666abc11fb70 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 23:05:05 -0700 Subject: [PATCH 09/11] test: update sleeps --- src/test/extension.test.ts | 11 +++++++---- src/test/utils/saveFile.ts | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index e4b5d1f..2104d0b 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -340,6 +340,7 @@ suite("oil.code", () => { const filePosition = new vscode.Position(2, 0); editor.selection = new vscode.Selection(filePosition, filePosition); await vscode.commands.executeCommand("oil-code.select"); + await sleep(200); const mockFileContent = `mock file content`; await vscode.window.activeTextEditor?.edit((editBuilder) => { @@ -352,7 +353,9 @@ suite("oil.code", () => { // Move cursor to the file name const position = new vscode.Position(2, 0); - editor.selection = new vscode.Selection(position, position); + const editor2 = vscode.window.activeTextEditor; + assert.ok(editor2, "No active editor2"); + editor2.selection = new vscode.Selection(position, position); // Cut selection await vscode.commands.executeCommand("editor.action.deleteLines"); @@ -364,9 +367,9 @@ suite("oil.code", () => { await vscode.commands.executeCommand("oil-code.select"); await sleep(200); - const editor2 = vscode.window.activeTextEditor; - assert.ok(editor2, "No active editor"); - editor2.edit((editBuilder) => { + const editor3 = vscode.window.activeTextEditor; + assert.ok(editor3, "No active editor3"); + editor3.edit((editBuilder) => { editBuilder.insert(new vscode.Position(0, 8), newline); editBuilder.insert(new vscode.Position(1, 0), `/002 oil-file.md`); }); diff --git a/src/test/utils/saveFile.ts b/src/test/utils/saveFile.ts index 500119b..9b1a109 100644 --- a/src/test/utils/saveFile.ts +++ b/src/test/utils/saveFile.ts @@ -7,5 +7,5 @@ export async function saveFile() { await vscode.commands.executeCommand("workbench.action.files.save"); // Give the file save operation time to complete - await new Promise((resolve) => setTimeout(resolve, 300)); + await sleep(300); } From 2f21bf6c25f125e26f2015002add0e5c1e0dc734 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 23:10:40 -0700 Subject: [PATCH 10/11] test: more sleep --- src/test/utils/saveFile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/utils/saveFile.ts b/src/test/utils/saveFile.ts index 9b1a109..e8359d0 100644 --- a/src/test/utils/saveFile.ts +++ b/src/test/utils/saveFile.ts @@ -7,5 +7,5 @@ export async function saveFile() { await vscode.commands.executeCommand("workbench.action.files.save"); // Give the file save operation time to complete - await sleep(300); + await sleep(400); } From ebf2371e218b1af33409f35d09102026b357d081 Mon Sep 17 00:00:00 2001 From: Corwin Marsh Date: Sun, 20 Jul 2025 23:20:17 -0700 Subject: [PATCH 11/11] refactor: Refactor common logic --- src/commands/select.ts | 71 ++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/src/commands/select.ts b/src/commands/select.ts index 835617a..e7a3c33 100644 --- a/src/commands/select.ts +++ b/src/commands/select.ts @@ -18,6 +18,30 @@ import { preview } from "./preview"; const cursorInitChar = 5; // 5 characters for "/000 " +function closeOldDocument(oldUri: vscode.Uri) { + // Close the old oil document after opening the new file + setTimeout(async () => { + try { + // Find and close the old document tab + const tabs = vscode.window.tabGroups.all.flatMap((group) => group.tabs); + const oldTab = tabs.find( + (tab) => + tab.input instanceof vscode.TabInputText && + tab.input.uri.toString() === oldUri.toString() + ); + if (oldTab) { + await vscode.window.tabGroups.close(oldTab); + } + } catch (error) { + // Fallback method if tab API fails + await vscode.window.showTextDocument(oldUri); + await vscode.commands.executeCommand( + "workbench.action.revertAndCloseActiveEditor" + ); + } + }, 50); +} + export async function select({ overRideLineText, overRideTargetPath, @@ -110,29 +134,7 @@ export async function select({ }); if (!viewColumn) { // Close the old document after the new one is shown - // Use a small delay to ensure smooth transition - setTimeout(async () => { - try { - // Find and close the old document tab - const tabs = vscode.window.tabGroups.all.flatMap( - (group) => group.tabs - ); - const oldTab = tabs.find( - (tab) => - tab.input instanceof vscode.TabInputText && - tab.input.uri.toString() === oldUri.toString() - ); - if (oldTab) { - await vscode.window.tabGroups.close(oldTab); - } - } catch (error) { - // Fallback method if tab API fails - await vscode.window.showTextDocument(oldUri); - await vscode.commands.executeCommand( - "workbench.action.revertAndCloseActiveEditor" - ); - } - }, 50); + closeOldDocument(oldUri); } // Position cursor appropriately @@ -240,28 +242,7 @@ export async function select({ if (!viewColumn) { // Close the old oil document after opening the new file - setTimeout(async () => { - try { - // Find and close the old document tab - const tabs = vscode.window.tabGroups.all.flatMap( - (group) => group.tabs - ); - const oldTab = tabs.find( - (tab) => - tab.input instanceof vscode.TabInputText && - tab.input.uri.toString() === activeEditor.document.uri.toString() - ); - if (oldTab) { - await vscode.window.tabGroups.close(oldTab); - } - } catch (error) { - // Fallback method if tab API fails - await vscode.window.showTextDocument(activeEditor.document.uri); - await vscode.commands.executeCommand( - "workbench.action.revertAndCloseActiveEditor" - ); - } - }, 50); + closeOldDocument(activeEditor.document.uri); } // For different column, show in new column (old one stays open) await vscode.window.showTextDocument(fileDoc, {