Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Themes
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Advanced Rename and Delete Handler

Michael NaumovMichael Naumov8k downloads

Handles renames and deletes for the whole vault in one place: updates links, moves attachment files and folders, and cleans up what a deletion leaves behind.

Add to Obsidian
Advanced Rename and Delete Handler screenshot
Advanced Rename and Delete Handler screenshot
Advanced Rename and Delete Handler screenshot
Advanced Rename and Delete Handler screenshot
Advanced Rename and Delete Handler screenshot
  • Overview
  • Scorecard
  • Updates5

Obsidian updates the links pointing at a note when you rename it, and stops there. The images you pasted into that note stay behind under the old name. Deleting the note leaves them behind entirely, referenced by nothing, in a folder named after something that no longer exists.

This plugin takes over renaming and deleting for the whole vault: links follow the note, the files it owns travel with it, and what a deletion leaves behind is cleaned up on terms you choose.

It is the single owner of that behavior in a vault. Several plugins used to carry their own copy of this handler, and two handlers acting on one rename corrupt links between them. Rather than compete, this plugin checks on load and refuses to run while a plugin that still owns its own handler is installed, naming the ones to update; once they are, it starts on its own.

Every rename and delete option, in one place

More screenshots
Rename a note and every link to it follows One owner per vault, and it says so rather than fighting Every rename and delete option, in one place Rename a note and every link to it follows

Demo vault

The documentation is a demo vault. Every feature has a note that explains what it does and why you would want it, with buttons that perform the rename or the deletion and then print the vault as a tree, so you see the effect rather than read a description of it.

Start reading here — it is plain markdown, so it works on GitHub with nothing installed.

A copy of the vault ships with every release. You can access it via any of the following:

  1. Running the Advanced Rename and Delete Handler: Open demo vault command.
  2. Downloading advanced-rename-and-delete-handler-demo-vault.zip from the Releases. It unzips into a single advanced-rename-and-delete-handler-demo-vault-<version> folder.
  3. Browsing its source in demo-vault/ in this repository.

What it does

  • Nothing, until you turn it on. A fresh install leaves renames and deletions to Obsidian and says so once, with a button to the settings. Other plugins ask you to install this one, and being asked to install something should never change how your vault behaves. 01 Renaming a note
  • It tells you which plugins need it. Its settings tab lists the enabled plugins that declare this one as a dependency, each with a button to that plugin's own settings — the answer to "why is this in my vault" before you remove it.
  • Links follow a renamed or moved note, including the display text of a link that was showing the old file name — while a link somebody gave their own words to is left alone. 01 Renaming a note
  • Attachments travel with the note that owns them, folder and all, when it is renamed or moved to another folder. 01 Renaming a note
  • Deleting a note can clean up after it — the attachments only that note used, and the folder the deletion leaves empty. Off by default, because each option removes something. A Delete empty folders command sweeps the whole vault for the ones already sitting there, left by deletions made before you turned any of this on. 02 Deleting a note
  • An attachment two notes share is never deleted with one of them, and can be moved to the note that still uses it rather than left in a folder belonging to a note that is gone. When several notes could adopt it and your priority list settles nothing, the plugin names them and asks rather than guessing. An attachment that is really a folder — a _files tree, a drawing's sidecar folder — moves whole, when your attachment-location plugin says so. 03 Shared attachments
  • A drawing stored as .excalidraw.md is treated as an attachment, not a note, along with any other ending you add. 04 What counts as a note
  • The plugin can be confined to part of the vault with include and exclude path lists. 05 Limiting the scope

For plugin developers: handing your settings over

A plugin that used to handle renames and deletions itself, and no longer does, can propose the settings it held so a vault keeps behaving the way it did, and can go on reading those settings back afterwards. This plugin owns those settings, so it owns the dialog too: your proposal is shown next to the current values, and the user approves, edits or declines it row by row. Nothing is written unless they press OK.

The API is published through the obsidian-dev-utils cross-plugin registry, which gives you version negotiation, a handle that is revoked when this plugin unloads, and a wait that ends when this plugin loads — rather than a lookup that returns undefined because it ran first.

import { watchPluginApi } from 'obsidian-dev-utils/obsidian/plugin/plugin-api';

const ref = watchPluginApi<AdvancedRenameAndDeleteHandlerApi>({
  apiVersionRange: '^1',
  app: this.app,
  component: this,
  pluginId: 'advanced-rename-and-delete-handler'
});

const api = await ref.whenAvailable();
const result = await api.migrateSettings({
  proposedSettings: {
    shouldHandleRenames: true,
    treatAsAttachmentExtensions: ['.excalidraw.md']
  },
  sourcePluginId: this.manifest.id
});

if (result.isApplied) {
  // Record your own one-shot flag, so the offer is not repeated.
}
  • proposedSettings names only what you held. Every member is optional, and a proposal that matches what this plugin already holds is dropped rather than shown, so a user is never asked about a row that would change nothing.
  • result.isApplied is false when the user cancelled and nothing was written — do NOT record your migration as done in that case. It is true when they approved, and also when the proposal changed nothing and no dialog was needed.
  • The call resolves only once the dialog is closed, so awaiting it is how you learn the answer. Two plugins proposing at once are queued, never stacked.
  • A value of the wrong type is refused rather than written, so a mistake surfaces as an error instead of a corrupted data.json.
  • The settings you may propose are emptyFolderBehavior, excludePaths, includePaths, notePriorities, shouldDeleteConflictingAttachments, shouldHandleDeletions, shouldHandleRenames, shouldRenameAttachmentFiles, shouldRenameAttachmentFolder, shouldRescueSharedAttachments, shouldUpdateFileNameAliases and treatAsAttachmentExtensions.
  • The contract version is 1.1.0 and moves independently of the plugin's own version. Ask for '^1'.
  • If you cannot depend on a library version that has the registry, the same object is on the plugin instance as app.plugins.plugins['advanced-rename-and-delete-handler']?.api — untyped, and null until this plugin has loaded.

