You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+26-18Lines changed: 26 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,8 @@
6
6
7
7
A hybrid markdown editor combining raw text editing with live inline rendering.
8
8
9
+

10
+
9
11
## Install
10
12
11
13
```bash
@@ -55,7 +57,9 @@ comment = "#7A88B8"
55
57
56
58
### Inline git diff
57
59
58
-
When the open file lives in a git repository, writ renders a live inline diff against `HEAD`: added lines and words are tinted green, deleted lines appear as red "ghost" rows above their position, all with the same markdown rendering as the rest of the document. writ watches the file, so edits made by an external tool (e.g. an AI agent) reload and re-diff live.
60
+
When the open file lives in a git repository, writ renders a live inline diff against `HEAD`: added lines and words are tinted green, deleted lines appear as red "ghost" rows above their position, all with the same markdown rendering as the rest of the document. writ watches both the file and the repository's `HEAD`, so edits made by an external tool (e.g. an AI agent) reload and re-diff live — and committing, amending, or switching branches re-bases the diff immediately, even when the working file itself is untouched.
61
+
62
+

59
63
60
64
### GitHub integration
61
65
@@ -96,19 +100,15 @@ On Linux, using a faster linker significantly improves build times. See [Zed's l
96
100
97
101
### Build Profiles
98
102
99
-
Debug builds are significantly slower, especially for image loading and text rendering. For day-to-day development with better performance, use the `release-fast` profile:
100
-
101
-
```bash
102
-
cargo run --profile release-fast -- --file path/to/document.md
103
-
```
103
+
The dev profile optimizes dependencies (`opt-level = 2` for all deps, via `[profile.dev.package."*"]`) while keeping writ's own code unoptimized and debuggable — so a plain `cargo run` is comfortably interactive (the graphics/parsing stack — wgpu, Vello, Parley, tree-sitter — runs at full speed). Dependencies compile once, so incremental writ builds stay fast.
104
104
105
105
For maximum runtime performance (slower compile times), use a full release build:
106
106
107
107
```bash
108
108
cargo run --release -- --file path/to/document.md
109
109
```
110
110
111
-
The release profile enables thin LTO and single codegen unit for best optimization. The`release-fast` profile trades some runtime performance for faster compilation by disabling LTO and using parallel codegen units.
111
+
The release profile enables thin LTO and a single codegen unit for best optimization; the`release-fast` profile (`cargo run --profile release-fast`) trades some of that for faster compilation by disabling LTO and using parallel codegen units.
112
112
113
113
## Features
114
114
@@ -126,6 +126,12 @@ Unordered list markers (`-`) are replaced with bullet symbols when the cursor is
126
126
127
127
Nesting is fully supported. A task item inside a blockquote is represented internally as a stack of layers, and each layer contributes its visual treatment independently.
128
128
129
+
### Callouts
130
+
131
+
Obsidian-style callouts — a blockquote whose first line is `> [!note]` (or `tip`, `warning`, `danger`, `success`, `question`, `example`, `quote`, …) — render inline with a type icon and accent color. Twelve types with their aliases are recognized. Add `+`/`-` after the type (`> [!tip]-`) to make a callout foldable (and start it collapsed); callouts nest, and each nesting level folds independently with the same gutter-chevron gestures as headings and lists. A custom title after the type (`> [!warning] Be careful`) replaces the default. As with other markers, the raw `[!type]` syntax reveals while your cursor is on the header line.
132
+
133
+

134
+
129
135
### Smart Enter and Tab
130
136
131
137
Enter inserts a raw newline—no magic. Shift+Enter continues the current container by copying markers from the current line (e.g., on `- item|`, Shift+Enter creates `\n- `). Shift+Alt+Enter creates an indented continuation for nested paragraphs within list items.
@@ -142,24 +148,32 @@ Full selection support with click, drag (with edge auto-scroll), shift+arrow key
142
148
143
149
### GFM Tables
144
150
145
-
Pipe tables render as a live grid — bold header, per-column alignment (`:--`/`:-:`/`--:`), and inline styles (bold, code, links) inside cells. Move your cursor into a table and it reveals the raw pipe source for editing; move out and it snaps back to the grid. Type a header row like `| Name | Age |` and press Shift+Enter to scaffold the delimiter and a body row; Tab moves between cells (and appends a row from the last cell).
151
+
Pipe tables render as a live grid — bold header, per-column alignment (`:--`/`:-:`/`--:`), and inline styles (bold, code, links) inside cells. Move your cursor into a table and it reveals the raw pipe source for editing; move out and it snaps back to the grid. Type a header row like `| Name | Age |` and press Shift+Enter to scaffold the delimiter and a body row; Tab moves between cells (and appends a row from the last cell). Type a new column into the header and the delimiter and every body row grow to match — in place, wherever you added it. Backspace on a freshly-added empty row removes it in one press.
152
+
153
+

146
154
147
155
### Find and Replace
148
156
149
157
Ctrl+F opens a find bar docked above the status bar; Ctrl+H adds the replace row. Matches highlight live with a count, and the current match is emphasized; Enter/Shift+Enter cycle through them. Toggle regular expressions (Alt+R, with `$1` capture groups in the replacement) and case sensitivity (Alt+C). Enter in the replace field swaps the current match, Ctrl+Enter replaces all in one undo step. Click into the document to keep the bar open while you edit.
150
158
151
159
### Folding
152
160
153
-
Headings and nested lists fold from the gutter. Hover the left margin to reveal a chevron on any foldable line and click to collapse its section; the outline mirrors what's folded. Modifier-clicks scope the fold: Ctrl folds every section at that level, Shift folds recursively, Ctrl+Shift folds that level and everything deeper. Jumping to a hidden line auto-unfolds it. Task lists fold the same way, so a long checklist collapses to its parent item.
161
+
Headings, nested lists, and callouts all fold from the gutter through one unified model. Hover the left margin to reveal a chevron on any foldable line and click to collapse its section; the outline mirrors what's folded. Modifier-clicks scope the fold: Ctrl folds every section at that level, Shift folds recursively, Ctrl+Shift folds that level and everything deeper. Jumping to a hidden line auto-unfolds it. Task lists fold the same way, so a long checklist collapses to its parent item.
162
+
163
+

154
164
155
165
### Mermaid Diagrams
156
166
157
167
Fenced ` ```mermaid ` blocks render inline as diagrams. Rendering runs off the UI thread and is cached, so scrolling stays smooth. Drag a selection through a diagram (or move the cursor onto its block) and it de-sugars back to the raw source you're actually editing, then snaps back to the rendered diagram when you leave.
158
168
169
+

