lsp_events.go 2.6 KB

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