|
1 | | -import { sql } from "@codemirror/lang-sql"; |
| 1 | +import { SQLDialect, StandardSQL, sql } from "@codemirror/lang-sql"; |
2 | 2 | import { basicSetup, EditorView } from "codemirror"; |
| 3 | +import { cteCompletionSource } from "../src/sql/cte-completion-source.js"; |
3 | 4 | import { sqlExtension } from "../src/sql/extension.js"; |
| 5 | +import type { SqlKeywordInfo } from "../src/sql/hover.js"; |
4 | 6 |
|
5 | 7 | // Default SQL content for the demo |
6 | 8 | const defaultSqlDoc = `-- Welcome to the SQL Editor Demo! |
7 | 9 | -- Try editing the queries below to see real-time validation |
8 | 10 |
|
| 11 | +WITH cte_name AS ( |
| 12 | + SELECT * FROM users |
| 13 | +) |
| 14 | +
|
9 | 15 | -- Valid queries (no errors): |
10 | 16 | SELECT id, name, email |
11 | 17 | FROM users |
@@ -46,23 +52,91 @@ WHERE order_date >= '2024-01-01' |
46 | 52 | ORDER BY total_amount DESC; |
47 | 53 | `; |
48 | 54 |
|
| 55 | +const schema = { |
| 56 | + // Users table |
| 57 | + users: ["id", "name", "email", "active", "status", "created_at", "updated_at", "profile_id"], |
| 58 | + // Posts table |
| 59 | + posts: [ |
| 60 | + "id", |
| 61 | + "title", |
| 62 | + "content", |
| 63 | + "user_id", |
| 64 | + "published", |
| 65 | + "created_at", |
| 66 | + "updated_at", |
| 67 | + "category_id", |
| 68 | + ], |
| 69 | + // Orders table |
| 70 | + orders: [ |
| 71 | + "id", |
| 72 | + "customer_id", |
| 73 | + "order_date", |
| 74 | + "total_amount", |
| 75 | + "status", |
| 76 | + "shipping_address", |
| 77 | + "created_at", |
| 78 | + ], |
| 79 | + // Customers table (additional example) |
| 80 | + customers: ["id", "first_name", "last_name", "email", "phone", "address", "city", "country"], |
| 81 | + // Categories table |
| 82 | + categories: ["id", "name", "description", "parent_id"], |
| 83 | +}; |
| 84 | + |
49 | 85 | let editor: EditorView; |
50 | 86 |
|
| 87 | +const completionKindStyles = { |
| 88 | + borderRadius: "4px", |
| 89 | + padding: "2px 4px", |
| 90 | + marginRight: "4px", |
| 91 | + display: "inline-flex", |
| 92 | + alignItems: "center", |
| 93 | + justifyContent: "center", |
| 94 | + width: "12px", |
| 95 | + height: "12px", |
| 96 | +}; |
| 97 | + |
| 98 | +const dialect = StandardSQL; |
| 99 | + |
51 | 100 | // Initialize the SQL editor |
52 | 101 | function initializeEditor() { |
53 | 102 | const extensions = [ |
54 | 103 | basicSetup, |
55 | 104 | EditorView.lineWrapping, |
56 | | - sql(), // SQL language support |
| 105 | + sql({ |
| 106 | + dialect: dialect, |
| 107 | + // Example schema for autocomplete |
| 108 | + schema: schema, |
| 109 | + // Enable uppercase keywords for more traditional SQL style |
| 110 | + upperCaseKeywords: true, |
| 111 | + }), |
57 | 112 | sqlExtension({ |
58 | | - // Our custom SQL extension with diagnostics and structure analysis |
59 | | - delay: 250, // Delay before running validation |
60 | | - enableStructureAnalysis: true, // Enable gutter markers for SQL expressions |
61 | | - enableGutterMarkers: true, // Show vertical bars in gutter |
62 | | - backgroundColor: "#3b82f6", // Blue for current statement |
63 | | - errorBackgroundColor: "#ef4444", // Red for invalid statements |
64 | | - hideWhenNotFocused: true, // Hide gutter when editor loses focus |
65 | | - // unfocusedOpacity: 0.1, // Alternative: set low opacity instead of hiding |
| 113 | + // Linter extension configuration |
| 114 | + linterConfig: { |
| 115 | + delay: 250, // Delay before running validation |
| 116 | + }, |
| 117 | + |
| 118 | + // Gutter extension configuration |
| 119 | + gutterConfig: { |
| 120 | + backgroundColor: "#3b82f6", // Blue for current statement |
| 121 | + errorBackgroundColor: "#ef4444", // Red for invalid statements |
| 122 | + hideWhenNotFocused: true, // Hide gutter when editor loses focus |
| 123 | + }, |
| 124 | + // Hover extension configuration |
| 125 | + enableHover: true, // Enable hover tooltips |
| 126 | + hoverConfig: { |
| 127 | + schema: schema, // Use the same schema as autocomplete |
| 128 | + hoverTime: 300, // 300ms hover delay |
| 129 | + enableKeywords: true, // Show keyword information |
| 130 | + enableTables: true, // Show table information |
| 131 | + enableColumns: true, // Show column information |
| 132 | + keywords: async () => { |
| 133 | + const keywords = await import("../src/data/common-keywords.json"); |
| 134 | + return keywords.default.keywords; |
| 135 | + }, |
| 136 | + }, |
| 137 | + }), |
| 138 | + dialect.language.data.of({ |
| 139 | + autocomplete: cteCompletionSource, |
66 | 140 | }), |
67 | 141 | // Custom theme for better SQL editing |
68 | 142 | EditorView.theme({ |
@@ -94,6 +168,39 @@ function initializeEditor() { |
94 | 168 | color: "#dc2626", |
95 | 169 | fontSize: "13px", |
96 | 170 | }, |
| 171 | + // Completion kind backgrounds |
| 172 | + ".cm-completionIcon-keyword": { |
| 173 | + backgroundColor: "#e0e7ff", // indigo-100 |
| 174 | + ...completionKindStyles, |
| 175 | + }, |
| 176 | + ".cm-completionIcon-variable": { |
| 177 | + backgroundColor: "#fef9c3", // yellow-100 |
| 178 | + ...completionKindStyles, |
| 179 | + }, |
| 180 | + ".cm-completionIcon-property": { |
| 181 | + backgroundColor: "#bbf7d0", // green-100 |
| 182 | + ...completionKindStyles, |
| 183 | + }, |
| 184 | + ".cm-completionIcon-function": { |
| 185 | + backgroundColor: "#bae6fd", // sky-100 |
| 186 | + ...completionKindStyles, |
| 187 | + }, |
| 188 | + ".cm-completionIcon-class": { |
| 189 | + backgroundColor: "#fbcfe8", // pink-100 |
| 190 | + ...completionKindStyles, |
| 191 | + }, |
| 192 | + ".cm-completionIcon-constant": { |
| 193 | + backgroundColor: "#fde68a", // amber-200 |
| 194 | + ...completionKindStyles, |
| 195 | + }, |
| 196 | + ".cm-completionIcon-type": { |
| 197 | + backgroundColor: "#ddd6fe", // violet-200 |
| 198 | + ...completionKindStyles, |
| 199 | + }, |
| 200 | + ".cm-completionIcon-text": { |
| 201 | + backgroundColor: "#f3f4f6", // gray-100 |
| 202 | + ...completionKindStyles, |
| 203 | + }, |
97 | 204 | }), |
98 | 205 | ]; |
99 | 206 |
|
|
0 commit comments