Notes Editor
A CodeMirror-based markdown editor with a formatting toolbar, live inline preview, and a full read mode renderer. Every note is saved as a plain .md file — readable outside Cairn forever.
Edit and Read modes
The editor has two modes, toggled from the header bar:
- Edit — CodeMirror editor with syntax highlighting and the formatting toolbar. A Live Preview toggle in the header turns inline rendering on or off: on (the default) shows callouts, code blocks, tables, math, and Mermaid diagrams rendered live in the editor; off shows the plain Markdown source, handy when the inline preview is in the way of editing the underlying syntax. Your choice is remembered.
- Read — full rendered view with a floating table of contents, clickable heading anchors, and all markdown extensions active
The editor state is preserved when switching modes — your cursor position, undo history, and unsaved content are kept in memory throughout. The editor also remembers whether you last used Edit or Read and opens notes that way.
Live Preview
While editing, rich blocks render inline exactly as they'll look in reading mode:
- Callouts —
> [!note]-style callouts show as styled callouts and click into raw Markdown to edit - Code blocks — fenced code renders with syntax highlighting and a copy button, and clicks into its source
- Tables, math, and Mermaid — GFM tables,
$$…$$display math, and```mermaiddiagrams render live, each clicking into its raw source to edit - Task lists —
- [ ]/- [x]items render as real checkboxes; click to toggle, which writes[ ]↔[x]back to the note's source (ordered lists work too)
Syntax markers (**, #, backticks, -, and link URLs) hide on every line except the one your cursor is on, so a note looks rendered while you type — bullets render as •, links show just their display text, headings render at their true size, and ==highlights==, [[wikilinks]] (as accent chips), and > blockquotes are styled inline too. The raw markdown is still exactly what's saved to disk.
Below the editor, a follow-the-cursor preview panel renders the block you're editing live as you type. When your cursor is inside a table, callout, code block, or math block, the panel shows it taking shape — a misaligned table row or an unclosed fence is instantly visible. Selecting text still previews the selection; plain paragraphs don't trigger it. The panel has an S / M / L toggle to shrink or grow it.
Distraction-free mode
A fullscreen toggle in the toolbar (⌘. / Ctrl+.) hides the notes list so the editor fills the window, in both Edit and Read modes. The list slides back the moment you close the note.
⌘B or click to toggle.
Formatting toolbar
The toolbar is always visible in Edit mode, docked between the title and the editor. It is hidden in Read mode. All actions support toggling — pressing a button a second time removes the formatting.
Inline formatting
These actions wrap the current selection. If nothing is selected, a placeholder is inserted and selected so you can type immediately.
| Button | Markdown | Result |
|---|---|---|
| Bold | **text** | Bold text |
| Italic | _text_ | Italic text |
| Strikethrough | ~~text~~ | ~~crossed out~~ |
| Highlight | ==text== | Yellow highlight in read mode |
| Inline code | `text` | Monospace code span |
| Link | [text](url) | Clickable link |
Headings
Heading buttons toggle the prefix on the current line (or all selected lines). Switching from H2 to H1 replaces the prefix — it does not accumulate ## marks.
| Button | Markdown | Notes |
|---|---|---|
| H1 | # Heading | Also generated in the table of contents |
| H2 | ## Heading | Appears in the table of contents |
| H3 | ### Heading | Appears in the table of contents |
Lists and blocks
These actions operate on the cursor line or every line in the selection. They toggle — pressing again removes the prefix. Numbered list items re-number automatically when toggled on.
| Button | Markdown | Notes |
|---|---|---|
| Blockquote | > text | Renders as an indented callout |
| Bullet list | - item | Toggle strips conflicting list prefixes |
| Numbered list | 1. item | Toggle detected on any number, not just 1. |
| Task list | - [ ] item | Renders as an interactive checkbox in read mode |
Block inserts
| Button | Behaviour |
|---|---|
| Code block | Wraps the selection (or inserts a placeholder) in a fenced ``` block. Pressing again when the cursor is inside a fence removes the fence and restores the inner content. |
| Divider | Inserts a --- horizontal rule after the current line. |
Inline selection preview
When you select text in the editor, a preview panel appears at the bottom of the editor pane. It renders the selection through the full markdown pipeline — including math, callouts, and code highlighting — so you can see exactly what will appear in read mode before you switch.
- Dismiss by pressing Esc, clicking ✕, or clicking outside the editor
- The preview updates as you format the selection
- Format actions applied while a selection is active show the result immediately
Keyboard shortcuts
- ⌘F / Ctrl+F — when the editor is focused: opens the find/replace panel inside the editor; when the editor is not focused: focuses the note list filter input
- ⌘R / Ctrl+R — toggle Read mode
- ⌘N / Ctrl+N — create a new note in the current project
Read mode
Switch to Read mode using the toggle in the header bar or pressing ⌘R. The full renderer activates with all extensions enabled.
The formatting toolbar ships with twelve actions across four groups.
Colour swatches render inline for hex and RGB values: #8faf6f and rgb(62,207,142).
Highlighted text renders with a yellow background: important callout.
npx tsc --noEmit
Colour swatches
In read mode, inline code spans that contain a recognised colour value automatically render a small filled circle next to the value. Supported formats:
#rgband#rrggbb— 3- and 6-digit hex#rrggbbaa— 8-digit hex with alphargb(r, g, b)andrgba(r, g, b, a)hsl(h, s%, l%)andhsla(h, s%, l%, a)
Swatches appear in both the inline selection preview and the full read-mode renderer.
Table of contents
Read mode generates a floating table of contents from all H1, H2, and H3 headings in the document. It appears to the right of the content column on wide viewports, and hides automatically when the viewport is too narrow to fit it without overlapping the text.
- Click any entry to scroll smoothly to that heading
- Requires at least 2 headings to appear
- Hidden automatically when the note pane is narrow
Full markdown syntax reference
Cairn supports standard GitHub-flavored Markdown plus several extensions.
Text formatting
| Syntax | Result |
|---|---|
**bold** | Bold |
_italic_ or *italic* | Italic |
~~strikethrough~~ | Strikethrough |
==highlight== | Yellow highlight |
`inline code` | Monospace code span (colour swatches for hex/rgb values) |
[text](url) | Hyperlink — external links open in system browser |
Headings
| Syntax | Notes |
|---|---|
# H1 | Appears in table of contents |
## H2 | Appears in table of contents |
### H3 | Appears in table of contents |
#### H4 – ###### H6 | Rendered but not in TOC |
Lists
| Syntax | Result |
|---|---|
- item or * item | Bullet list |
1. item | Numbered list |
- [ ] item | Unchecked task checkbox |
- [x] item | Checked task checkbox |
Blocks
| Syntax | Result |
|---|---|
> text | Blockquote |
```language … ``` | Fenced code block with syntax highlighting for 100+ languages |
--- | Horizontal rule |
| Column 1 | Column 2 (GFM) | Table |
Math (KaTeX)
| Syntax | Result |
|---|---|
$E = mc^2$ | Inline math |
$$…$$ or display block | Block-level math, centred |
Callouts
Cairn supports Obsidian-style callout blocks using a blockquote with a type tag on the first line:
> [!NOTE] > This is a note callout. > [!WARNING] > This is a warning. > [!TIP] > Supported types: NOTE, TIP, INFO, WARNING, DANGER, SUCCESS, QUESTION, QUOTE
Footnotes
| Syntax | Result |
|---|---|
text[^1] + [^1]: definition | Superscript reference with footnote list at bottom of page |
AI text actions
The AI row in the toolbar applies to the current selection. All actions require text to be selected except Custom when the cursor is in a line.
| Action | What it does |
|---|---|
| Rephrase | Rewrites the selection with the same meaning but different wording |
| Summarize | Condenses the selection to its key points |
| Expand | Elaborates on the selection with additional detail |
| Fix Grammar | Corrects grammar and spelling without changing meaning |
| Change Tone | Opens a tone picker: Professional, Casual, Concise, Enthusiastic |
| Custom… | Type your own instruction — the AI applies it to the selection |
AI text actions require an AI endpoint to be configured in Settings → AI & Chat. See AI Chat for setup instructions.
Reusable templates
Save any note as a template and re-use it to spin up a fresh note with the same layout. The notes sidebar has a New from template menu — with a one-click Add starter templates for Meeting Notes, Weekly Review, and Daily Standup — plus Save current note as template.
Templates support placeholders filled in when you create a note: {{date}}, {{time}}, {{weekOf}}, {{month}}, {{year}}, and {{title}}. Templates are scoped per-project and kept out of the normal notes list. The assistant can start a note from a template too — just ask ("start my weekly review").
Export to Markdown & PDF
A note's export menu offers Markdown and PDF. PDF exports carry a small running footer with the note title and page number. You can also export a whole project from the sidebar as a single Markdown document — its metadata, the board grouped by column, and every note, folder-sorted.
Organising notes & folders
- Drag a folder onto another folder (or the pinned "Move to root" zone) to reparent the whole subtree — every note keeps its relative structure.
- Drag a folder — or a single note — onto a project row in the leftmost sidebar to move it to that project.
- The folder tree remembers which folders are expanded, per project, across view and project switches.
File storage
Each note is saved as a plain .md file at:
workspace/notes/<Project Name>/<Note Title>.md
Notes are written with YAML frontmatter containing the note ID, creation date, and tags:
--- id: note_abc123 title: v0.9.1 Release Notes created: 2026-05-03T09:00:00.000Z tags: - release - docs --- # v0.9.1 Release Notes …
External edits to the .md file are detected automatically via a file watcher and reflected in the app within a few seconds — no manual refresh needed.