diff --git a/src/folderSuggestModal.ts b/src/folderSuggestModal.ts index 55d0943..e1831d4 100644 --- a/src/folderSuggestModal.ts +++ b/src/folderSuggestModal.ts @@ -2,7 +2,11 @@ import { App, FuzzySuggestModal, TFolder, WorkspaceLeaf, View } from "obsidian"; import type FolderNavigatorPlugin from "./main"; // Helper function for conditional logging based on plugin settings -function log(message: string, plugin: FolderNavigatorPlugin, ...args: any[]): void { +function log( + message: string, + plugin: FolderNavigatorPlugin, + ...args: any[] +): void { if (plugin.settings.debugMode) { console.log(message, ...args); } @@ -15,7 +19,7 @@ function logError(message: string, ...args: any[]): void { interface FileExplorerView extends View { fileItems: Record; - expandFolder?: (folder: TFolder) => void; // Optional: may not exist in all versions + expandFolder?: (folder: TFolder) => void; // Optional: may not exist in all versions } interface FileExplorerInstance { @@ -44,7 +48,7 @@ export class FolderSuggestModal extends FuzzySuggestModal { this.plugin = plugin; this.setPlaceholder("Type folder name..."); this.folders = this.getAllFolders(); - + // Use the max results from settings this.limit = this.plugin.settings.maxResults; } @@ -67,12 +71,12 @@ export class FolderSuggestModal extends FuzzySuggestModal { private getParentFolderChain(folder: TFolder): TFolder[] { const parentChain: TFolder[] = []; let currentFolder: TFolder | null = folder.parent; - + while (currentFolder) { parentChain.unshift(currentFolder); // Add at beginning to get root->leaf order currentFolder = currentFolder.parent; } - + return parentChain; } @@ -82,28 +86,35 @@ export class FolderSuggestModal extends FuzzySuggestModal { private getFileExplorer(): FileExplorerInstance | null { try { const app = this.app as ExtendedApp; - + if (!app.internalPlugins?.plugins["file-explorer"]?.instance) { logError("Could not find file explorer plugin instance"); return null; } - const fileExplorer = app.internalPlugins.plugins["file-explorer"].instance; - + const fileExplorer = + app.internalPlugins.plugins["file-explorer"].instance; + if (typeof fileExplorer.revealInFolder !== "function") { - logError("revealInFolder method not found on file explorer instance"); + logError( + "revealInFolder method not found on file explorer instance", + ); return null; } // Log available methods for debugging if (this.plugin.settings.debugMode) { log("File explorer instance methods:", this.plugin); - const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(fileExplorer)); + const methods = Object.getOwnPropertyNames( + Object.getPrototypeOf(fileExplorer), + ); log(methods.join(", "), this.plugin); - + if (fileExplorer.view) { log("File explorer view methods:", this.plugin); - const viewMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(fileExplorer.view)); + const viewMethods = Object.getOwnPropertyNames( + Object.getPrototypeOf(fileExplorer.view), + ); log(viewMethods.join(", "), this.plugin); } } @@ -119,42 +130,52 @@ export class FolderSuggestModal extends FuzzySuggestModal { * Event handler for when a folder is chosen from the suggestion list */ onChooseItem(folder: TFolder): void { - log(`Folder selected: "${folder.path}" (name: "${folder.name}")`, this.plugin); - + log( + `Folder selected: "${folder.path}" (name: "${folder.name}")`, + this.plugin, + ); + try { // Close the modal first this.close(); - + // Make sure the file explorer is visible - const fileExplorerLeaves = this.app.workspace.getLeavesOfType("file-explorer"); + const fileExplorerLeaves = + this.app.workspace.getLeavesOfType("file-explorer"); if (fileExplorerLeaves.length === 0) { logError("No file explorer leaf found"); return; } - + const fileExplorerLeaf = fileExplorerLeaves[0]; this.app.workspace.revealLeaf(fileExplorerLeaf); log("File explorer leaf revealed", this.plugin); - + // Get the file explorer instance const fileExplorer = this.getFileExplorer(); if (!fileExplorer) { logError("Failed to get file explorer instance"); return; } - + // Step 1: Reveal the folder in the file explorer log(`Revealing folder in explorer: "${folder.path}"`, this.plugin); fileExplorer.revealInFolder(folder); - + // Step 2: Wait a bit for the UI to update, then expand folders using DOM setTimeout(() => { if (this.plugin.settings.expandTargetFolder) { // Get all parent folders in order - log(`Expanding parent folders for: "${folder.path}"`, this.plugin); + log( + `Expanding parent folders for: "${folder.path}"`, + this.plugin, + ); const parentFolders = this.getParentFolderChain(folder); - log(`Parent chain: ${parentFolders.map(f => f.name).join(" -> ")}`, this.plugin); - + log( + `Parent chain: ${parentFolders.map((f) => f.name).join(" -> ")}`, + this.plugin, + ); + // First, expand all parent folders in order from root to leaf parentFolders.forEach((parentFolder, index) => { // Use increasing delays to ensure proper sequence @@ -162,17 +183,23 @@ export class FolderSuggestModal extends FuzzySuggestModal { this.expandFolderByDOMClick(parentFolder.name); }, index * 50); }); - + // Then expand the target folder itself (after parents are expanded) - setTimeout(() => { - log(`Expanding target folder: "${folder.name}"`, this.plugin); - this.expandFolderByDOMClick(folder.name); - - // Highlight the folder after expansion - setTimeout(() => { - this.highlightFolderInDOM(folder.name); - }, 200); - }, parentFolders.length * 50 + 100); + setTimeout( + () => { + log( + `Expanding target folder: "${folder.name}"`, + this.plugin, + ); + this.expandFolderByDOMClick(folder.name); + + // Highlight the folder after expansion + setTimeout(() => { + this.highlightFolderInDOM(folder.name); + }, 200); + }, + parentFolders.length * 50 + 100, + ); } else { // Just highlight the folder if we're not expanding setTimeout(() => { @@ -184,93 +211,128 @@ export class FolderSuggestModal extends FuzzySuggestModal { logError(`Error in folder navigation: ${error}`); } } - + /** * Expand a folder by finding and clicking its title directly in the DOM */ private expandFolderByDOMClick(folderName: string): void { try { log(`Looking for folder to expand: "${folderName}"`, this.plugin); - + // Find all folder title content elements - const allTitleContents = document.querySelectorAll(".nav-folder-title-content"); - + const allTitleContents = document.querySelectorAll( + ".nav-folder-title-content", + ); + for (const titleContent of Array.from(allTitleContents)) { if (titleContent.textContent === folderName) { - log(`Found folder title content: "${folderName}"`, this.plugin); - + log( + `Found folder title content: "${folderName}"`, + this.plugin, + ); + // Get the title element - const titleElement = titleContent.closest(".nav-folder-title"); + const titleElement = + titleContent.closest(".nav-folder-title"); if (!(titleElement instanceof HTMLElement)) { - log(`Could not find title element for: "${folderName}"`, this.plugin); + log( + `Could not find title element for: "${folderName}"`, + this.plugin, + ); continue; } - + // Get the folder element const folderElement = titleContent.closest(".nav-folder"); if (!(folderElement instanceof HTMLElement)) { - log(`Could not find folder element for: "${folderName}"`, this.plugin); + log( + `Could not find folder element for: "${folderName}"`, + this.plugin, + ); continue; } - + // Check if it's collapsed if (folderElement.classList.contains("is-collapsed")) { - log(`Folder is collapsed, clicking title to expand: "${folderName}"`, this.plugin); + log( + `Folder is collapsed, clicking title to expand: "${folderName}"`, + this.plugin, + ); // Click the title element directly - this is more reliable than the collapse indicator titleElement.click(); return; } else { - log(`Folder already expanded: "${folderName}"`, this.plugin); + log( + `Folder already expanded: "${folderName}"`, + this.plugin, + ); return; } } } - - log(`Could not find folder with name: "${folderName}"`, this.plugin); + + log( + `Could not find folder with name: "${folderName}"`, + this.plugin, + ); } catch (error) { logError(`Error expanding folder: ${error}`); } } - + /** * Highlight a folder in the DOM by finding and styling its title */ private highlightFolderInDOM(folderName: string): void { try { - log(`Looking for folder to highlight: "${folderName}"`, this.plugin); - + log( + `Looking for folder to highlight: "${folderName}"`, + this.plugin, + ); + // Find all folder title content elements - const allTitleContents = document.querySelectorAll(".nav-folder-title-content"); - + const allTitleContents = document.querySelectorAll( + ".nav-folder-title-content", + ); + for (const titleContent of Array.from(allTitleContents)) { if (titleContent.textContent === folderName) { - log(`Found folder to highlight: "${folderName}"`, this.plugin); - + log( + `Found folder to highlight: "${folderName}"`, + this.plugin, + ); + // Get the title element - const titleElement = titleContent.closest(".nav-folder-title"); + const titleElement = + titleContent.closest(".nav-folder-title"); if (!(titleElement instanceof HTMLElement)) { continue; } - + // Scroll into view titleElement.scrollIntoView({ behavior: "smooth", block: "center", }); - + // Add highlighting class titleElement.classList.add("nav-folder-title-highlighted"); - + // Remove after delay setTimeout(() => { - titleElement.classList.remove("nav-folder-title-highlighted"); + titleElement.classList.remove( + "nav-folder-title-highlighted", + ); }, 2000); - + return; } } - - log(`Could not find folder to highlight: "${folderName}"`, this.plugin); + + log( + `Could not find folder to highlight: "${folderName}"`, + this.plugin, + ); } catch (error) { logError(`Error highlighting folder: ${error}`); } diff --git a/src/settingsTab.ts b/src/settingsTab.ts index a7c95aa..04a4930 100644 --- a/src/settingsTab.ts +++ b/src/settingsTab.ts @@ -40,10 +40,10 @@ export class SettingsTab extends PluginSettingTab { await this.plugin.saveSettings(); }), ); - + // Add advanced section new Setting(containerEl).setName("Advanced").setHeading(); - + new Setting(containerEl) .setName("Debug mode") .setDesc(