1package lsp
2
3import (
4 "encoding/json"
5 "log/slog"
6
7 "github.com/charmbracelet/crush/internal/lsp/protocol"
8 "github.com/charmbracelet/crush/internal/lsp/util"
9)
10
11// Requests
12
13func (c *Client) HandleWorkspaceConfiguration(params json.RawMessage) (any, error) {
14 return []map[string]any{{}}, nil
15}
16
17func (c *Client) HandleRegisterCapability(params json.RawMessage) (any, error) {
18 var registerParams protocol.RegistrationParams
19 if err := json.Unmarshal(params, ®isterParams); err != nil {
20 slog.Error("Error unmarshaling registration params", "error", err)
21 return nil, err
22 }
23
24 for _, reg := range registerParams.Registrations {
25 switch reg.Method {
26 case "workspace/didChangeWatchedFiles":
27 // Parse the registration options
28 optionsJSON, err := json.Marshal(reg.RegisterOptions)
29 if err != nil {
30 slog.Error("Error marshaling registration options", "error", err)
31 continue
32 }
33
34 var options protocol.DidChangeWatchedFilesRegistrationOptions
35 if err := json.Unmarshal(optionsJSON, &options); err != nil {
36 slog.Error("Error unmarshaling registration options", "error", err)
37 continue
38 }
39
40 // Store the file watchers registrations
41 notifyFileWatchRegistration(reg.ID, options.Watchers)
42 }
43 }
44
45 return nil, nil
46}
47
48func (c *Client) HandleApplyEdit(params json.RawMessage) (any, error) {
49 var edit protocol.ApplyWorkspaceEditParams
50 if err := json.Unmarshal(params, &edit); err != nil {
51 return nil, err
52 }
53
54 err := util.ApplyWorkspaceEdit(edit.Edit)
55 if err != nil {
56 slog.Error("Error applying workspace edit", "error", err)
57 return protocol.ApplyWorkspaceEditResult{Applied: false, FailureReason: err.Error()}, nil
58 }
59
60 return protocol.ApplyWorkspaceEditResult{Applied: true}, nil
61}
62
63// FileWatchRegistrationHandler is a function that will be called when file watch registrations are received
64type FileWatchRegistrationHandler func(id string, watchers []protocol.FileSystemWatcher)
65
66// fileWatchHandler holds the current handler for file watch registrations
67var fileWatchHandler FileWatchRegistrationHandler
68
69// RegisterFileWatchHandler sets the handler for file watch registrations
70func RegisterFileWatchHandler(handler FileWatchRegistrationHandler) {
71 fileWatchHandler = handler
72}
73
74// notifyFileWatchRegistration notifies the handler about new file watch registrations
75func notifyFileWatchRegistration(id string, watchers []protocol.FileSystemWatcher) {
76 if fileWatchHandler != nil {
77 fileWatchHandler(id, watchers)
78 }
79}
80
81// Notifications
82
83func (c *Client) HandleServerMessage(params json.RawMessage) {
84 var msg struct {
85 Type int `json:"type"`
86 Message string `json:"message"`
87 }
88 if err := json.Unmarshal(params, &msg); err == nil {
89 if c.debug {
90 slog.Debug("Server message", "type", msg.Type, "message", msg.Message)
91 }
92 }
93}
94
95func (c *Client) HandleDiagnostics(params json.RawMessage) {
96 var diagParams protocol.PublishDiagnosticsParams
97 if err := json.Unmarshal(params, &diagParams); err != nil {
98 slog.Error("Error unmarshaling diagnostics params", "error", err)
99 return
100 }
101
102 c.diagnosticsMu.Lock()
103 defer c.diagnosticsMu.Unlock()
104
105 c.diagnostics[diagParams.URI] = diagParams.Diagnostics
106}