Merge pull request #163 from jfsicilia/open_from_file_explorer

Added new command to open folder note of current active folder in file explorer.
This commit is contained in:
Lost Paul 2025-05-05 12:15:21 +02:00 committed by GitHub
commit 78a28b09b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 139 additions and 4 deletions

View file

@ -1,11 +1,13 @@
import { App, TFolder, Menu, TAbstractFile, Notice, TFile, Editor, MarkdownView, Platform } 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 } from './functions/utils';
import { getFolderPathFromString, getFileExplorerActiveFolder } from './functions/utils';
import { addExcludedFolder, deleteExcludedFolder, getDetachedFolder, getExcludedFolder } from './ExcludeFolders/functions/folderFunctions';
import { applyCSSClassesToFolder } from './functions/styleFunctions';
export class Commands {
plugin: FolderNotesPlugin;
app: App;
@ -83,6 +85,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',
@ -98,6 +120,21 @@ export class Commands {
},
});
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',
@ -111,6 +148,48 @@ export class Commands {
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 folderNote = getFolderNote(this.plugin, folder.path);
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',
name: 'Insert folder overview',
editorCheckCallback: (checking: boolean, editor: Editor) => {
const line = editor.getCursor().line;
const lineText = editor.getLine(line);
if (lineText.trim() === '' || lineText.trim() === '>') {
if (!checking) {
const json = Object.assign({}, this.plugin.settings.defaultOverview);
json.id = crypto.randomUUID();
const yaml = stringifyYaml(json);
if (lineText.trim() === '') {
editor.replaceSelection(`\`\`\`folder-overview\n${yaml}\`\`\`\n`);
} else if (lineText.trim() === '>') {
// add > to the beginning of each line
const lines = yaml.split('\n');
const newLines = lines.map((line) => {
return `> ${line}`;
});
editor.replaceSelection(`\`\`\`folder-overview\n${newLines.join('\n')}\`\`\`\n`);
}
}
return true;
}
return false;
},
});
this.plugin.addCommand({
id: 'create-folder-note-from-selected-text',

View file

@ -1,4 +1,6 @@
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';
@ -50,3 +52,24 @@ export function getFocusedItem(plugin: FolderNotesPlugin) {
const focusedItem = fileExplorer.view.tree.focusedItem;
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 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;
}

35
src/globals.d.ts vendored
View file

@ -1,4 +1,4 @@
import { TAbstractFile, View, WorkspaceLeaf } from 'obsidian';
import { 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<FileOrFolderItem>;
}
interface FileExplorerView extends View {
fileItems: { [path: string]: FileExplorerViewFileItem };
activeDom: FileOrFolderItem;
tree: TreeItem;
}
declare global {