170
+
159
171
### Math
160
172
161
173
LaTeX math renders inline via RaTeX with the KaTeX fonts embedded. Block `$$…$$` renders as centered display math on its own line; inline `$…$` renders as a baseline-aligned box within the text (the GitHub/pandoc rule keeps prose like "$5 and $10" literal). Glyphs take the theme foreground color. As with mermaid, moving the cursor into a span reveals its raw source for editing.
162
174
175
+

176
+
163
177
## Library Usage
164
178
165
179
writ is also a library: its rendering and editing layers work independently of the
@@ -229,7 +243,7 @@ and opt into only what you need:
229
243
230
244
```toml
231
245
# render-only: pulls in none of tokio/reqwest/gix/github/winit
232
-
writ = { version = "0.15", default-features = false }
246
+
writ = { version = "0.16", default-features = false }
233
247
```
234
248
235
249
| Feature | Adds |
@@ -269,12 +283,6 @@ This manual extraction approach was chosen over tree-sitter's built-in injection
269
283
270
284
Currently Rust and Bash are supported; adding a language requires just the grammar crate and a highlights.scm query file. Highlights are cached and only recomputed after edits.
271
285
272
-
## Known Issues
273
-
274
-
### Short Headings Not Styled While Typing
275
-
276
-
When typing `# Hello`, tree-sitter doesn't recognize it as a heading until enough content is present or a newline is added. This is a quirk of the tree-sitter-md grammar. The heading styling appears once you press Enter or type enough characters.
277
-
278
-
### Ordered List Continuation Shows Wrong Number
286
+
## Limitations
279
287
280
-
Pressing Shift+Enter on an ordered list item inserts `1. `as a placeholder. The correct number appears after you start typing, when tree-sitter recognizes the list structure and auto-numbering corrects it.
288
+
Only **ATX** headings (`# Heading`) are recognized — setext headings (a line underlined with `===` or `---`) render as plain text and don't appear in the outline or fold. This is deliberate: setext text and its underline live on separate lines, so full support means both collecting *and* rendering it across the pair, for a syntax `#` dominates in practice.
0 commit comments