feat: add LSP server, VSCode + DataGrip extensions, release infra, autofix
CI / Test (push) Failing after 47s
CI / Build snapshot (push) Has been skipped

- pkg/lsp: JSON-RPC 2.0 LSP server (formatting, diagnostics, codeAction quick-fixes)
- cmd/pgtidy: lsp and config subcommands
- pkg/diagnostics: TextFix struct for byte-range autofixes
- pkg/lint: MIG001/MIG003 autofixes, ApplyFixes helper, --fix flag on lint command
- editors/vscode: TypeScript extension with LanguageClient, showVersion/showConfig/formatDocument commands, logo
- editors/datagrip: Gradle JetBrains plugin via LSP4IJ, pluginIcon
- .goreleaser.yaml, .github/workflows: CI + release pipeline
- Makefile: snapshot, release, vscode-compile, vscode-package targets
- go.mod + all imports: module path updated to git.warky.dev/wdevs/pgtidy
- assets: logo files (256px, 128px, 1024px, ico)
This commit is contained in:
2026-06-28 12:48:28 +02:00
parent 7fb76bae3d
commit e88d32f281
49 changed files with 3228 additions and 49 deletions
+39
View File
@@ -0,0 +1,39 @@
package lint
import (
"sort"
"git.warky.dev/wdevs/pgtidy/pkg/diagnostics"
)
// ApplyFixes applies all autofixes from diags to src and returns the result.
// Fixes are applied in reverse-offset order so earlier edits do not shift the
// byte positions of later ones. Overlapping fixes are skipped.
func ApplyFixes(src string, diags []diagnostics.Diagnostic) string {
type fix struct {
offset, end int
new string
}
var fixes []fix
for _, d := range diags {
if d.Fix != nil {
fixes = append(fixes, fix{d.Fix.Offset, d.Fix.End, d.Fix.New})
}
}
if len(fixes) == 0 {
return src
}
sort.Slice(fixes, func(i, j int) bool {
return fixes[i].offset > fixes[j].offset
})
b := []byte(src)
last := len(b) + 1 // sentinel: no fix applied yet
for _, f := range fixes {
if f.end > last {
continue // overlaps a previously applied fix; skip
}
last = f.offset
b = append(b[:f.offset], append([]byte(f.new), b[f.end:]...)...)
}
return string(b)
}