chore: more work done and planning with AI.
CI / Test (push) Failing after 25s
CI / Build (push) Has been skipped

This commit is contained in:
2026-06-30 22:43:25 +02:00
parent a58b081cae
commit c8030247f2
15 changed files with 4948 additions and 157 deletions
+85
View File
@@ -71,6 +71,89 @@ to the intended style below.
`::`, `->`, `->>`, array `[...]`, or before a call's `(`.
- Dollar-quote tags preserved verbatim (`$$`, `$S$`, `$Z$`, …).
## DataGrip settings mapping
`PostgresCodeStyleSettings` (DataGrip / JetBrains) is the reference for all configurable
style options. The table below maps every relevant DataGrip key to its `.pgtidy.yaml`
counterpart so a user can reproduce their DataGrip style exactly in PgTidy.
DataGrip enum conventions used below:
- **Case**: 0=preserve, 1=upper, 2=lower
- **Comma**: 1=leading (`,col`), 2=trailing (`col,`)
- **Placement**: 1=same_line, 2=new_line
- **Wrap**: 0=never, 1=when_long, 2=always
### Casing
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `KEYWORD_CASE` | `keyword_case` | `upper` | SELECT, FROM, WHERE, … |
| `IDENTIFIER_CASE` | `ident_case` | `lower` | unquoted column/variable names |
| `TYPE_CASE` | `type_case` | `lower` | built-in type names (text, integer, …) |
| `CUSTOM_TYPE_CASE` | `custom_type_case` | `lower` | user-defined / domain types |
| `ALIAS_CASE` | `alias_case` | `lower` | column and table aliases |
| `BUILT_IN_CASE` | `builtin_case` | `lower` | built-in functions (COALESCE, MAX, …) |
### Query layout
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `QUERY_EL_COMMA` | `commas` | `leading` | applies to all clause element lists |
| `QUERY_ALIGN_ELEMENTS` | `align_columns` | `false` | align SELECT list items to same column |
| `QUERY_ALIGN_LINE_COMMENTS` | `align_line_comments` | `false` | align `--` inline comments in a block |
| `SELECT_ALIGN_AS` | `select_align_as` | `false` | align `AS` keyword across SELECT list |
| `FROM_INDENT_JOIN` | `indent_join` | `false` | indent JOIN relative to FROM |
| `FROM_ONLY_JOIN_INDENT` | `join_indent_size` | `1` | extra indent levels for JOINs |
| `SET_ALIGN_EQUAL_SIGN` | `set_align_equal` | `false` | align `=` in UPDATE SET list |
| `WHERE_EL_WRAP` + `WHERE_EL_LINE` | `where_wrap` | `always` | always \| when_long \| never — each AND/OR condition on its own line |
| _(no DataGrip equivalent)_ | `where_and_or_indent` | `true` | when true, AND/OR are indented one level under WHERE, not at WHERE's column |
### Subqueries
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `SUBQUERY_OPENING` | `subquery_opening` | `same_line` | opening `(` placement |
| `SUBQUERY_CONTENT` | `subquery_content` | `new_line` | content indentation inside paren |
| `SUBQUERY_CLOSING` | `subquery_closing` | `new_line` | closing `)` placement |
| `SUBQUERY_PAR_SPACE_BEFORE` | `subquery_space_before_paren` | `false` | space before `(` |
### INSERT
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `INSERT_COLLAPSE_MULTI_ROW_VALUES` | `insert_collapse_values` | `true` | fold VALUES rows into fewer lines |
### Routine (function / procedure)
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `ROUTINE_ARG_COMMA` | uses `commas` | `leading` | same setting as query lists |
| `ROUTINE_ARG_ALIGN_TYPES` | `align_param_types` | `true` | align type column in param list |
| `ROUTINE_AS_WRAP` | `routine_as_wrap` | `true` | newline before `AS $$` |
### PL/pgSQL body
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `IMP_COMMON_KEEP_BLANK_LINES_IN_CODE` | `plpgsql_max_blank_lines` | `1` | max consecutive blank lines in body |
| `IMP_DECLARE_ALIGN_TYPE` | `plpgsql_declare_align_type` | `false` | align type column in DECLARE block |
| `IMP_DECLARE_ALIGN_EQ` | `plpgsql_declare_align_eq` | `false` | align `:=` / `=` in DECLARE block |
| `IMP_IF_THEN_WRAP_THEN` | `plpgsql_if_then_newline` | `true` | THEN on its own line |
| `IMP_LOOP_COLLAPSE` | `plpgsql_loop_collapse` | `true` | collapse empty loop bodies |
### Expressions
| DataGrip key | PgTidy key | Default | Notes |
|---|---|---|---|
| `EXPR_BINARY_OP_ALIGN` | `binary_op_align` | `false` | align `=`, `<>`, `||`, … vertically in WHERE/expression lists; default false — must not be hardcoded |
| `EXPR_CALL_SPACE_AFTER_COMMA` | `space_after_comma_in_calls` | `false` | space after `,` in function calls |
| `EXPR_CASE_WHEN_WRAP` | `case_when_wrap` | `false` | each WHEN on its own line |
| `EXPR_CASE_END` | `case_end` | `new_line` | same_line \| new_line |
| `EXPR_CASE_COLLAPSE` | `case_collapse` | `false` | collapse short CASE to one line |
| `CORTEGE_SPACE_BEFORE_L_PAREN` | `record_space_before_paren` | `false` | space before `(` in ROW/record constructors |
---
## Milestones
### V1 — Formatter + CLI (priority)
@@ -88,6 +171,8 @@ to the intended style below.
5. **CLI** (`cmd/pgtidy fmt`): `--check`, `--write`/`-w`, stdin→stdout, `--diff`; config
discovery walking up to `.pgtidy.yaml`; CI-friendly exit codes.
6. **Config** (`pkg/config`): load/merge style config; defaults = house style above.
Full field set defined in the DataGrip settings mapping section above — covers casing
(6 keys), query layout, subqueries, INSERT, routines, PL/pgSQL body, and expressions.
**Safety guarantees (tested):** semantic equivalence (re-lex output, compare non-trivia token
stream to input), and idempotence (`fmt(fmt(x)) == fmt(x)`). The corpus is the