Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ This is a Cargo workspace with five crates:
- **postgres-lsp-parse** — Document model with tree-sitter incremental parsing, parser pool, and PL/pgSQL injection handling. Core types: `Document`, `ParserPool`.
- **postgres-lsp-analysis** — Symbol extraction from parse trees, `DashMap`-backed workspace index, name resolution, completion, and hover logic. Core types: `Symbol`, `SymbolKind`, `QualifiedName`, `WorkspaceIndex`.
- **postgres-lsp-schema** — Optional live database introspection via `tokio-postgres` against `pg_catalog` (Phase 7).
- **postgres-lsp-format** — SQL formatting powered by [libpgfmt](https://crates.io/crates/libpgfmt). Supports 7 styles (River, Mozilla, Aweber, Dbt, Gitlab, Kickstarter, Mattmc3). Public API: `format_sql(source, options)` and `FormatOptions { style }`.
- **postgres-lsp-format** — SQL formatting powered by [libpgfmt](https://crates.io/crates/libpgfmt). Supports 8 styles (River, Mozilla, Aweber, Dbt, Gitlab, Kickstarter, Mattmc3, PgDump). Public API: `format_sql(source, options)` and `FormatOptions { style }`.
- **postgres-lsp** — Binary crate implementing the LSP via `tower-lsp`. Handles document sync, diagnostics, semantic tokens, go-to-definition, find references, completion, hover, document/workspace symbols, folding ranges, and rename.

### Key Design Constraints
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ serde_json = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
thiserror = "2"
libpgfmt = "1"
libpgfmt = "1.2"

35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,41 @@ A Language Server Protocol (LSP) implementation for PostgreSQL and PL/pgSQL, bui
- **Find References** — Find all usages of a symbol across the workspace
- **Hover** — Show definition source on hover
- **Completion** — Context-aware completion for keywords, tables, columns, and functions
- **Signature Help** — Parameter hints for function calls
- **Folding Ranges** — Collapse multi-line statements
- **Rename** — Rename symbols across the workspace
- **Code Actions** — Quick fixes and refactor rewrites
- **Formatting** — Reformat SQL using one of several style guides
- **PL/pgSQL Support** — Parses PL/pgSQL function bodies with language injection

## Installation

### Homebrew (macOS / Linux)

```bash
brew tap gmr/postgres
brew install postgres-lsp
```

> [!NOTE]
> Homebrew 6.0 added [tap trust](https://docs.brew.sh/Tap-Trust), and some
> versions fail to install third-party taps inside the build sandbox (the
> error mentions `build.rb ... exited with 1`). If you hit this, trust the
> formula first:
>
> ```bash
> brew trust --formula gmr/postgres/postgres-lsp
> ```
>
> or, as a temporary workaround, set `HOMEBREW_NO_REQUIRE_TAP_TRUST=1` for
> the install.

### From Source (via Cargo)

```bash
cargo install postgres-lsp
```

## Building

```bash
Expand All @@ -29,10 +60,10 @@ Requires the [tree-sitter-postgres](https://github.com/gmr/tree-sitter-postgres)
The server communicates over stdio:

```bash
cargo run -p pg-lsp
cargo run -p postgres-lsp
```

Configure your editor to use `pg-lsp` as the language server for `.sql` files.
Configure your editor to use `postgres-lsp` as the language server for `.sql` files.

## License

Expand Down
18 changes: 18 additions & 0 deletions crates/postgres-lsp-format/src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ mod tests {
);
}

#[test]
fn format_with_pg_dump_style() {
let sql = "select a, b from users where active = true";
let opts = FormatOptions {
style: Style::PgDump,
};
let result = format_sql(sql, &opts).unwrap();
assert!(
result.contains("SELECT"),
"expected uppercase SELECT with pg_dump style, got: {result}"
);
}

#[test]
fn parse_pg_dump_style() {
assert_eq!("pg_dump".parse::<Style>().unwrap(), Style::PgDump);
}

#[test]
fn format_plpgsql_block() {
let code = "begin\nraise notice 'hello';\nend;";
Expand Down
4 changes: 2 additions & 2 deletions crates/postgres-lsp/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct Cli {
short = 's',
default_value = "aweber",
value_parser = parse_style,
help = "Formatting style: river, mozilla, aweber, dbt, gitlab, kickstarter, mattmc3"
help = "Formatting style: river, mozilla, aweber, dbt, gitlab, kickstarter, mattmc3, pg_dump"
)]
format_style: Style,

Expand All @@ -38,7 +38,7 @@ struct Cli {
fn parse_style(s: &str) -> Result<Style, String> {
s.parse::<Style>().map_err(|_| {
format!(
"unknown style '{s}'; options: river, mozilla, aweber, dbt, gitlab, kickstarter, mattmc3"
"unknown style '{s}'; options: river, mozilla, aweber, dbt, gitlab, kickstarter, mattmc3, pg_dump"
)
})
}
Expand Down
Loading