Notes Editor
A CodeMirror-based markdown editor with a formatting toolbar, inline selection preview, and a full read mode renderer. Every note is saved as a plain .md file — readable outside Cairn forever.
Write and Read modes
The editor has two modes, toggled from the header bar:
- Write — CodeMirror editor with syntax highlighting, the formatting toolbar, and the inline preview panel
- 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.
⌘B or click to toggle.
Formatting toolbar
The toolbar is always visible in Write 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: #7c6af7 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.
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.