lsp.go

 1package config
 2
 3import (
 4	"encoding/json"
 5	"os"
 6	"path/filepath"
 7
 8	"github.com/opencode-ai/opencode/internal/logging"
 9	"github.com/opencode-ai/opencode/internal/lsp/protocol"
10)
11
12// LSPServerInfo contains information about an LSP server
13type LSPServerInfo struct {
14	Name        string   // Display name of the server
15	Command     string   // Command to execute
16	Args        []string // Arguments to pass to the command
17	InstallCmd  string   // Command to install the server
18	Description string   // Description of the server
19	Recommended bool     // Whether this is the recommended server for the language
20	Options     any      // Additional options for the server
21}
22
23// UpdateLSPConfig updates the LSP configuration with the provided servers in the local config file
24func UpdateLSPConfig(servers map[protocol.LanguageKind]LSPServerInfo) error {
25	// Create a map for the LSP configuration
26	lspConfig := make(map[string]LSPConfig)
27	
28	for lang, server := range servers {
29		langStr := string(lang)
30		
31		lspConfig[langStr] = LSPConfig{
32			Disabled: false,
33			Command:  server.Command,
34			Args:     server.Args,
35			Options:  server.Options,
36		}
37	}
38	
39	return SaveLocalLSPConfig(lspConfig)
40}
41
42// SaveLocalLSPConfig saves only the LSP configuration to the local config file
43func SaveLocalLSPConfig(lspConfig map[string]LSPConfig) error {
44	// Get the working directory
45	workingDir := WorkingDirectory()
46	
47	// Define the local config file path
48	configPath := filepath.Join(workingDir, ".opencode.json")
49	
50	// Create a new configuration with only the LSP settings
51	localConfig := make(map[string]any)
52	
53	// Read existing local config if it exists
54	if _, err := os.Stat(configPath); err == nil {
55		data, err := os.ReadFile(configPath)
56		if err == nil {
57			if err := json.Unmarshal(data, &localConfig); err != nil {
58				logging.Warn("Failed to parse existing local config", "error", err)
59				// Continue with empty config if we can't parse the existing one
60				localConfig = make(map[string]any)
61			}
62		}
63	}
64	
65	// Update only the LSP configuration
66	localConfig["lsp"] = lspConfig
67	
68	// Marshal the configuration to JSON
69	data, err := json.MarshalIndent(localConfig, "", "  ")
70	if err != nil {
71		return err
72	}
73	
74	// Write the configuration to the file
75	if err := os.WriteFile(configPath, data, 0644); err != nil {
76		return err
77	}
78	
79	logging.Info("LSP configuration saved to local config file", configPath)
80	return nil
81}
82
83// IsLSPConfigured checks if LSP is already configured
84func IsLSPConfigured() bool {
85	cfg := Get()
86	return len(cfg.LSP) > 0
87}