lax-sql 0.1.0

Lax SQL formatter that never reinterprets your code. Dialect agnostic by construction. Usable as a library or a dprint plugin.
Documentation

lax-sql

Lax SQL formatter, usable as a Rust library or as a dprint plugin.

Philosophy

This formatter is deliberately lax, following the same design as lax-css: it never interprets your SQL, only adjusts whitespace. Statements are split at top level clause keywords (select, from, where, joins, ...), each clause goes on its own line, and everything else is preserved as written.

Because nothing is interpreted, the formatter is dialect agnostic by construction: PostgreSQL dollar quoting, MySQL backticks and backslash escapes, T-SQL bracket identifiers, and placeholder styles (?, $1, :name, @var) are all opaque tokens that pass through untouched.

  • A line break is never introduced where the author had no whitespace.
  • Author newlines are preserved, so hand formatted statements keep their shape. Multi line paren groups indent one level per nesting depth.
  • Long clauses wrap at the configured line width, breaking only at existing author spaces.
  • Strings, quoted identifiers, and comments are never modified, except that multi line comment interiors are realigned with their statement.

Keyword casing

The one opt-in exception to "never touch tokens" is keywordCase:

Value Behavior
"preserve" (default) Keywords are kept exactly as written.
"upper" Known SQL keywords are uppercased.
"lower" Known SQL keywords are lowercased.

Only words on a curated keyword list are transformed. Quoted identifiers and function names are different token kinds and can never be affected; unquoted identifiers that collide with a keyword are case insensitive in SQL engines, so the transform is semantics preserving.

Configuration

Key Default Description
lineWidth 120 Target maximum line width.
indentWidth 2 Number of spaces per indent.
useTabs false Use tabs instead of spaces.
newLineKind lf Kind of newline to use.
keywordCase "preserve" See above.

// dprint-ignore and // dprint-ignore-file comment directives are supported and configurable via ignoreNodeCommentText and ignoreFileCommentText.

Development

cargo test

Spec tests live in tests/specs. Each file contains one or more cases with the input followed by an [expect] block.