diff --git a/gopls/doc/vscode.md b/gopls/doc/vscode.md index c21c894820..f0aff81245 100644 --- a/gopls/doc/vscode.md +++ b/gopls/doc/vscode.md @@ -12,6 +12,12 @@ Use the [VSCode-Go] plugin, with the following configuration: // Optional: Disable snippets, as they conflict with completion ranking. "editor.snippetSuggestions": "none", }, +"[go.mod]": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": true, + }, +}, "gopls": { // Add parameter placeholders when completing a function. "usePlaceholders": true, diff --git a/internal/lsp/format.go b/internal/lsp/format.go index 33dd4072a7..f9bf5aa903 100644 --- a/internal/lsp/format.go +++ b/internal/lsp/format.go @@ -7,18 +7,21 @@ package lsp import ( "context" + "golang.org/x/tools/internal/lsp/mod" "golang.org/x/tools/internal/lsp/protocol" "golang.org/x/tools/internal/lsp/source" ) func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) { - snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go) + snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.UnknownKind) if !ok { return nil, err } - edits, err := source.Format(ctx, snapshot, fh) - if err != nil { - return nil, err + switch fh.Identity().Kind { + case source.Mod: + return mod.Format(ctx, snapshot, fh) + case source.Go: + return source.Format(ctx, snapshot, fh) } - return edits, nil + return nil, nil } diff --git a/internal/lsp/mod/format.go b/internal/lsp/mod/format.go new file mode 100644 index 0000000000..40dfe495f9 --- /dev/null +++ b/internal/lsp/mod/format.go @@ -0,0 +1,26 @@ +package mod + +import ( + "context" + + "golang.org/x/tools/internal/lsp/protocol" + "golang.org/x/tools/internal/lsp/source" + "golang.org/x/tools/internal/telemetry/trace" +) + +func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.TextEdit, error) { + ctx, done := trace.StartSpan(ctx, "mod.Format") + defer done() + + file, m, err := snapshot.ModHandle(ctx, fh).Parse(ctx) + if err != nil { + return nil, err + } + formatted, err := file.Format() + if err != nil { + return nil, err + } + // Calculate the edits to be made due to the change. + diff := snapshot.View().Options().ComputeEdits(fh.Identity().URI, string(m.Content), string(formatted)) + return source.ToProtocolEdits(m, diff) +}