lsp_events.go

 1package app
 2
 3import (
 4	"context"
 5	"time"
 6
 7	"github.com/charmbracelet/crush/internal/csync"
 8	"github.com/charmbracelet/crush/internal/lsp"
 9	"github.com/charmbracelet/crush/internal/pubsub"
10)
11
12// LSPEventType represents the type of LSP event
13type LSPEventType string
14
15const (
16	LSPEventStateChanged       LSPEventType = "state_changed"
17	LSPEventDiagnosticsChanged LSPEventType = "diagnostics_changed"
18)
19
20// LSPEvent represents an event in the LSP system
21type LSPEvent struct {
22	Type            LSPEventType
23	Name            string
24	State           lsp.ServerState
25	Error           error
26	DiagnosticCount int
27}
28
29// LSPClientInfo holds information about an LSP client's state
30type LSPClientInfo struct {
31	Name            string
32	State           lsp.ServerState
33	Error           error
34	Client          *lsp.Client
35	DiagnosticCount int
36	ConnectedAt     time.Time
37}
38
39var (
40	lspStates = csync.NewMap[string, LSPClientInfo]()
41	lspBroker = pubsub.NewBroker[LSPEvent]()
42)
43
44// SubscribeLSPEvents returns a channel for LSP events
45func SubscribeLSPEvents(ctx context.Context) <-chan pubsub.Event[LSPEvent] {
46	return lspBroker.Subscribe(ctx)
47}
48
49// GetLSPStates returns the current state of all LSP clients
50func GetLSPStates() map[string]LSPClientInfo {
51	return lspStates.Copy()
52}
53
54// GetLSPState returns the state of a specific LSP client
55func GetLSPState(name string) (LSPClientInfo, bool) {
56	return lspStates.Get(name)
57}
58
59// updateLSPState updates the state of an LSP client and publishes an event
60func updateLSPState(name string, state lsp.ServerState, err error, client *lsp.Client, diagnosticCount int) {
61	info := LSPClientInfo{
62		Name:            name,
63		State:           state,
64		Error:           err,
65		Client:          client,
66		DiagnosticCount: diagnosticCount,
67	}
68	if state == lsp.StateReady {
69		info.ConnectedAt = time.Now()
70	}
71	lspStates.Set(name, info)
72
73	// Publish state change event
74	lspBroker.Publish(pubsub.UpdatedEvent, LSPEvent{
75		Type:            LSPEventStateChanged,
76		Name:            name,
77		State:           state,
78		Error:           err,
79		DiagnosticCount: diagnosticCount,
80	})
81}
82
83// updateLSPDiagnostics updates the diagnostic count for an LSP client and publishes an event
84func updateLSPDiagnostics(name string, diagnosticCount int) {
85	if info, exists := lspStates.Get(name); exists {
86		info.DiagnosticCount = diagnosticCount
87		lspStates.Set(name, info)
88
89		// Publish diagnostics change event
90		lspBroker.Publish(pubsub.UpdatedEvent, LSPEvent{
91			Type:            LSPEventDiagnosticsChanged,
92			Name:            name,
93			State:           info.State,
94			Error:           info.Error,
95			DiagnosticCount: diagnosticCount,
96		})
97	}
98}