https://github.com/minfhs/pgformat
Highly opinionated PostgreSQL formatter
https://github.com/minfhs/pgformat
formatter postgres sql
Last synced: about 1 month ago
JSON representation
Highly opinionated PostgreSQL formatter
- Host: GitHub
- URL: https://github.com/minfhs/pgformat
- Owner: minfhs
- Created: 2025-01-29T07:53:24.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-10-18T00:05:36.000Z (8 months ago)
- Last Synced: 2025-12-01T17:45:45.901Z (7 months ago)
- Topics: formatter, postgres, sql
- Language: OCaml
- Homepage:
- Size: 43.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# pgformat - PostgreSQL Formatter
An opinionated PostgreSQL code formatter built in OCaml with configurable formatting options.
## Features
✨ **Smart SQL Formatting**
- Consistent indentation and line breaks
- Proper comma placement and spacing
- Function and procedure formatting
- Complex query structure normalization
🔧 **Configurable Options**
- Customizable indentation size
- Adjustable line length limits
- Boolean formatting preferences
- Project-level configuration files
🚀 **Multiple Interfaces**
- Command-line tool with rich options
- VS Code extension support
- Editor integrations (Helix, etc.)
- Programmatic FormatterBuilder API
## Installation
### Quick Install
```bash
just up
just install # installs to /usr/local/bin
```
### From Source
```bash
dune build
dune install
```
## Usage
### Basic Command Line
```bash
# Format a file
pgformat myfile.sql
# Format from stdin
echo "SELECT a,b FROM users;" | pgformat
# Format with custom indentation
pgformat myfile.sql -indent-size 2
# Format with custom line length
pgformat myfile.sql -max-line-length 80
```
### Configuration File
Create a `.pgformat` file in your project root for consistent formatting:
```ini
# .pgformat configuration file
indent-size = 2
max-line-length = 80
newline-after-semicolon = true
space-after-comma = true
```
Command-line options override config file settings.
### Help
```bash
pgformat --help
```
## Editor Integration
### VS Code
Install the pgformat extension following this [guide](./.vscode/README.md).
### Helix
Add to your `languages.toml`:
```toml
[[language]]
name = "sql"
auto-format = true
formatter = { command = "pgformat" }
```
Check with `hx --health sql`.
### Other Editors
pgformat works with any editor that supports external formatters. Configure your editor to run `pgformat` on SQL files.
## Configuration Options
| Option | Type | Default | Description |
| ------------------------- | ------- | ------- | -------------------------------------- |
| `indent-size` | integer | 4 | Number of spaces per indentation level |
| `max-line-length` | integer | 120 | Maximum line length before wrapping |
| `newline-after-semicolon` | boolean | true | Add newline after semicolons |
| `space-after-comma` | boolean | true | Add space after commas |
### Configuration Precedence
1. Command-line arguments (highest priority)
2. `.pgformat` file in current directory
3. Default values (fallback)
## Sample Output
### Before
```sql
SELECT , reviews.room_id , reviews.user_id , reviews.state AS "state: ReviewState"
, applicants.state AS "applicant_state: ApplicantState"
FROM applicant_reviews AS reviews LEFT JOIN (
SELECT id , fhs_id , state FROM applicants ) AS applicants ON applicants.id
= reviews.applicant_id
WHERE
reviews.room_id = ( SELECT id FROM rooms
WHERE abbr = $1 AND y = x )
AND applicants.state IS NOT NULL AND applicants.fhs_id IS NOT NULL;
```
### After
```sql
SELECT
reviews.id AS id
, applicants.fhs_id AS fhs_id
, applicants.id AS applicant_id
, reviews.room_id
, reviews.user_id
, reviews.state AS "state: ReviewState"
, applicants.state AS "applicant_state: ApplicantState"
FROM applicant_reviews AS reviews
LEFT JOIN (
SELECT
id
, fhs_id
, state
FROM applicants
) AS applicants ON applicants.id = reviews.applicant_id
WHERE
reviews.room_id = (
SELECT
id
FROM rooms
WHERE
abbr = $1
AND y = x
)
AND applicants.state IS NOT NULL
AND applicants.fhs_id IS NOT NULL;
```
## Development
### Running Tests
```bash
# Run all tests
dune runtest
# Run tests in watch mode
dune runtest -w
# Run specific test
dune runtest test/
```
### Testing the Formatter
```bash
# Test on fixture files
dune exec bin/main.exe fixture/complex.sql
# Test with different configurations
echo "SELECT a,b FROM users;" | dune exec bin/main.exe -- -indent-size 2
```
### Building
```bash
# Build library and executables
dune build
# Build in watch mode
dune build -w
```
## Architecture
pgformat uses a modular architecture with:
- **Lexer**: Tokenizes SQL input
- **Parser**: Processes tokens with formatting rules
- **Formatters**: Specialized modules for different token types
- Comment Formatter
- Keyword Formatter
- Literal Formatter
- Punctuation Formatter
- **Builder Pattern**: Configurable formatter construction
- **Output Interface**: Pluggable output destinations
### FormatterBuilder API
For programmatic use:
```ocaml
open Pgformat
let config = { Config.default_config with indent_size = 2 } in
let builder = Builder.FormatterBuilder.create ()
|> Builder.FormatterBuilder.with_indent_size config.indent_size
|> Builder.FormatterBuilder.with_max_line_length config.max_line_length in
Builder.FormatterBuilder.format_with_config builder lexbuf
```
## Examples
Check the [fixture](./fixture) directory for formatted examples demonstrating various SQL constructs:
- `complex.sql` - Complex queries with functions and nested structures
- `create.sql` - Table creation statements
- `select.sql` - Various SELECT query patterns
- `select_simple.sql` - Basic SELECT statements
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Ensure all tests pass: `dune runtest`
5. Submit a pull request
## License
This project is licensed under the terms specified in the repository.