Skip to main content
Preslav Rachev

Image Source: Midjourney

If you have ever used Obsidian or any other Markdown editor that switches between Source and Reading, I am sure the following annoyance must be familiar to you. Imagine you’re scrolling through a document and suddenly notice that the layout has shifted or you added some characters by mistake. While you can always undo those changes, they inadvertently change the state of the note, most importantly, when it was last updated. This is particularly annoying when reviewing important documentation or reference materials you’d rather keep pristine.

The simplest solution is to make Reading mode the default for all notes. The problem with that is that once edited, notes won’t go back to Reading unless closed or manually switched back to that mode.

Obsidian can display notes in Reading mode by default.

This led me to put together a small plugin for personal use that I call “Locked Notes.” The concept is straightforward: notes default to preview mode, and you need to explicitly enter edit mode through a double-click. When editing, you can simply press ESC and move back to note Preview. Think of it as a gentler version of Vim’s modal editing – you’re either viewing or editing, with a clear distinction between the two states.

My original motivation was to prevent accidental changes. However, it quickly became a whole new way of distinguishing between when I consume and when I create information. This is supported by the fact that Reading mode beautifully renders notes and leaves away all the cognitive burden of Markdown or some other syntax. While Obsidian’s Vim mode offers similar functionality, it comes with a steeper learning curve and doesn’t quite capture the simple preview/edit toggle I was looking for.

The implementation is relatively straightforward with a bit of TypeScript. The changes fit in a TS file so small that I can share the entire code right away:

export default class LockedNotesPlugin extends Plugin {
    private handleDoubleClick(leaf: WorkspaceLeaf) {
        return () => {
            let viewState = leaf.getViewState();
            viewState.state.mode = "source";
            leaf.setViewState(viewState);
        };
    }

    private handleEscapeKey(leaf: WorkspaceLeaf) {
        return (e: KeyboardEvent) => {
            if (e.keyCode === 27) {
                let viewState = leaf.getViewState();
                viewState.state.mode = "preview";
                leaf.setViewState(viewState);
            }
        };
    }

    private attachEventHandlers(leaf: WorkspaceLeaf) {
        if (this.isActiveNote(leaf)) {
            leaf.view.containerEl.ondblclick = this.handleDoubleClick(leaf);
            leaf.view.containerEl.onkeydown = this.handleEscapeKey(leaf);
            this.lockLeaf(leaf);
        }
    }

    async onload() {
        // Initialize for all open notes
        this.app.workspace.iterateAllLeaves(leaf => {
            this.attachEventHandlers(leaf);
        });

        // Register handler for new notes
        this.registerEvent(
            this.app.workspace.on("active-leaf-change", leaf => {
                this.attachEventHandlers(leaf as WorkspaceLeaf);
            })
        );
    }

    onunload() {
        this.app.workspace.iterateAllLeaves(leaf => {
            if (this.isActiveNote(leaf)) {
                leaf.view.containerEl.ondblclick = null;
                leaf.view.containerEl.onkeydown = null;
            }
        });
    }

    isActiveNote(leaf: WorkspaceLeaf): Boolean {
        let view = leaf.view instanceof MarkdownView ? leaf.view : null;
        return view !== null;
    }

    lockLeaf(leaf: WorkspaceLeaf) {
        let viewState = leaf.getViewState();
        viewState.state.mode = "preview";
        leaf.setViewState(viewState);
    }
}

Still, I’m hesitant to release Locked Notes as a community plugin. This feels like functionality that would be better implemented at the core level, providing a consistent experience for all users. Worse, I have abolutely no idea if this piece of code is safe, or it might (highly likely) collide with some other extensions. Given Obsidian’s thoughtful approach to user experience, I’m curious to see how they might tackle this challenge in the future.

For now, this remains a personal solution to a personal annoyance. Often, the best tools are the ones we craft for ourselves, even if they never see the light of public release. After all, isn’t that what personal knowledge management is all about – creating an environment that works precisely the way we need it to?

What do you think about this approach to note editing? Do you have your own strategies for preventing accidental modifications? Let me know in the comments below.

Until next time! ✌️

Have something to say? Join the discussion below 👇

Want to explore instead? Fly with the time capsule 🛸

You may also find these interesting