Neither vault.process nor vault.modify work if there’s a requestSave debounce event running in the background. This means they don’t work if they are being called within 2 seconds of a file being edited.
Steps to reproduce
Minimal plugin example:
export class OnSavePlugin extends Plugin {
async onload() {
const saveCommandDefinition = this.app.commands?.commands?.["editor:save-file"];
saveCommandDefinition.checkCallback = (checking: boolean) => {
if (checking) return this.originalSaveCallback(checking);
const file = this.app.workspace.getActiveFile();
this.app.vault.process(file, (data) => {
return data.replace('Hello', 'World');
});
}
}
}
There are two outcomes:
- Edit the file and immediately press
Ctrl+S. The content doesn’t change, despitevault.processbeing called. - Edit the file and wait for two seconds for the file to automatically save. The content is being changed as expected.
- Edit the file, and press
Ctrl+Stwo times. The content will only change the second time the file is being saved.
Workarounds
- obsidian-plugin-prettier has a workaround for this by using
editor.setValue(formatted)and then manually restoring the scroll and cursor position. But that workaround is very dirty. - I wasn’t able to figure out what exactly Obsidian Linter does, but I think they hook into codemirror directly.
- You can also wait for
markdownView.dirtyto change and then callprocess, but this would add a delay when pressingCtrl+S.
Environment
Obsidian version: v1.10.3
Installer version: v1.9.14
Operating system: Windows 10 Home 10.0.19045