lruijsink2 downloadsMake Live Preview render Markdown the way CommonMark does: soft line breaks as spaces and nested lists with any valid indent, without touching your files.
Make Obsidian's Live Preview editor render Markdown the way CommonMark says it should, without touching your files. It only changes what the editor shows, so it works with whatever formatter or linter you use.
- , 3 under 1. . Live Preview only draws
nested lists correctly with 4 spaces per level, and its Tab key always inserts 4.
Here, the editor shows 4 spaces per level instead.Only whitespace is changed, never the text. Reading view isn't affected.
The plugin remembers how each file looked on disk next to what the editor shows for it. On save:
The plugin never wraps or reindents anything itself. Wrapping and indentation on disk are up to whatever formatter or linter you run. Until it runs, lines you edited stay as the editor has them.
Plugins that format the note on save usually replace the whole document, which would bring the soft wraps and 2-space lists back into the editor. This plugin rewrites such a replacement before it is applied:
In Settings > CommonMark Live Preview:
| Setting | Default | Description |
|---|---|---|
| Render soft line breaks as spaces | on | Master toggle |
| Render nested lists with 4-space indents | on | See what it fixes |
Per-file opt-out: add commonmark-live-preview: false to the file's frontmatter.
The plugin monkey-patches MarkdownView.prototype using
monkey-around:
setViewData): the text goes through unwrap and the list indent
expansion before reaching the editor. The original text and the converted text
are stored as the file's baseline, with a mapping from each editor line to the
disk lines it came from.getViewData): the editor's text is compared with the baseline
line by line. Unchanged lines map back to their original disk lines, changed
lines are written as they are. Obsidian also calls getViewData for change
detection and for merging external changes, which needs a stable answer, so
an unedited editor returns the disk text unchanged.setMode): when switching back to source mode, this.data
is converted back to the editor form. Obsidian's setMode bypasses
setViewData and feeds this.data directly to the editor.A CodeMirror transaction filter handles whole-document replacements that didn't come from the user, as described above.
Anything a CommonMark renderer would join into a single paragraph is joined:
Everything else passes through verbatim: frontmatter, fenced and indented code
blocks, headings, tables, thematic breaks, HTML blocks and callout headers.
Hard line breaks (trailing \ or two trailing spaces) are preserved.
List indentation is only changed for lists outside blockquotes and callouts, and not at all in documents indented with tabs.
Requires Node.js >= 18.
npm install
npm run build # production build → main.js
npm run dev # watch mode (rebuilds on change)
npm test # run unit tests
The build uses esbuild. Output is a single main.js (CommonJS). The
obsidian package and @codemirror/* are externals (provided by
Obsidian at runtime). monkey-around is bundled.
Forked from obsidian-hard-wrap
by alethiophile, MIT licensed. The idea of
showing a different text in the editor than is on disk, and the unwrap logic,
come from that plugin. This version stopped wrapping files itself and instead
keeps their on-disk text, and adds the list indentation rendering and the
formatter handling.
This plugin and its documentation were substantially created using AI. They have been tested and reviewed by the human author.