From 6743340aba909a761a80ea844ca195fa645492a4 Mon Sep 17 00:00:00 2001 From: jfsicilia Date: Mon, 21 Oct 2024 21:17:32 +0100 Subject: [PATCH 1/3] Added new command to open folder note of current active folder in file explorer. --- src/Commands.ts | 28 +++++++++++++++++++++++++++- src/globals.d.ts | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/Commands.ts b/src/Commands.ts index 71bc48f..e0243fb 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -1,4 +1,4 @@ -import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, Platform, stringifyYaml } from 'obsidian'; +import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, Platform, stringifyYaml, View } from 'obsidian'; import FolderNotesPlugin from './main'; import { getFolderNote, createFolderNote, deleteFolderNote, turnIntoFolderNote, openFolderNote, extractFolderName, detachFolderNote } from './functions/folderNoteFunctions'; import { ExcludedFolder } from './ExcludeFolders/ExcludeFolder'; @@ -9,6 +9,8 @@ import ExcludedFolderSettings from './ExcludeFolders/modals/ExcludeFolderSetting import { ExcludePattern } from './ExcludeFolders/ExcludePattern'; import PatternSettings from './ExcludeFolders/modals/PatternSettings'; import { applyCSSClassesToFolder } from './functions/styleFunctions'; +import { FileExplorerView } from './globals'; + export class Commands { plugin: FolderNotesPlugin; @@ -114,6 +116,30 @@ export class Commands { openFolderNote(this.plugin, folderNote); } }); + this.plugin.addCommand({ + id: 'open-folder-note-for-active-file-explorer-folder', + name: 'Open folder note of current active folder in file explorer', + checkCallback: (checking: boolean) => { + // Check if the active view is a file explorer. + const view = this.app.workspace.getActiveViewOfType(View); + if (view?.getViewType() !== 'file-explorer') return false; + // Check if there is a focused or active item in the file explorer. + const fe = view as FileExplorerView; + const activeFileOrFolder = + fe.tree.focusedItem?.file ?? fe.activeDom?.file; + if (!activeFileOrFolder) return false; + // Only interested in focused or active folder. + if (activeFileOrFolder instanceof TFile) return false; + if (checking) return true; + + // Everything is fine and now not checking, let's do action: + // if folder has a folder note, open it. + const folder = activeFileOrFolder as TFolder; + const folderNote = getFolderNote(this.plugin, folder.path); + if (!(folderNote instanceof TFile)) return; + openFolderNote(this.plugin, folderNote); + }, + }); this.plugin.addCommand({ id: 'insert-folder-overview-fn', name: 'Insert folder overview', diff --git a/src/globals.d.ts b/src/globals.d.ts index 7bc4834..b322eba 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,4 +1,4 @@ -import { Plugin, TAbstractFile, View, WorkspaceLeaf } from 'obsidian'; +import { Plugin, TAbstractFile, TFile, TFolder, View, WorkspaceLeaf } from 'obsidian'; declare module 'obsidian' { interface Setting { @@ -34,8 +34,41 @@ interface FileExplorerViewFileItem extends TAbstractFile { selfEl: HTMLElement } +type FileOrFolderItem = FolderItem | FileItem; + +interface FileItem { + el: HTMLDivElement; + file: TFile; + fileExplorer: FileExplorerView; + info: any; + selfEl: HTMLDivElement; + innerEl: HTMLDivElement; +} + +interface FolderItem { + el: HTMLDivElement; + fileExplorer: FileExplorerView; + info: any; + selfEl: HTMLDivElement; + innerEl: HTMLDivElement; + file: TFolder; + children: FileOrFolderItem[]; + childrenEl: HTMLDivElement; + collapseIndicatorEl: HTMLDivElement; + collapsed: boolean; + setCollapsed: (collapsed: boolean) => void; + pusherEl: HTMLDivElement; +} + +interface TreeItem { + focusedItem: FileOrFolderItem; + setFocusedItem: (item: FileOrFolderItem, moveViewport: boolean) => void; + selectedDoms: Set; +} interface FileExplorerView extends View { fileItems: { [path: string]: FileExplorerViewFileItem }; + activeDom: FileOrFolderItem; + tree: TreeItem; } declare global { From 8627c2db546c9c0a69d3999c8f328b19b28d7c79 Mon Sep 17 00:00:00 2001 From: jfsicilia Date: Tue, 22 Oct 2024 11:34:18 +0100 Subject: [PATCH 2/3] Added commands for folder note creation and deletion in file explorer. Improved code readability. --- src/Commands.ts | 64 +++++++++++++++++++++++++++++------------- src/functions/utils.ts | 25 ++++++++++++++++- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/src/Commands.ts b/src/Commands.ts index e0243fb..1fb3eb0 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -2,7 +2,7 @@ import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, import FolderNotesPlugin from './main'; import { getFolderNote, createFolderNote, deleteFolderNote, turnIntoFolderNote, openFolderNote, extractFolderName, detachFolderNote } from './functions/folderNoteFunctions'; import { ExcludedFolder } from './ExcludeFolders/ExcludeFolder'; -import { getFolderPathFromString } from './functions/utils'; +import { getFolderPathFromString, getFileExplorerActiveFolder } from './functions/utils'; import { getExcludedFolderByPattern } from './ExcludeFolders/functions/patternFunctions'; import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder, getExcludedFoldersByPath, updateExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import ExcludedFolderSettings from './ExcludeFolders/modals/ExcludeFolderSettings' @@ -89,6 +89,26 @@ export class Commands { } }); }); + this.plugin.settings.supportedFileTypes.forEach((fileType) => { + const type = fileType === 'md' ? 'markdown' : fileType; + this.plugin.addCommand({ + id: `create-${type}-folder-note-for-active-file-explorer-folder`, + name: `Create ${type} folder note for current active folder in file explorer`, + checkCallback: (checking: boolean) => { + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there already a folder note for the active folder? + const folderNote = getFolderNote(this.plugin, folder.path); + if (folderNote instanceof TFile) return false; + if (checking) return true; + + // Everything is fine and not checking, let's create the folder note. + const ext = '.' + fileType; + const path = folder.path; + createFolderNote(this.plugin, path, true, ext, false); + } + }); + }); this.plugin.addCommand({ id: 'delete-folder-note-for-current-folder', @@ -103,6 +123,21 @@ export class Commands { deleteFolderNote(this.plugin, folderNote, true); } }); + this.plugin.addCommand({ + id: 'delete-folder-note-of-active-file-explorer-folder', + name: 'Delete folder note of current active folder in file explorer', + checkCallback: (checking: boolean) => { + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there any folder note for the active folder? + const folderNote = getFolderNote(this.plugin, folder.path); + if (!(folderNote instanceof TFile)) return false; + if (checking) return true; + + // Everything is fine and not checking, let's delete the folder note. + deleteFolderNote(this.plugin, folderNote, true); + } + }); this.plugin.addCommand({ id: 'open-folder-note-for-current-folder', name: 'Open folder note of current folder of active note', @@ -117,28 +152,19 @@ export class Commands { } }); this.plugin.addCommand({ - id: 'open-folder-note-for-active-file-explorer-folder', + id: 'open-folder-note-of-active-file-explorer-folder', name: 'Open folder note of current active folder in file explorer', checkCallback: (checking: boolean) => { - // Check if the active view is a file explorer. - const view = this.app.workspace.getActiveViewOfType(View); - if (view?.getViewType() !== 'file-explorer') return false; - // Check if there is a focused or active item in the file explorer. - const fe = view as FileExplorerView; - const activeFileOrFolder = - fe.tree.focusedItem?.file ?? fe.activeDom?.file; - if (!activeFileOrFolder) return false; - // Only interested in focused or active folder. - if (activeFileOrFolder instanceof TFile) return false; - if (checking) return true; - - // Everything is fine and now not checking, let's do action: - // if folder has a folder note, open it. - const folder = activeFileOrFolder as TFolder; + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there any folder note for the active folder? const folderNote = getFolderNote(this.plugin, folder.path); - if (!(folderNote instanceof TFile)) return; + if (!(folderNote instanceof TFile)) return false; + if (checking) return true; + + // Everything is fine and not checking, let's open the folder note. openFolderNote(this.plugin, folderNote); - }, + } }); this.plugin.addCommand({ id: 'insert-folder-overview-fn', diff --git a/src/functions/utils.ts b/src/functions/utils.ts index 2ea5210..33e39d0 100644 --- a/src/functions/utils.ts +++ b/src/functions/utils.ts @@ -1,4 +1,6 @@ -import { FileExplorerWorkspaceLeaf } from "src/globals"; +import { TAbstractFile, TFolder, TFile, View} from "obsidian"; +import { FileExplorerWorkspaceLeaf, FileExplorerView } from "src/globals"; +import { getFolderNote } from "./folderNoteFunctions"; export function getFileNameFromPathString(path: string): string { return path.substring(path.lastIndexOf('/' || '\\') >= 0 ? path.lastIndexOf('/' || '\\') + 1 : 0); @@ -41,3 +43,24 @@ export function getFileExplorer() { export function getFileExplorerView() { return this.getFileExplorer().view; } + +export function getFileExplorerActiveFolder() : TFolder | null { + // Check if the active view is a file explorer. + const view = this.app.workspace.getActiveViewOfType(View); + if (view?.getViewType() !== 'file-explorer') return null; + // Check if there is a focused or active item in the file explorer. + const fe = view as FileExplorerView; + const activeFileOrFolder = + fe.tree.focusedItem?.file ?? fe.activeDom?.file; + if (!(activeFileOrFolder instanceof TFolder)) return null; + return activeFileOrFolder as TFolder; +} + +export function getFileExplorerActiveFolderNote(): TFile | null { + const folder = getFileExplorerActiveFolder(); + if (!folder) return null; + // Is there any folder note for the active folder? + const folderNote = getFolderNote(this.plugin, folder.path); + if (!(folderNote instanceof TFile)) return null; + return folderNote; +} \ No newline at end of file From d0aea34ea9768648c76e1b67be96dcdce855c363 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Mon, 5 May 2025 11:57:53 +0200 Subject: [PATCH 3/3] Fix eslint issues --- src/Commands.ts | 63 +++++++++++++++++++----------------------- src/functions/utils.ts | 41 ++++++++++++++------------- src/globals.d.ts | 4 +-- 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/src/Commands.ts b/src/Commands.ts index 08d981f..f0654a1 100644 --- a/src/Commands.ts +++ b/src/Commands.ts @@ -1,15 +1,10 @@ -import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, Platform, stringifyYaml, View } from 'obsidian'; +import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, Platform, stringifyYaml } from 'obsidian'; import FolderNotesPlugin from './main'; import { getFolderNote, createFolderNote, deleteFolderNote, turnIntoFolderNote, openFolderNote, extractFolderName, detachFolderNote } from './functions/folderNoteFunctions'; import { ExcludedFolder } from './ExcludeFolders/ExcludeFolder'; import { getFolderPathFromString, getFileExplorerActiveFolder } from './functions/utils'; -import { getExcludedFolderByPattern } from './ExcludeFolders/functions/patternFunctions'; -import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder, getExcludedFoldersByPath, updateExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; -import ExcludedFolderSettings from './ExcludeFolders/modals/ExcludeFolderSettings'; -import { ExcludePattern } from './ExcludeFolders/ExcludePattern'; -import PatternSettings from './ExcludeFolders/modals/PatternSettings'; +import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { applyCSSClassesToFolder } from './functions/styleFunctions'; -import { FileExplorerView } from './globals'; @@ -91,23 +86,23 @@ export class Commands { }); }); this.plugin.settings.supportedFileTypes.forEach((fileType) => { - const type = fileType === 'md' ? 'markdown' : fileType; + const type = fileType === 'md' ? 'markdown' : fileType; this.plugin.addCommand({ id: `create-${type}-folder-note-for-active-file-explorer-folder`, name: `Create ${type} folder note for current active folder in file explorer`, checkCallback: (checking: boolean) => { - const folder = getFileExplorerActiveFolder(); - if (!folder) return false; - // Is there already a folder note for the active folder? - const folderNote = getFolderNote(this.plugin, folder.path); - if (folderNote instanceof TFile) return false; - if (checking) return true; + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there already a folder note for the active folder? + const folderNote = getFolderNote(this.plugin, folder.path); + if (folderNote instanceof TFile) return false; + if (checking) return true; - // Everything is fine and not checking, let's create the folder note. - const ext = '.' + fileType; - const path = folder.path; - createFolderNote(this.plugin, path, true, ext, false); - } + // Everything is fine and not checking, let's create the folder note. + const ext = '.' + fileType; + const path = folder.path; + createFolderNote(this.plugin, path, true, ext, false); + }, }); }); @@ -129,16 +124,16 @@ export class Commands { id: 'delete-folder-note-of-active-file-explorer-folder', name: 'Delete folder note of current active folder in file explorer', checkCallback: (checking: boolean) => { - const folder = getFileExplorerActiveFolder(); - if (!folder) return false; - // Is there any folder note for the active folder? + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there any folder note for the active folder? const folderNote = getFolderNote(this.plugin, folder.path); if (!(folderNote instanceof TFile)) return false; - if (checking) return true; + if (checking) return true; - // Everything is fine and not checking, let's delete the folder note. + // Everything is fine and not checking, let's delete the folder note. deleteFolderNote(this.plugin, folderNote, true); - } + }, }); this.plugin.addCommand({ id: 'open-folder-note-for-current-folder', @@ -151,22 +146,22 @@ export class Commands { const folderNote = getFolderNote(this.plugin, folder.path); if (!(folderNote instanceof TFile)) return; openFolderNote(this.plugin, folderNote); - } + }, }); this.plugin.addCommand({ id: 'open-folder-note-of-active-file-explorer-folder', name: 'Open folder note of current active folder in file explorer', checkCallback: (checking: boolean) => { - const folder = getFileExplorerActiveFolder(); - if (!folder) return false; - // Is there any folder note for the active folder? + const folder = getFileExplorerActiveFolder(); + if (!folder) return false; + // Is there any folder note for the active folder? const folderNote = getFolderNote(this.plugin, folder.path); if (!(folderNote instanceof TFile)) return false; - if (checking) return true; + if (checking) return true; - // Everything is fine and not checking, let's open the folder note. + // Everything is fine and not checking, let's open the folder note. openFolderNote(this.plugin, folderNote); - } + }, }); this.plugin.addCommand({ id: 'insert-folder-overview-fn', @@ -176,9 +171,9 @@ export class Commands { const lineText = editor.getLine(line); if (lineText.trim() === '' || lineText.trim() === '>') { if (!checking) { - let json = Object.assign({}, this.plugin.settings.defaultOverview); + const json = Object.assign({}, this.plugin.settings.defaultOverview); json.id = crypto.randomUUID(); - const yaml = stringifyYaml(json) + const yaml = stringifyYaml(json); if (lineText.trim() === '') { editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`); } else if (lineText.trim() === '>') { diff --git a/src/functions/utils.ts b/src/functions/utils.ts index 7df32f9..c50a5e7 100644 --- a/src/functions/utils.ts +++ b/src/functions/utils.ts @@ -1,7 +1,6 @@ -import { TAbstractFile, TFolder, TFile, View} from "obsidian"; -import { FileExplorerWorkspaceLeaf, FileExplorerView } from "src/globals"; -import { getFolderNote } from "./folderNoteFunctions"; -import { FileExplorerWorkspaceLeaf } from 'src/globals'; +import { TFolder, TFile, View } from 'obsidian'; +import { FileExplorerWorkspaceLeaf, FileExplorerView } from 'src/globals'; +import { getFolderNote } from './folderNoteFunctions'; import FolderNotesPlugin from 'src/main'; import { FileExplorerLeaf } from 'obsidian-typings'; import FolderOverviewPlugin from 'src/obsidian-folder-overview/src/main'; @@ -54,23 +53,23 @@ export function getFocusedItem(plugin: FolderNotesPlugin) { return focusedItem; } -export function getFileExplorerActiveFolder() : TFolder | null { - // Check if the active view is a file explorer. - const view = this.app.workspace.getActiveViewOfType(View); - if (view?.getViewType() !== 'file-explorer') return null; - // Check if there is a focused or active item in the file explorer. - const fe = view as FileExplorerView; - const activeFileOrFolder = - fe.tree.focusedItem?.file ?? fe.activeDom?.file; - if (!(activeFileOrFolder instanceof TFolder)) return null; - return activeFileOrFolder as TFolder; +export function getFileExplorerActiveFolder(): TFolder | null { + // Check if the active view is a file explorer. + const view = this.app.workspace.getActiveViewOfType(View); + if (view?.getViewType() !== 'file-explorer') return null; + // Check if there is a focused or active item in the file explorer. + const fe = view as FileExplorerView; + const activeFileOrFolder = + fe.tree.focusedItem?.file ?? fe.activeDom?.file; + if (!(activeFileOrFolder instanceof TFolder)) return null; + return activeFileOrFolder as TFolder; } export function getFileExplorerActiveFolderNote(): TFile | null { - const folder = getFileExplorerActiveFolder(); - if (!folder) return null; - // Is there any folder note for the active folder? - const folderNote = getFolderNote(this.plugin, folder.path); - if (!(folderNote instanceof TFile)) return null; - return folderNote; -} \ No newline at end of file + const folder = getFileExplorerActiveFolder(); + if (!folder) return null; + // Is there any folder note for the active folder? + const folderNote = getFolderNote(this.plugin, folder.path); + if (!(folderNote instanceof TFile)) return null; + return folderNote; +} diff --git a/src/globals.d.ts b/src/globals.d.ts index 261cc0f..ffe085a 100644 --- a/src/globals.d.ts +++ b/src/globals.d.ts @@ -1,4 +1,4 @@ -import { Plugin, TAbstractFile, TFile, TFolder, View, WorkspaceLeaf } from 'obsidian'; +import { TAbstractFile, TFile, TFolder, View, WorkspaceLeaf } from 'obsidian'; declare module 'obsidian' { interface Setting { @@ -59,7 +59,7 @@ interface FolderItem { setCollapsed: (collapsed: boolean) => void; pusherEl: HTMLDivElement; } - + interface TreeItem { focusedItem: FileOrFolderItem; setFocusedItem: (item: FileOrFolderItem, moveViewport: boolean) => void;