Reading the settings back

Handing the settings over does not end your interest in them: the same values drive features of your own that have nothing to do with a rename or a delete. Rather than keeping a shadow copy, read them from here.

All three members are synchronous, so you can call them from a checkCallback(isChecking), a settings row's disabled / visible predicate, or a loop over vault files — none of which can await. Hold the ref, not the API object, and read ref.value each time: it is null before this plugin loads and after it unloads, and correct again on a re-enable.

const ref = watchPluginApi<AdvancedRenameAndDeleteHandlerApi>({
  apiVersionRange: '^1',
  app: this.app,
  component: this,
  pluginId: 'advanced-rename-and-delete-handler'
});

// Inside a `checkCallback`, a `visible` predicate, or a loop over vault files.
const api = ref.value;
if (api && !api.isPathIgnored(file.path) && !api.isTreatedAsAttachment(file.path)) {
  const { emptyFolderBehavior, notePriorities } = api.getSettings();
  // ...
}
  • getSettings() returns all twelve values above as plain data, read live on every call, so there is nothing to invalidate and nothing to subscribe to. The arrays are copies — writing to one changes nothing here.
  • isPathIgnored(path) answers whether this plugin leaves the path alone, per the include and exclude lists.
  • isTreatedAsAttachment(path) answers whether the path names an attachment despite its extension — .excalidraw.md being the case that motivated the setting.
  • Use the two predicates rather than re-matching the arrays yourself. Every plugin bundles its own copy of obsidian-dev-utils, so running the lists through your copy of the matching code is two copies that can drift apart; asking here keeps the matching in one place.
  • These arrived in contract 1.1.0. That is purely additive, so '^1' still gets you them — but a vault running an older release will hand you an API without them, which is what watchPluginApi's shape check is for.

Declaring this plugin as a dependency

If your plugin cannot work without this one, say so rather than failing quietly once a user removes it. With obsidian-dev-utils' PluginBase, declare it and your onloadImpl does not run until this plugin is installed, enabled and new enough — your plugin explains what is missing and installs it in one click, and finishes loading the moment it arrives:

protected override getPluginDependencies(): PluginDependency[] {
  return [
    {
      apiVersionRange: '^1.1.0',
      pluginId: 'advanced-rename-and-delete-handler',
      pluginName: 'Advanced Rename and Delete Handler',
      reason: 'Moves each note\'s attachment folder with it when the note is renamed.'
    }
  ];
}

Your plugin then appears in this plugin's settings tab under Plugins that depend on this one. Because this plugin does nothing until something is turned on, asking a user to install it is harmless; hand your old values over with migrateSettings (above) for the switches your users relied on.

Installation

The plugin is available in the official Community Plugins repository.

Beta versions

To install the latest beta release of this plugin (regardless if it is available in the official Community Plugins repository or not), follow these steps:

  1. Ensure you have the BRAT plugin installed and enabled.
  2. Click Install via BRAT.
  3. An Obsidian pop-up window should appear. In the window, click the Add plugin button once and wait a few seconds for the plugin to install.

Debugging

By default, debug messages for this plugin are hidden.

To show them, run the following command in the DevTools Console:

window.DEBUG.enable('advanced-rename-and-delete-handler');

For more details, refer to the documentation.

Changelog

All notable changes to this project will be documented in the CHANGELOG.

Contributing

Contributions are welcome — see CONTRIBUTING to get set up.

Support

My other Obsidian resources

See my other Obsidian resources.

License

© Michael Naumov

HealthExcellent
ReviewPassed
Details
Current version
1.3.0
Last updated
2 weeks ago
Created
3 weeks ago
Updates
5 releases
Downloads
8k
Compatible with
Obsidian 1.13.7+
Platforms
Desktop, Mobile
License
MIT
Report bugRequest featureReport plugin
Sponsor
Buy Me a Coffee
Author
Michael NaumovMichael Naumovmnaoumov
mnaoumov.dev
GitHubmnaoumov
Xmnaoumov
  1. Community
  2. Plugins
  3. Advanced Rename and Delete Handler

Related plugins

Notebook Navigator

A better file browser and calendar inspired by Apple Notes, Bear, Evernote and Day One.

Importer

Convert your data to Markdown files you can use in Obsidian. Works with Apple Notes, OneNote, Evernote, Notion, Google Keep, and many other formats.

Advanced Canvas

Supercharge your canvas experience. Create presentations, flowcharts and more.

Minimal Theme Settings

Control the colors and fonts in Minimal Theme.

Homepage

Open a note, base, or workspace on startup, or set it for quick access later.

Linter

Format and style your notes. Linter can be used to format YAML tags, aliases, arrays, and metadata; footnotes; headings; spacing; math blocks; regular Markdown contents like list, italics, and bold styles; and more with the use of custom rule options.

TaskNotes

Note-based task management with calendar, pomodoro and time-tracking integration.

Hider

Hide interface elements such as tooltips, status bar, titlebar, and more.

BRAT

Easily install a beta version of a plugin for testing.

Excalidraw

Visual PKM powerhouse. Create and edit Excalidraw drawings.