handlers.go

  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, &registerParams); 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}