service.go

  1package setup
  2
  3import (
  4	"context"
  5
  6	"github.com/opencode-ai/opencode/internal/lsp/protocol"
  7	"github.com/opencode-ai/opencode/internal/pubsub"
  8)
  9
 10// LSPSetupEvent represents an event related to LSP setup
 11type LSPSetupEvent struct {
 12	Type        LSPSetupEventType
 13	Language    protocol.LanguageKind
 14	ServerName  string
 15	Success     bool
 16	Error       error
 17	Description string
 18}
 19
 20// LSPSetupEventType defines the type of LSP setup event
 21type LSPSetupEventType string
 22
 23const (
 24	// EventLanguageDetected is emitted when a language is detected in the workspace
 25	EventLanguageDetected LSPSetupEventType = "language_detected"
 26	// EventServerDiscovered is emitted when an LSP server is discovered
 27	EventServerDiscovered LSPSetupEventType = "server_discovered"
 28	// EventServerInstalled is emitted when an LSP server is installed
 29	EventServerInstalled LSPSetupEventType = "server_installed"
 30	// EventServerInstallFailed is emitted when an LSP server installation fails
 31	EventServerInstallFailed LSPSetupEventType = "server_install_failed"
 32	// EventSetupCompleted is emitted when the LSP setup is completed
 33	EventSetupCompleted LSPSetupEventType = "setup_completed"
 34)
 35
 36// Service defines the interface for the LSP setup service
 37type Service interface {
 38	pubsub.Suscriber[LSPSetupEvent]
 39	
 40	// DetectLanguages detects languages in the workspace
 41	DetectLanguages(ctx context.Context, workspaceDir string) (map[protocol.LanguageKind]int, error)
 42	
 43	// GetPrimaryLanguages returns the top N languages in the project
 44	GetPrimaryLanguages(languages map[protocol.LanguageKind]int, limit int) []LanguageScore
 45	
 46	// DetectMonorepo checks if the workspace is a monorepo
 47	DetectMonorepo(ctx context.Context, workspaceDir string) (bool, []string)
 48	
 49	// DiscoverInstalledLSPs discovers installed LSP servers
 50	DiscoverInstalledLSPs(ctx context.Context) LSPServerMap
 51	
 52	// GetRecommendedLSPServers returns recommended LSP servers for languages
 53	GetRecommendedLSPServers(ctx context.Context, languages []LanguageScore) LSPServerMap
 54	
 55	// InstallLSPServer installs an LSP server
 56	InstallLSPServer(ctx context.Context, server LSPServerInfo) InstallationResult
 57	
 58	// VerifyInstallation verifies that an LSP server is correctly installed
 59	VerifyInstallation(ctx context.Context, serverName string) bool
 60	
 61	// SaveConfiguration saves the LSP configuration
 62	SaveConfiguration(ctx context.Context, servers map[protocol.LanguageKind]LSPServerInfo) error
 63}
 64
 65type service struct {
 66	*pubsub.Broker[LSPSetupEvent]
 67}
 68
 69// NewService creates a new LSP setup service
 70func NewService() Service {
 71	broker := pubsub.NewBroker[LSPSetupEvent]()
 72	return &service{
 73		Broker: broker,
 74	}
 75}
 76
 77// DetectLanguages detects languages in the workspace
 78func (s *service) DetectLanguages(ctx context.Context, workspaceDir string) (map[protocol.LanguageKind]int, error) {
 79	languages, err := DetectProjectLanguages(workspaceDir)
 80	if err != nil {
 81		return nil, err
 82	}
 83	
 84	// Emit events for detected languages
 85	for lang, score := range languages {
 86		if lang != "" && score > 0 {
 87			s.Publish(pubsub.CreatedEvent, LSPSetupEvent{
 88				Type:        EventLanguageDetected,
 89				Language:    lang,
 90				Description: "Language detected in workspace",
 91			})
 92		}
 93	}
 94	
 95	return languages, nil
 96}
 97
 98// GetPrimaryLanguages returns the top N languages in the project
 99func (s *service) GetPrimaryLanguages(languages map[protocol.LanguageKind]int, limit int) []LanguageScore {
100	return GetPrimaryLanguages(languages, limit)
101}
102
103// DetectMonorepo checks if the workspace is a monorepo
104func (s *service) DetectMonorepo(ctx context.Context, workspaceDir string) (bool, []string) {
105	return DetectMonorepo(workspaceDir)
106}
107
108// DiscoverInstalledLSPs discovers installed LSP servers
109func (s *service) DiscoverInstalledLSPs(ctx context.Context) LSPServerMap {
110	servers := DiscoverInstalledLSPs()
111	
112	// Emit events for discovered servers
113	for lang, serverList := range servers {
114		for _, server := range serverList {
115			s.Publish(pubsub.CreatedEvent, LSPSetupEvent{
116				Type:        EventServerDiscovered,
117				Language:    lang,
118				ServerName:  server.Name,
119				Description: "LSP server discovered",
120			})
121		}
122	}
123	
124	return servers
125}
126
127// GetRecommendedLSPServers returns recommended LSP servers for languages
128func (s *service) GetRecommendedLSPServers(ctx context.Context, languages []LanguageScore) LSPServerMap {
129	return GetRecommendedLSPServers(languages)
130}
131
132// InstallLSPServer installs an LSP server
133func (s *service) InstallLSPServer(ctx context.Context, server LSPServerInfo) InstallationResult {
134	result := InstallLSPServer(ctx, server)
135	
136	// Emit event based on installation result
137	eventType := EventServerInstalled
138	if !result.Success {
139		eventType = EventServerInstallFailed
140	}
141	
142	s.Publish(pubsub.CreatedEvent, LSPSetupEvent{
143		Type:        eventType,
144		ServerName:  server.Name,
145		Success:     result.Success,
146		Error:       result.Error,
147		Description: result.Output,
148	})
149	
150	return result
151}
152
153// VerifyInstallation verifies that an LSP server is correctly installed
154func (s *service) VerifyInstallation(ctx context.Context, serverName string) bool {
155	return VerifyInstallation(serverName)
156}
157
158// SaveConfiguration saves the LSP configuration
159func (s *service) SaveConfiguration(ctx context.Context, servers map[protocol.LanguageKind]LSPServerInfo) error {
160	// Update the LSP configuration
161	err := UpdateLSPConfig(servers)
162	
163	// Emit setup completed event
164	s.Publish(pubsub.CreatedEvent, LSPSetupEvent{
165		Type:        EventSetupCompleted,
166		Success:     err == nil,
167		Error:       err,
168		Description: "LSP setup completed",
169	})
170	
171	return err
172}