obsidianmd / obsidian-api

Type definitions for the latest Obsidian API.
https://docs.obsidian.md
MIT License
1.65k stars 192 forks source link

Feat: "mode-change" workspace event #135

Open decaf-dev opened 9 months ago

decaf-dev commented 9 months ago

I am developing a plugin that needs to know when a leaf changes from source mode to preview mode.

registerMarkdownPostProcessor is not suitable for me as it is being called dozens of times. I think this happens because I am replacing the placeholder content (the grey rectangle) of an embedded link with a React 18 app. Whenever the React application updates, the markdown post processor will return the element has been changed.

Proposed solution

Make an event callback in the workspace that returns the markdown leaf that has had its mode changed.

this.registerEvent(
   this.app.workspace.on("mode-change", (leaf: WorkspaceLeaf, mode: "source" | "preview") => {
   });
);
pjeby commented 8 months ago

You want:

app.workspace.on("layout-change", () => { /* check for a change of mode in the target view */ })

The layout change event is fired after every significant state change in the workspace layout, not just of which tabs are active or present or what files are open, but also mode changes in the case of markdown files. So you will get a lot of events where nothing has changed that you care about, but you will also get called when things have changed.

Note that there is a slight delay between the change and the event, and in principle somebody could change modes twice really fast and it would look like the mode never changed at all.