|
4 | 4 | codeFolding, |
5 | 5 | foldEffect, |
6 | 6 | foldGutter, |
| 7 | + foldService, |
7 | 8 | } from "@codemirror/language" |
8 | 9 | import { Compartment, EditorState } from "@codemirror/state" |
9 | 10 | import { EditorView, lineNumbers } from "@codemirror/view" |
@@ -47,6 +48,27 @@ function getActiveTheme() { |
47 | 48 | : tokyoNightCmTheme |
48 | 49 | } |
49 | 50 |
|
| 51 | +/** |
| 52 | + * Fold service that tells CM6 where CREATE TABLE folds are possible. |
| 53 | + * This ensures the fold gutter always shows ▾/▸ on CREATE TABLE lines, |
| 54 | + * even after the user unfolds them. |
| 55 | + */ |
| 56 | +const createTableFoldService = foldService.of((state, lineStart) => { |
| 57 | + const line = state.doc.lineAt(lineStart) |
| 58 | + const text = line.text.trimStart() |
| 59 | + if (!text.startsWith("CREATE TABLE")) return null |
| 60 | + |
| 61 | + // Find the end of the statement (the line ending with ;) |
| 62 | + let endLine = line |
| 63 | + for (let n = line.number + 1; n <= state.doc.lines; n++) { |
| 64 | + endLine = state.doc.line(n) |
| 65 | + if (endLine.text.trimEnd().endsWith(";")) break |
| 66 | + } |
| 67 | + |
| 68 | + // Fold from end of first line to end of last line |
| 69 | + return { from: line.to, to: endLine.to } |
| 70 | +}) |
| 71 | + |
50 | 72 | /** |
51 | 73 | * Compute fold ranges for CREATE TABLE statements. |
52 | 74 | * Keeps the first line (CREATE TABLE `name` (...) visible and folds the body |
@@ -115,6 +137,7 @@ function CodeViewer({ |
115 | 137 | bracketMatching(), |
116 | 138 | javascript(), |
117 | 139 | codeFolding({ placeholderText: "…" }), |
| 140 | + createTableFoldService, |
118 | 141 | foldGutter({ |
119 | 142 | openText: "▾", |
120 | 143 | closedText: "▸", |
|
0 commit comments