Skip to content

Commit 01f192a

Browse files
author
sutong.527608
committed
Add LSP server support for organize imports command
Register workspace/executeCommand handler for typescript-go.organizeImports: - Declare command in ExecuteCommandProvider capabilities - Handle command execution and dispatch to language service - Apply text edits via workspace/applyEdit request
1 parent 7d6879c commit 01f192a

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

internal/lsp/server.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ var handlers = sync.OnceValue(func() handlerMap {
463463
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight)
464464
registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol)
465465
registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve)
466+
registerRequestHandler(handlers, lsproto.WorkspaceExecuteCommandInfo, (*Server).handleExecuteCommand)
466467

467468
return handlers
468469
})
@@ -640,6 +641,11 @@ func (s *Server) handleInitialize(ctx context.Context, params *lsproto.Initializ
640641
DocumentHighlightProvider: &lsproto.BooleanOrDocumentHighlightOptions{
641642
Boolean: ptrTo(true),
642643
},
644+
ExecuteCommandProvider: &lsproto.ExecuteCommandOptions{
645+
Commands: []string{
646+
"typescript-go.organizeImports",
647+
},
648+
},
643649
},
644650
}
645651

@@ -844,6 +850,65 @@ func (s *Server) handleDocumentHighlight(ctx context.Context, ls *ls.LanguageSer
844850
return ls.ProvideDocumentHighlights(ctx, params.TextDocument.Uri, params.Position)
845851
}
846852

853+
func (s *Server) handleExecuteCommand(ctx context.Context, params *lsproto.ExecuteCommandParams, _ *lsproto.RequestMessage) (lsproto.ExecuteCommandResponse, error) {
854+
switch params.Command {
855+
case "typescript-go.organizeImports":
856+
return s.handleOrganizeImportsCommand(ctx, params)
857+
default:
858+
return lsproto.LSPAnyOrNull{}, fmt.Errorf("unknown command: %s", params.Command)
859+
}
860+
}
861+
862+
func (s *Server) handleOrganizeImportsCommand(ctx context.Context, params *lsproto.ExecuteCommandParams) (lsproto.ExecuteCommandResponse, error) {
863+
if params.Arguments == nil || len(*params.Arguments) == 0 {
864+
return lsproto.LSPAnyOrNull{}, fmt.Errorf("organizeImports command requires a document URI argument")
865+
}
866+
867+
var documentURI lsproto.DocumentUri
868+
argBytes, err := json.Marshal((*params.Arguments)[0])
869+
if err != nil {
870+
return lsproto.LSPAnyOrNull{}, fmt.Errorf("failed to marshal argument: %w", err)
871+
}
872+
if err := json.Unmarshal(argBytes, &documentURI); err != nil {
873+
return lsproto.LSPAnyOrNull{}, fmt.Errorf("invalid document URI: %w", err)
874+
}
875+
876+
languageService, err := s.session.GetLanguageService(ctx, documentURI)
877+
if err != nil {
878+
return lsproto.LSPAnyOrNull{}, err
879+
}
880+
881+
edits, err := languageService.OrganizeImports(ctx, documentURI, ls.OrganizeImportsModeAll)
882+
if err != nil {
883+
return lsproto.LSPAnyOrNull{}, err
884+
}
885+
886+
if len(edits) == 0 {
887+
return lsproto.LSPAnyOrNull{}, nil
888+
}
889+
890+
editPtrs := make([]*lsproto.TextEdit, len(edits))
891+
for i := range edits {
892+
editPtrs[i] = &edits[i]
893+
}
894+
895+
workspaceEdit := &lsproto.WorkspaceEdit{
896+
Changes: &map[lsproto.DocumentUri][]*lsproto.TextEdit{
897+
documentURI: editPtrs,
898+
},
899+
}
900+
901+
_, err = s.sendRequest(ctx, lsproto.MethodWorkspaceApplyEdit, &lsproto.ApplyWorkspaceEditParams{
902+
Label: ptrTo("Organize Imports"),
903+
Edit: workspaceEdit,
904+
})
905+
if err != nil {
906+
return lsproto.LSPAnyOrNull{}, fmt.Errorf("failed to apply workspace edit: %w", err)
907+
}
908+
909+
return lsproto.LSPAnyOrNull{}, nil
910+
}
911+
847912
func (s *Server) Log(msg ...any) {
848913
fmt.Fprintln(s.stderr, msg...)
849914
}

0 commit comments

Comments
 (0)