Plugin API: expose live edit functionality for extension

Use case or problem

The live edit view allows you to interact with Markdown syntax in a specific way. When you click into a Markdown formatting element, the raw text is revealed while the formatting is mostly preserved (a kind of semi-source-edit view). When you click out, the syntax characters are hidden, returning the element to a “preview” view.

I want to be able to mimic this behavior with arbitrary syntax rules. My specific use case is to add a formatting rule that grants specific styles to an inline block that is a keyboard shortcut, e.g. ⌘⇧. Doesn’t really matter what the wrapper character is, I was thinking {{}}.

Exposing this functionality could open up plenty more use cases.

Proposed solution

Assuming that there is some set of declarative rules governing the behavior of the live edit view – e.g. something like:

const liveEditRules = {
  inlineCodeBlock: {
    wrappingChar: '`',
    class: 'inline-code',

Then allowing plugins to register and/or edit rules would be the obvious choice. I have to imagine that there’s some kind of unified logic handling the way the live edit format toggling behaves. Whatever that system is, allow us to modify it.

Editor extensions already provide an interface similar to what I describe with “mark” and “replace” decorations. However, because they are CodeMirror level extensions, they are not privy to whatever Obsidian has added on top to implement the live edit view.

Current workaround (optional)

Closest I’ve gotten is using an editor extension to add a “mark” decoration, basically how you would do syntax highlighting. This allows for convenient styling of a span like {{⌘⇧}}, but doesn’t allow for the “hide the syntax” behavior of native Markdown features.

Related feature requests (optional)


I don’t know if this helps (or maybe you already know), but there is an HTML element for your specific case:

Obviously it’s less nice to type, but it’s standard.

1 Like

Good tip! Thank you :slightly_smiling_face:

Maybe I will just write something up to auto-wrap any \w starting with ⌘ in that HTML element ? :thinking:

In this case, you should use replace widgets, not mark widgets.
Obsidian’s live preview decorations are implemented as a state field that provides decorations that display replace widgets when the cursor is not overlapping with the target positions.

Have you read Obsidian’s dev docs and CodeMirror’s system guide, as well as decoration examples? If not, they are where you start off.

Right, I tried a replace widget but couldn’t get it to be editable or properly integrated with the editor. Can you point me to an example of that? Also would love to see documentation on Obsidian using replace widgets for live edit formatting so I can see how they’re doing it…

EDIT: Do you mean they’re using replace widgets like, to hide/show the syntax characters specifically? Like, the styling is a mark, and then the replace widget is toggling the wrapping char like ``` or * or whatever?

This is code from my plugin.

To briefly explain what this code does, Obsidian doesn’t render math expressions ($...$ or $$...$$) inside callouts in live preview, while it does outside callouts.

So this code renders math inside callouts by mimicking how Obsidian’s built-in decorations do that outside callouts.

P.S. you can just ignore the block with the comment // Add blockquote-related decorations to ">"s, mimicing Obsidian's built-in ones.

1 Like

Yes, Obsidian is using replace widgets for hiding the syntax characters (or completely replace the range with some widget, for example in the case of math expressions) when the cursor is not overlapping with the target range.

And when they’re overlapping, we see the syntax highlighting generated by mark decorations.

1 Like

Thank you so much for this explanation/info, this is unbelievably helpful. I do still think it would be really cool for Obsidian to expose their own functionality for this, so we don’t have to reinvent the wheel, but you’ve given me plenty of blueprint to do the reinventing :slight_smile:

I made a plugin for keyboard shortcuts, if anyone comes across this thread and is wishing for the same thing I did: GitHub - andyzito/obsidian-nice-kbds