Skip to content

marimo-team/codemirror-sql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

144 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

codemirror-sql

A CodeMirror extension for SQL linting and visual gutter indicators. Built by and used in marimo.

Features

  • โšก Real-time validation - Per-statement SQL syntax checking as you type, with detailed error messages for every broken statement
  • ๐Ÿง  Schema-aware linting - Warns about unknown tables, unknown columns, and ambiguous column references based on your schema
  • ๐ŸŽจ Visual gutter - Color-coded statement indicators and error highlighting
  • ๐Ÿ’ก Hover tooltips - Schema info, keywords, and column details on hover
  • ๐Ÿ”ฎ CTE autocomplete - Statement-scoped completion of CTE names and their output columns
  • ๐Ÿท๏ธ Alias resolution - Hover and completion understand table aliases (SELECT u.name FROM users u)
  • ๐Ÿ“‡ FROM-aware column completion - Unqualified prefixes complete the columns of the tables in the statement's FROM clause (SELECT e -> email with FROM users), even with many tables in the schema
  • ๐Ÿงญ Navigation - Go-to-definition, reference highlighting, and rename for CTEs and aliases
  • ๐ŸŽฏ Query-aware resolution - Context-sensitive schema and column suggestions
  • ๐Ÿ” Additional dialects - DuckDB, BigQuery, Dremio
  • ๐Ÿ› ๏ธ Custom renderers - Customizable tooltip rendering for tables, columns, and keywords

Installation

npm install @marimo-team/codemirror-sql
# or
pnpm add @marimo-team/codemirror-sql

Usage

Basic Setup

import { sql, StandardSQL } from "@codemirror/lang-sql";
import { basicSetup, EditorView } from "codemirror";
import { sqlExtension, cteCompletionSource, aliasColumnCompletionSource, unqualifiedColumnCompletionSource } from "@marimo-team/codemirror-sql";

const schema = {
  users: ["id", "name", "email", "active"],
  posts: ["id", "title", "content", "user_id"],
};

const editor = new EditorView({
  doc: "SELECT * FROM users WHERE active = true",
  extensions: [
    basicSetup,
    sql({
      dialect: StandardSQL,
      schema: schema,
      upperCaseKeywords: true,
    }),
    StandardSQL.language.data.of({
      autocomplete: cteCompletionSource,
    }),
    StandardSQL.language.data.of({
      // Complete `u.` -> columns of `users` in `SELECT ... FROM users u`
      autocomplete: aliasColumnCompletionSource({ schema }),
    }),
    StandardSQL.language.data.of({
      // Complete `SELECT e` -> `email` because `FROM users` is in the statement
      autocomplete: unqualifiedColumnCompletionSource({ schema }),
    }),
    sqlExtension({
      // Shared by hover tooltips and semantic linting
      schema: schema,
      linterConfig: {
        delay: 250, // Validation delay in ms
      },
      gutterConfig: {
        backgroundColor: "#3b82f6", // Current statement color
        errorBackgroundColor: "#ef4444", // Error highlight color
        hideWhenNotFocused: true,
      },
      enableHover: true,
      hoverConfig: {
        hoverTime: 300,
        enableKeywords: true,
        enableTables: true,
        enableColumns: true,
      },
    }),
  ],
  parent: document.querySelector("#editor"),
});

Schema-aware semantic linting

When a schema is provided (via the top-level schema option, the sqlSchemaFacet, or semanticLinterConfig.schema), queries are validated against it: unknown tables, unknown columns, and ambiguous column references are reported as warnings (configurable per check). Without a schema the semantic linter is inert.

import { EditorView } from "codemirror";
import { sqlSemanticLinter } from "@marimo-team/codemirror-sql";

const editor = new EditorView({
  extensions: [
    sqlSemanticLinter({
      schema: { users: ["id", "name"], posts: ["id", "user_id"] },
      severity: {
        unknownTable: "error", // "error" | "warning" | "off" (default: "warning")
        unknownColumn: "warning",
        ambiguousColumn: "warning",
      },
    }),
  ],
  parent: document.querySelector("#editor"),
});

Checks only run on statements that parse cleanly, and skip anything that can't be confidently resolved (CTE outputs, subquery results, aliases from outer scopes), preferring under-reporting over false positives. Semantic diagnostics carry source: "sql-schema"; syntax diagnostics use source: "sql-parser". If the schema is provided as a function, it is called on every lint pass and should be cheap/memoized.

Navigation: go-to-definition, highlights, rename

sqlExtension includes navigation for statement-local identifiers (CTE names, table aliases, select aliases) by default: the references of the identifier under the cursor are highlighted, and Mod-click (Cmd/Ctrl-click) on a resolvable identifier jumps to its definition. Keybindings (F12/Mod-b for go-to-definition, F2 for rename) are opt-in:

import { renameSqlIdentifier, sqlExtension } from "@marimo-team/codemirror-sql";

sqlExtension({
  enableNavigation: true, // default
  navigationConfig: {
    keymap: true, // enable F12 / Mod-b / F2
    // Supply your own rename UI (defaults to window.prompt)
    prompt: (currentName) => window.prompt(`Rename '${currentName}' to:`, currentName),
  },
});

// Rename programmatically: rewrites the definition and all references
// in a single undo step
await renameSqlIdentifier(view, { prompt: () => "new_name" });

The pieces are also exported individually: sqlHighlightReferences, sqlGotoDefinition, sqlNavigationKeymap, gotoSqlDefinition, and findReferences. Rename returns false when the identifier can't be confidently resolved โ€” it never falls back to text search-and-replace.

Additional Dialects

This extension adds support for additional dialects:

  • DuckDB
  • BigQuery
  • Dremio

Keyword Completion

The extension includes keyword documentation for common SQL keywords including used in hover and completion, which can be found in the src/data directory.

Demo

See the demo for a full example.

Development

# Install dependencies
pnpm install

# Run tests
pnpm test

# Run demo
pnpm dev

License

Apache 2.0

About

A CodeMirror extension for SQL linting, hover, and completions. With support for DuckDB and BigQuery

Topics

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Contributors

Languages