The FileManager class provides higher-level file and folder operations that respect user preferences and automatically update links when files are moved or renamed.
Methods
getNewFileParent
getNewFileParent(sourcePath: string, newFilePath?: string): TFolder
Gets the folder that new files should be saved to, given the user’s preferences.
The path to the current open/focused file, used when the user wants new files to be created ‘in the same folder’. Use an empty string if there is no active file.
The path to the file that will be newly created, used to infer what settings to use based on the path’s extension.
Returns: The folder where the new file should be created.
Since: 1.1.13
renameFile
renameFile(file: TAbstractFile, newPath: string): Promise<void>
Rename or move a file safely, and update all links to it depending on the user’s preferences.
The file to rename or move.
The new path for the file.
Returns: Promise that resolves when the operation is complete.
Since: 0.11.0
Note: This method is preferred over Vault.rename() because it automatically updates all links to the renamed file.
promptForDeletion
promptForDeletion(file: TAbstractFile): Promise<boolean>
Prompt the user to confirm they want to delete the specified file or folder.
The file or folder to delete.
Returns: Promise that resolves to true if the prompt was confirmed or false if it was canceled.
Since: 0.15.0
trashFile
trashFile(file: TAbstractFile): Promise<void>
Remove a file or a folder from the vault according to the user’s preferred ‘trash’ options (either moving the file to .trash/ or the OS trash bin).
The file or folder to trash.
Returns: Promise that resolves when the operation is complete.
Since: 1.6.6
generateMarkdownLink
generateMarkdownLink(file: TFile, sourcePath: string, subpath?: string, alias?: string): string
Generate a Markdown link based on the user’s preferences.
Where the link is stored in, used to compute relative links.
A subpath, starting with #, used for linking to headings or blocks.
The display text if it’s to be different than the file name. Pass empty string to use file name.
Returns: The generated Markdown link.
Since: 0.12.0
processFrontMatter
processFrontMatter(file: TFile, fn: (frontmatter: any) => void, options?: DataWriteOptions): Promise<void>
Atomically read, modify, and save the frontmatter of a note. The frontmatter is passed in as a JS object, and should be mutated directly to achieve the desired result.
The file to be modified. Must be a Markdown file.
fn
(frontmatter: any) => void
required
A callback function which mutates the frontmatter object synchronously.
Returns: Promise that resolves when the operation is complete.
Throws:
YAMLParseError if the YAML parsing fails
- Any errors that your callback function throws
Since: 1.4.4
Example:
await app.fileManager.processFrontMatter(file, (frontmatter) => {
frontmatter['key1'] = value;
delete frontmatter['key2'];
});
getAvailablePathForAttachment
getAvailablePathForAttachment(filename: string, sourcePath?: string): Promise<string>
Resolves a unique path for the attachment file being saved. Ensures that the parent directory exists and dedupes the filename if the destination filename already exists.
Name of the attachment being saved.
The path to the note associated with this attachment, defaults to the workspace’s active file.
Returns: Full path for where the attachment should be saved, according to the user’s settings.
Since: 1.5.7
Examples
Renaming a file with automatic link updates
const file = this.app.vault.getFileByPath('OldName.md');
if (file) {
// This will automatically update all links to this file
await this.app.fileManager.renameFile(file, 'NewName.md');
console.log('File renamed and all links updated');
}
Moving a file to a different folder
const file = this.app.vault.getFileByPath('MyNote.md');
if (file) {
// Move the file and update all links
await this.app.fileManager.renameFile(file, 'Archive/MyNote.md');
}
Safely deleting a file with user confirmation
const file = this.app.vault.getFileByPath('MyNote.md');
if (file) {
const confirmed = await this.app.fileManager.promptForDeletion(file);
if (confirmed) {
await this.app.fileManager.trashFile(file);
console.log('File deleted');
} else {
console.log('Deletion cancelled');
}
}
Generating markdown links
const targetFile = this.app.vault.getFileByPath('Notes/Target.md');
const sourceFile = this.app.vault.getFileByPath('Journal/2024-01.md');
if (targetFile && sourceFile) {
// Generate a link to the file
const link1 = this.app.fileManager.generateMarkdownLink(
targetFile,
sourceFile.path
);
console.log(link1); // [[Target]]
// Generate a link to a heading
const link2 = this.app.fileManager.generateMarkdownLink(
targetFile,
sourceFile.path,
'#Section 1'
);
console.log(link2); // [[Target#Section 1]]
// Generate a link with custom alias
const link3 = this.app.fileManager.generateMarkdownLink(
targetFile,
sourceFile.path,
'',
'My Custom Link Text'
);
console.log(link3); // [[Target|My Custom Link Text]]
}
Modifying frontmatter
const file = this.app.vault.getFileByPath('MyNote.md');
if (file) {
try {
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
// Add or update properties
frontmatter.tags = ['important', 'work'];
frontmatter.lastModified = new Date().toISOString();
// Remove a property
delete frontmatter.obsoleteKey;
// Increment a counter
frontmatter.viewCount = (frontmatter.viewCount || 0) + 1;
});
console.log('Frontmatter updated');
} catch (error) {
console.error('Failed to update frontmatter:', error);
}
}
Creating a new file in the correct location
const activeFile = this.app.workspace.getActiveFile();
const sourcePath = activeFile?.path || '';
// Get the folder where new files should be created
const folder = this.app.fileManager.getNewFileParent(
sourcePath,
'NewNote.md'
);
// Create the file in the correct location
const newFilePath = `${folder.path}/NewNote.md`;
const file = await this.app.vault.create(newFilePath, '# New Note');
console.log('Created file at:', file.path);
Saving an attachment
const activeFile = this.app.workspace.getActiveFile();
const imageData = await fetch('https://example.com/image.png')
.then(res => res.arrayBuffer());
// Get the appropriate path for the attachment
const attachmentPath = await this.app.fileManager.getAvailablePathForAttachment(
'image.png',
activeFile?.path
);
// Save the attachment
const file = await this.app.vault.createBinary(attachmentPath, imageData);
// Generate a link to the attachment
if (activeFile) {
const link = this.app.fileManager.generateMarkdownLink(
file,
activeFile.path
);
console.log('Attachment link:', link);
}
Batch renaming files
const files = this.app.vault.getMarkdownFiles();
for (const file of files) {
if (file.basename.startsWith('draft-')) {
const newName = file.basename.replace('draft-', 'published-');
const newPath = `${file.parent?.path}/${newName}.${file.extension}`;
await this.app.fileManager.renameFile(file, newPath);
console.log(`Renamed: ${file.path} -> ${newPath}`);
}
}
- Vault - Lower-level file operations
- TFile - File representation
- TFolder - Folder representation