lsp_events.go

  1package app
  2
  3import (
  4	"context"
  5	"maps"
  6	"time"
  7
  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
 20func (e LSPEventType) MarshalText() ([]byte, error) {
 21	return []byte(e), nil
 22}
 23
 24func (e *LSPEventType) UnmarshalText(data []byte) error {
 25	*e = LSPEventType(data)
 26	return nil
 27}
 28
 29// LSPEvent represents an event in the LSP system
 30type LSPEvent struct {
 31	Type            LSPEventType    `json:"type"`
 32	Name            string          `json:"name"`
 33	State           lsp.ServerState `json:"state"`
 34	Error           error           `json:"error,omitempty"`
 35	DiagnosticCount int             `json:"diagnostic_count,omitempty"`
 36}
 37
 38// LSPClientInfo holds information about an LSP client's state
 39type LSPClientInfo struct {
 40	Name            string          `json:"name"`
 41	State           lsp.ServerState `json:"state"`
 42	Error           error           `json:"error,omitempty"`
 43	DiagnosticCount int             `json:"diagnostic_count,omitempty"`
 44	ConnectedAt     time.Time       `json:"connected_at"`
 45}
 46
 47// SubscribeLSPEvents returns a channel for LSP events
 48func (a *App) SubscribeLSPEvents(ctx context.Context) <-chan pubsub.Event[LSPEvent] {
 49	return a.lspBroker.Subscribe(ctx)
 50}
 51
 52// GetLSPStates returns the current state of all LSP clients
 53func (a *App) GetLSPStates() map[string]LSPClientInfo {
 54	return maps.Collect(a.lspStates.Seq2())
 55}
 56
 57// GetLSPState returns the state of a specific LSP client
 58func (a *App) GetLSPState(name string) (LSPClientInfo, bool) {
 59	return a.lspStates.Get(name)
 60}
 61
 62// updateLSPState updates the state of an LSP client and publishes an event
 63func (a *App) updateLSPState(name string, state lsp.ServerState, err error, diagnosticCount int) {
 64	info := LSPClientInfo{
 65		Name:            name,
 66		State:           state,
 67		Error:           err,
 68		DiagnosticCount: diagnosticCount,
 69	}
 70	if state == lsp.StateReady {
 71		info.ConnectedAt = time.Now()
 72	}
 73	a.lspStates.Set(name, info)
 74
 75	// Publish state change event
 76	a.lspBroker.Publish(pubsub.UpdatedEvent, LSPEvent{
 77		Type:            LSPEventStateChanged,
 78		Name:            name,
 79		State:           state,
 80		Error:           err,
 81		DiagnosticCount: diagnosticCount,
 82	})
 83}
 84
 85// updateLSPDiagnostics updates the diagnostic count for an LSP client and publishes an event
 86func (a *App) updateLSPDiagnostics(name string, diagnosticCount int) {
 87	if info, exists := a.lspStates.Get(name); exists {
 88		info.DiagnosticCount = diagnosticCount
 89		a.lspStates.Set(name, info)
 90
 91		// Publish diagnostics change event
 92		a.lspBroker.Publish(pubsub.UpdatedEvent, LSPEvent{
 93			Type:            LSPEventDiagnosticsChanged,
 94			Name:            name,
 95			State:           info.State,
 96			Error:           info.Error,
 97			DiagnosticCount: diagnosticCount,
 98		})
 99	}
100}