diff options
| author | adamdottv <[email protected]> | 2025-05-09 13:37:13 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-05-09 13:37:13 -0500 |
| commit | f1007771997bd0401516eda87a7e0ac92f269680 (patch) | |
| tree | d26198d031516eaebcc885870b470925492d8775 /internal/lsp | |
| parent | f41b7bbd0a0cc731fd7c471b7ee8b26f14a21755 (diff) | |
| download | opencode-f1007771997bd0401516eda87a7e0ac92f269680.tar.gz opencode-f1007771997bd0401516eda87a7e0ac92f269680.zip | |
wip: logging improvements
Diffstat (limited to 'internal/lsp')
| -rw-r--r-- | internal/lsp/client.go | 34 | ||||
| -rw-r--r-- | internal/lsp/discovery/integration.go | 13 | ||||
| -rw-r--r-- | internal/lsp/discovery/language.go | 9 | ||||
| -rw-r--r-- | internal/lsp/discovery/server.go | 53 | ||||
| -rw-r--r-- | internal/lsp/handlers.go | 14 | ||||
| -rw-r--r-- | internal/lsp/transport.go | 32 | ||||
| -rw-r--r-- | internal/lsp/watcher/watcher.go | 112 |
7 files changed, 135 insertions, 132 deletions
diff --git a/internal/lsp/client.go b/internal/lsp/client.go index 290a01cba..ca2016691 100644 --- a/internal/lsp/client.go +++ b/internal/lsp/client.go @@ -14,6 +14,8 @@ import ( "sync/atomic" "time" + "log/slog" + "github.com/opencode-ai/opencode/internal/config" "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp/protocol" @@ -97,10 +99,10 @@ func NewClient(ctx context.Context, command string, args ...string) (*Client, er go func() { scanner := bufio.NewScanner(stderr) for scanner.Scan() { - logging.Info("LSP Server", "message", scanner.Text()) + slog.Info("LSP Server", "message", scanner.Text()) } if err := scanner.Err(); err != nil { - logging.Error("Error reading LSP stderr", "error", err) + slog.Error("Error reading LSP stderr", "error", err) } }() @@ -301,7 +303,7 @@ func (c *Client) WaitForServerReady(ctx context.Context) error { defer ticker.Stop() if cnf.DebugLSP { - logging.Debug("Waiting for LSP server to be ready...") + slog.Debug("Waiting for LSP server to be ready...") } // Determine server type for specialized initialization @@ -310,7 +312,7 @@ func (c *Client) WaitForServerReady(ctx context.Context) error { // For TypeScript-like servers, we need to open some key files first if serverType == ServerTypeTypeScript { if cnf.DebugLSP { - logging.Debug("TypeScript-like server detected, opening key configuration files") + slog.Debug("TypeScript-like server detected, opening key configuration files") } c.openKeyConfigFiles(ctx) } @@ -327,15 +329,15 @@ func (c *Client) WaitForServerReady(ctx context.Context) error { // Server responded successfully c.SetServerState(StateReady) if cnf.DebugLSP { - logging.Debug("LSP server is ready") + slog.Debug("LSP server is ready") } return nil } else { - logging.Debug("LSP server not ready yet", "error", err, "serverType", serverType) + slog.Debug("LSP server not ready yet", "error", err, "serverType", serverType) } if cnf.DebugLSP { - logging.Debug("LSP server not ready yet", "error", err, "serverType", serverType) + slog.Debug("LSP server not ready yet", "error", err, "serverType", serverType) } } } @@ -410,9 +412,9 @@ func (c *Client) openKeyConfigFiles(ctx context.Context) { if _, err := os.Stat(file); err == nil { // File exists, try to open it if err := c.OpenFile(ctx, file); err != nil { - logging.Debug("Failed to open key config file", "file", file, "error", err) + slog.Debug("Failed to open key config file", "file", file, "error", err) } else { - logging.Debug("Opened key config file for initialization", "file", file) + slog.Debug("Opened key config file for initialization", "file", file) } } } @@ -488,7 +490,7 @@ func (c *Client) pingTypeScriptServer(ctx context.Context) error { return nil }) if err != nil { - logging.Debug("Error walking directory for TypeScript files", "error", err) + slog.Debug("Error walking directory for TypeScript files", "error", err) } // Final fallback - just try a generic capability @@ -528,7 +530,7 @@ func (c *Client) openTypeScriptFiles(ctx context.Context, workDir string) { if err := c.OpenFile(ctx, path); err == nil { filesOpened++ if cnf.DebugLSP { - logging.Debug("Opened TypeScript file for initialization", "file", path) + slog.Debug("Opened TypeScript file for initialization", "file", path) } } } @@ -537,11 +539,11 @@ func (c *Client) openTypeScriptFiles(ctx context.Context, workDir string) { }) if err != nil && cnf.DebugLSP { - logging.Debug("Error walking directory for TypeScript files", "error", err) + slog.Debug("Error walking directory for TypeScript files", "error", err) } if cnf.DebugLSP { - logging.Debug("Opened TypeScript files for initialization", "count", filesOpened) + slog.Debug("Opened TypeScript files for initialization", "count", filesOpened) } } @@ -691,7 +693,7 @@ func (c *Client) CloseFile(ctx context.Context, filepath string) error { } if cnf.DebugLSP { - logging.Debug("Closing file", "file", filepath) + slog.Debug("Closing file", "file", filepath) } if err := c.Notify(ctx, "textDocument/didClose", params); err != nil { return err @@ -730,12 +732,12 @@ func (c *Client) CloseAllFiles(ctx context.Context) { for _, filePath := range filesToClose { err := c.CloseFile(ctx, filePath) if err != nil && cnf.DebugLSP { - logging.Warn("Error closing file", "file", filePath, "error", err) + slog.Warn("Error closing file", "file", filePath, "error", err) } } if cnf.DebugLSP { - logging.Debug("Closed all files", "files", filesToClose) + slog.Debug("Closed all files", "files", filesToClose) } } diff --git a/internal/lsp/discovery/integration.go b/internal/lsp/discovery/integration.go index 7820b6449..d44389384 100644 --- a/internal/lsp/discovery/integration.go +++ b/internal/lsp/discovery/integration.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/opencode-ai/opencode/internal/config" - "github.com/opencode-ai/opencode/internal/logging" + "log/slog" ) // IntegrateLSPServers discovers languages and LSP servers and integrates them into the application configuration @@ -23,9 +23,9 @@ func IntegrateLSPServers(workingDir string) error { // Always run language detection, but log differently for first run vs. subsequent runs if shouldInit || len(cfg.LSP) == 0 { - logging.Info("Running initial LSP auto-discovery...") + slog.Info("Running initial LSP auto-discovery...") } else { - logging.Debug("Running LSP auto-discovery to detect new languages...") + slog.Debug("Running LSP auto-discovery to detect new languages...") } // Configure LSP servers @@ -38,7 +38,7 @@ func IntegrateLSPServers(workingDir string) error { for langID, serverInfo := range servers { // Skip languages that already have a configured server if _, exists := cfg.LSP[langID]; exists { - logging.Debug("LSP server already configured for language", "language", langID) + slog.Debug("LSP server already configured for language", "language", langID) continue } @@ -49,12 +49,12 @@ func IntegrateLSPServers(workingDir string) error { Command: serverInfo.Path, Args: serverInfo.Args, } - logging.Info("Added LSP server to configuration", + slog.Info("Added LSP server to configuration", "language", langID, "command", serverInfo.Command, "path", serverInfo.Path) } else { - logging.Warn("LSP server not available", + slog.Warn("LSP server not available", "language", langID, "command", serverInfo.Command, "installCmd", serverInfo.InstallCmd) @@ -63,4 +63,3 @@ func IntegrateLSPServers(workingDir string) error { return nil } - diff --git a/internal/lsp/discovery/language.go b/internal/lsp/discovery/language.go index 5e0a8d1af..69fef01d5 100644 --- a/internal/lsp/discovery/language.go +++ b/internal/lsp/discovery/language.go @@ -6,8 +6,8 @@ import ( "strings" "sync" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp" + "log/slog" ) // LanguageInfo stores information about a detected language @@ -206,9 +206,9 @@ func DetectLanguages(rootDir string) (map[string]LanguageInfo, error) { // Log detected languages for id, info := range languages { if info.IsPrimary { - logging.Debug("Detected primary language", "language", id, "files", info.FileCount, "projectFiles", len(info.ProjectFiles)) + slog.Debug("Detected primary language", "language", id, "files", info.FileCount, "projectFiles", len(info.ProjectFiles)) } else { - logging.Debug("Detected secondary language", "language", id, "files", info.FileCount) + slog.Debug("Detected secondary language", "language", id, "files", info.FileCount) } } @@ -295,4 +295,5 @@ func GetLanguageIDFromPath(path string) string { uri := "file://" + path langKind := lsp.DetectLanguageID(uri) return GetLanguageIDFromProtocol(string(langKind)) -}
\ No newline at end of file +} + diff --git a/internal/lsp/discovery/server.go b/internal/lsp/discovery/server.go index 2b7d4eeb6..98b56bc18 100644 --- a/internal/lsp/discovery/server.go +++ b/internal/lsp/discovery/server.go @@ -8,7 +8,7 @@ import ( "runtime" "strings" - "github.com/opencode-ai/opencode/internal/logging" + "log/slog" ) // ServerInfo contains information about an LSP server @@ -114,7 +114,7 @@ func FindLSPServer(languageID string) (ServerInfo, error) { if err == nil { serverInfo.Available = true serverInfo.Path = path - logging.Debug("Found LSP server in PATH", "language", languageID, "command", serverInfo.Command, "path", path) + slog.Debug("Found LSP server in PATH", "language", languageID, "command", serverInfo.Command, "path", path) return serverInfo, nil } @@ -125,13 +125,13 @@ func FindLSPServer(languageID string) (ServerInfo, error) { // Found the server serverInfo.Available = true serverInfo.Path = searchPath - logging.Debug("Found LSP server in common location", "language", languageID, "command", serverInfo.Command, "path", searchPath) + slog.Debug("Found LSP server in common location", "language", languageID, "command", serverInfo.Command, "path", searchPath) return serverInfo, nil } } // Server not found - logging.Debug("LSP server not found", "language", languageID, "command", serverInfo.Command) + slog.Debug("LSP server not found", "language", languageID, "command", serverInfo.Command) return serverInfo, fmt.Errorf("LSP server for %s not found. Install with: %s", languageID, serverInfo.InstallCmd) } @@ -140,7 +140,7 @@ func getCommonLSPPaths(languageID, command string) []string { var paths []string homeDir, err := os.UserHomeDir() if err != nil { - logging.Error("Failed to get user home directory", "error", err) + slog.Error("Failed to get user home directory", "error", err) return paths } @@ -148,21 +148,21 @@ func getCommonLSPPaths(languageID, command string) []string { switch runtime.GOOS { case "darwin": // macOS paths - paths = append(paths, + paths = append(paths, fmt.Sprintf("/usr/local/bin/%s", command), fmt.Sprintf("/opt/homebrew/bin/%s", command), fmt.Sprintf("%s/.local/bin/%s", homeDir, command), ) case "linux": // Linux paths - paths = append(paths, + paths = append(paths, fmt.Sprintf("/usr/bin/%s", command), fmt.Sprintf("/usr/local/bin/%s", command), fmt.Sprintf("%s/.local/bin/%s", homeDir, command), ) case "windows": // Windows paths - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s\\AppData\\Local\\Programs\\%s.exe", homeDir, command), fmt.Sprintf("C:\\Program Files\\%s\\bin\\%s.exe", command, command), ) @@ -182,12 +182,12 @@ func getCommonLSPPaths(languageID, command string) []string { case "typescript", "javascript", "html", "css", "json", "yaml", "php": // Node.js global packages if runtime.GOOS == "windows" { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s\\AppData\\Roaming\\npm\\%s.cmd", homeDir, command), fmt.Sprintf("%s\\AppData\\Roaming\\npm\\node_modules\\.bin\\%s.cmd", homeDir, command), ) } else { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s/.npm-global/bin/%s", homeDir, command), fmt.Sprintf("%s/.nvm/versions/node/*/bin/%s", homeDir, command), fmt.Sprintf("/usr/local/lib/node_modules/.bin/%s", command), @@ -196,12 +196,12 @@ func getCommonLSPPaths(languageID, command string) []string { case "python": // Python paths if runtime.GOOS == "windows" { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s\\AppData\\Local\\Programs\\Python\\Python*\\Scripts\\%s.exe", homeDir, command), fmt.Sprintf("C:\\Python*\\Scripts\\%s.exe", command), ) } else { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s/.local/bin/%s", homeDir, command), fmt.Sprintf("%s/.pyenv/shims/%s", homeDir, command), fmt.Sprintf("/usr/local/bin/%s", command), @@ -210,12 +210,12 @@ func getCommonLSPPaths(languageID, command string) []string { case "rust": // Rust paths if runtime.GOOS == "windows" { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s\\.rustup\\toolchains\\*\\bin\\%s.exe", homeDir, command), fmt.Sprintf("%s\\.cargo\\bin\\%s.exe", homeDir, command), ) } else { - paths = append(paths, + paths = append(paths, fmt.Sprintf("%s/.rustup/toolchains/*/bin/%s", homeDir, command), fmt.Sprintf("%s/.cargo/bin/%s", homeDir, command), ) @@ -248,7 +248,7 @@ func getCommonLSPPaths(languageID, command string) []string { // getVSCodeExtensionsPath returns the path to VSCode extensions directory func getVSCodeExtensionsPath(homeDir string) string { var basePath string - + switch runtime.GOOS { case "darwin": basePath = filepath.Join(homeDir, "Library", "Application Support", "Code", "User", "globalStorage") @@ -259,12 +259,12 @@ func getVSCodeExtensionsPath(homeDir string) string { default: return "" } - + // Check if the directory exists if _, err := os.Stat(basePath); err != nil { return "" } - + return basePath } @@ -275,32 +275,33 @@ func ConfigureLSPServers(rootDir string) (map[string]ServerInfo, error) { if err != nil { return nil, fmt.Errorf("failed to detect languages: %w", err) } - + // Find LSP servers for detected languages servers := make(map[string]ServerInfo) for langID, langInfo := range languages { // Prioritize primary languages but include all languages that have server definitions if !langInfo.IsPrimary && langInfo.FileCount < 3 { // Skip non-primary languages with very few files - logging.Debug("Skipping non-primary language with few files", "language", langID, "files", langInfo.FileCount) + slog.Debug("Skipping non-primary language with few files", "language", langID, "files", langInfo.FileCount) continue } - + // Check if we have a server for this language serverInfo, err := FindLSPServer(langID) if err != nil { - logging.Warn("LSP server not found", "language", langID, "error", err) + slog.Warn("LSP server not found", "language", langID, "error", err) continue } - + // Add to the map of configured servers servers[langID] = serverInfo if langInfo.IsPrimary { - logging.Info("Configured LSP server for primary language", "language", langID, "command", serverInfo.Command, "path", serverInfo.Path) + slog.Info("Configured LSP server for primary language", "language", langID, "command", serverInfo.Command, "path", serverInfo.Path) } else { - logging.Info("Configured LSP server for secondary language", "language", langID, "command", serverInfo.Command, "path", serverInfo.Path) + slog.Info("Configured LSP server for secondary language", "language", langID, "command", serverInfo.Command, "path", serverInfo.Path) } } - + return servers, nil -}
\ No newline at end of file +} + diff --git a/internal/lsp/handlers.go b/internal/lsp/handlers.go index e24945b42..656ec1228 100644 --- a/internal/lsp/handlers.go +++ b/internal/lsp/handlers.go @@ -4,9 +4,9 @@ import ( "encoding/json" "github.com/opencode-ai/opencode/internal/config" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp/protocol" "github.com/opencode-ai/opencode/internal/lsp/util" + "log/slog" ) // Requests @@ -18,7 +18,7 @@ func HandleWorkspaceConfiguration(params json.RawMessage) (any, error) { func HandleRegisterCapability(params json.RawMessage) (any, error) { var registerParams protocol.RegistrationParams if err := json.Unmarshal(params, ®isterParams); err != nil { - logging.Error("Error unmarshaling registration params", "error", err) + slog.Error("Error unmarshaling registration params", "error", err) return nil, err } @@ -28,13 +28,13 @@ func HandleRegisterCapability(params json.RawMessage) (any, error) { // Parse the registration options optionsJSON, err := json.Marshal(reg.RegisterOptions) if err != nil { - logging.Error("Error marshaling registration options", "error", err) + slog.Error("Error marshaling registration options", "error", err) continue } var options protocol.DidChangeWatchedFilesRegistrationOptions if err := json.Unmarshal(optionsJSON, &options); err != nil { - logging.Error("Error unmarshaling registration options", "error", err) + slog.Error("Error unmarshaling registration options", "error", err) continue } @@ -54,7 +54,7 @@ func HandleApplyEdit(params json.RawMessage) (any, error) { err := util.ApplyWorkspaceEdit(edit.Edit) if err != nil { - logging.Error("Error applying workspace edit", "error", err) + slog.Error("Error applying workspace edit", "error", err) return protocol.ApplyWorkspaceEditResult{Applied: false, FailureReason: err.Error()}, nil } @@ -89,7 +89,7 @@ func HandleServerMessage(params json.RawMessage) { } if err := json.Unmarshal(params, &msg); err == nil { if cnf.DebugLSP { - logging.Debug("Server message", "type", msg.Type, "message", msg.Message) + slog.Debug("Server message", "type", msg.Type, "message", msg.Message) } } } @@ -97,7 +97,7 @@ func HandleServerMessage(params json.RawMessage) { func HandleDiagnostics(client *Client, params json.RawMessage) { var diagParams protocol.PublishDiagnosticsParams if err := json.Unmarshal(params, &diagParams); err != nil { - logging.Error("Error unmarshaling diagnostics params", "error", err) + slog.Error("Error unmarshaling diagnostics params", "error", err) return } diff --git a/internal/lsp/transport.go b/internal/lsp/transport.go index 9b07d53c9..577ba2ed0 100644 --- a/internal/lsp/transport.go +++ b/internal/lsp/transport.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/opencode-ai/opencode/internal/config" - "github.com/opencode-ai/opencode/internal/logging" + "log/slog" ) // Write writes an LSP message to the given writer @@ -21,7 +21,7 @@ func WriteMessage(w io.Writer, msg *Message) error { cnf := config.Get() if cnf.DebugLSP { - logging.Debug("Sending message to server", "method", msg.Method, "id", msg.ID) + slog.Debug("Sending message to server", "method", msg.Method, "id", msg.ID) } _, err = fmt.Fprintf(w, "Content-Length: %d\r\n\r\n", len(data)) @@ -50,7 +50,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) { line = strings.TrimSpace(line) if cnf.DebugLSP { - logging.Debug("Received header", "line", line) + slog.Debug("Received header", "line", line) } if line == "" { @@ -66,7 +66,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) { } if cnf.DebugLSP { - logging.Debug("Content-Length", "length", contentLength) + slog.Debug("Content-Length", "length", contentLength) } // Read content @@ -77,7 +77,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) { } if cnf.DebugLSP { - logging.Debug("Received content", "content", string(content)) + slog.Debug("Received content", "content", string(content)) } // Parse message @@ -96,7 +96,7 @@ func (c *Client) handleMessages() { msg, err := ReadMessage(c.stdout) if err != nil { if cnf.DebugLSP { - logging.Error("Error reading message", "error", err) + slog.Error("Error reading message", "error", err) } return } @@ -104,7 +104,7 @@ func (c *Client) handleMessages() { // Handle server->client request (has both Method and ID) if msg.Method != "" && msg.ID != 0 { if cnf.DebugLSP { - logging.Debug("Received request from server", "method", msg.Method, "id", msg.ID) + slog.Debug("Received request from server", "method", msg.Method, "id", msg.ID) } response := &Message{ @@ -144,7 +144,7 @@ func (c *Client) handleMessages() { // Send response back to server if err := WriteMessage(c.stdin, response); err != nil { - logging.Error("Error sending response to server", "error", err) + slog.Error("Error sending response to server", "error", err) } continue @@ -158,11 +158,11 @@ func (c *Client) handleMessages() { if ok { if cnf.DebugLSP { - logging.Debug("Handling notification", "method", msg.Method) + slog.Debug("Handling notification", "method", msg.Method) } go handler(msg.Params) } else if cnf.DebugLSP { - logging.Debug("No handler for notification", "method", msg.Method) + slog.Debug("No handler for notification", "method", msg.Method) } continue } @@ -175,12 +175,12 @@ func (c *Client) handleMessages() { if ok { if cnf.DebugLSP { - logging.Debug("Received response for request", "id", msg.ID) + slog.Debug("Received response for request", "id", msg.ID) } ch <- msg close(ch) } else if cnf.DebugLSP { - logging.Debug("No handler for response", "id", msg.ID) + slog.Debug("No handler for response", "id", msg.ID) } } } @@ -192,7 +192,7 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any id := c.nextID.Add(1) if cnf.DebugLSP { - logging.Debug("Making call", "method", method, "id", id) + slog.Debug("Making call", "method", method, "id", id) } msg, err := NewRequest(id, method, params) @@ -218,14 +218,14 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any } if cnf.DebugLSP { - logging.Debug("Request sent", "method", method, "id", id) + slog.Debug("Request sent", "method", method, "id", id) } // Wait for response resp := <-ch if cnf.DebugLSP { - logging.Debug("Received response", "id", id) + slog.Debug("Received response", "id", id) } if resp.Error != nil { @@ -251,7 +251,7 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any func (c *Client) Notify(ctx context.Context, method string, params any) error { cnf := config.Get() if cnf.DebugLSP { - logging.Debug("Sending notification", "method", method) + slog.Debug("Sending notification", "method", method) } msg, err := NewNotification(method, params) diff --git a/internal/lsp/watcher/watcher.go b/internal/lsp/watcher/watcher.go index 58ad25695..ed8fe6b76 100644 --- a/internal/lsp/watcher/watcher.go +++ b/internal/lsp/watcher/watcher.go @@ -13,9 +13,9 @@ import ( "github.com/bmatcuk/doublestar/v4" "github.com/fsnotify/fsnotify" "github.com/opencode-ai/opencode/internal/config" - "github.com/opencode-ai/opencode/internal/logging" "github.com/opencode-ai/opencode/internal/lsp" "github.com/opencode-ai/opencode/internal/lsp/protocol" + "log/slog" ) // WorkspaceWatcher manages LSP file watching @@ -46,7 +46,7 @@ func NewWorkspaceWatcher(client *lsp.Client) *WorkspaceWatcher { func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watchers []protocol.FileSystemWatcher) { cnf := config.Get() - logging.Debug("Adding file watcher registrations") + slog.Debug("Adding file watcher registrations") w.registrationMu.Lock() defer w.registrationMu.Unlock() @@ -55,33 +55,33 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc // Print detailed registration information for debugging if cnf.DebugLSP { - logging.Debug("Adding file watcher registrations", + slog.Debug("Adding file watcher registrations", "id", id, "watchers", len(watchers), "total", len(w.registrations), ) for i, watcher := range watchers { - logging.Debug("Registration", "index", i+1) + slog.Debug("Registration", "index", i+1) // Log the GlobPattern switch v := watcher.GlobPattern.Value.(type) { case string: - logging.Debug("GlobPattern", "pattern", v) + slog.Debug("GlobPattern", "pattern", v) case protocol.RelativePattern: - logging.Debug("GlobPattern", "pattern", v.Pattern) + slog.Debug("GlobPattern", "pattern", v.Pattern) // Log BaseURI details switch u := v.BaseURI.Value.(type) { case string: - logging.Debug("BaseURI", "baseURI", u) + slog.Debug("BaseURI", "baseURI", u) case protocol.DocumentUri: - logging.Debug("BaseURI", "baseURI", u) + slog.Debug("BaseURI", "baseURI", u) default: - logging.Debug("BaseURI", "baseURI", u) + slog.Debug("BaseURI", "baseURI", u) } default: - logging.Debug("GlobPattern", "unknown type", fmt.Sprintf("%T", v)) + slog.Debug("GlobPattern", "unknown type", fmt.Sprintf("%T", v)) } // Log WatchKind @@ -90,13 +90,13 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc watchKind = *watcher.Kind } - logging.Debug("WatchKind", "kind", watchKind) + slog.Debug("WatchKind", "kind", watchKind) } } // Determine server type for specialized handling serverName := getServerNameFromContext(ctx) - logging.Debug("Server type detected", "serverName", serverName) + slog.Debug("Server type detected", "serverName", serverName) // Check if this server has sent file watchers hasFileWatchers := len(watchers) > 0 @@ -124,7 +124,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc filesOpened += highPriorityFilesOpened if cnf.DebugLSP { - logging.Debug("Opened high-priority files", + slog.Debug("Opened high-priority files", "count", highPriorityFilesOpened, "serverName", serverName) } @@ -132,7 +132,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc // If we've already opened enough high-priority files, we might not need more if filesOpened >= maxFilesToOpen { if cnf.DebugLSP { - logging.Debug("Reached file limit with high-priority files", + slog.Debug("Reached file limit with high-priority files", "filesOpened", filesOpened, "maxFiles", maxFilesToOpen) } @@ -150,7 +150,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc if d.IsDir() { if path != w.workspacePath && shouldExcludeDir(path) { if cnf.DebugLSP { - logging.Debug("Skipping excluded directory", "path", path) + slog.Debug("Skipping excluded directory", "path", path) } return filepath.SkipDir } @@ -178,7 +178,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc elapsedTime := time.Since(startTime) if cnf.DebugLSP { - logging.Debug("Limited workspace scan complete", + slog.Debug("Limited workspace scan complete", "filesOpened", filesOpened, "maxFiles", maxFilesToOpen, "elapsedTime", elapsedTime.Seconds(), @@ -187,11 +187,11 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc } if err != nil && cnf.DebugLSP { - logging.Debug("Error scanning workspace for files to open", "error", err) + slog.Debug("Error scanning workspace for files to open", "error", err) } }() } else if cnf.DebugLSP { - logging.Debug("Using on-demand file loading for server", "server", serverName) + slog.Debug("Using on-demand file loading for server", "server", serverName) } } @@ -264,7 +264,7 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName matches, err := doublestar.Glob(os.DirFS(w.workspacePath), pattern) if err != nil { if cnf.DebugLSP { - logging.Debug("Error finding high-priority files", "pattern", pattern, "error", err) + slog.Debug("Error finding high-priority files", "pattern", pattern, "error", err) } continue } @@ -282,12 +282,12 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName // Open the file if err := w.client.OpenFile(ctx, fullPath); err != nil { if cnf.DebugLSP { - logging.Debug("Error opening high-priority file", "path", fullPath, "error", err) + slog.Debug("Error opening high-priority file", "path", fullPath, "error", err) } } else { filesOpened++ if cnf.DebugLSP { - logging.Debug("Opened high-priority file", "path", fullPath) + slog.Debug("Opened high-priority file", "path", fullPath) } } @@ -319,7 +319,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str } serverName := getServerNameFromContext(ctx) - logging.Debug("Starting workspace watcher", "workspacePath", workspacePath, "serverName", serverName) + slog.Debug("Starting workspace watcher", "workspacePath", workspacePath, "serverName", serverName) // Register handler for file watcher registrations from the server lsp.RegisterFileWatchHandler(func(id string, watchers []protocol.FileSystemWatcher) { @@ -328,7 +328,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str watcher, err := fsnotify.NewWatcher() if err != nil { - logging.Error("Error creating watcher", "error", err) + slog.Error("Error creating watcher", "error", err) } defer watcher.Close() @@ -342,7 +342,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str if d.IsDir() && path != workspacePath { if shouldExcludeDir(path) { if cnf.DebugLSP { - logging.Debug("Skipping excluded directory", "path", path) + slog.Debug("Skipping excluded directory", "path", path) } return filepath.SkipDir } @@ -352,14 +352,14 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str if d.IsDir() { err = watcher.Add(path) if err != nil { - logging.Error("Error watching path", "path", path, "error", err) + slog.Error("Error watching path", "path", path, "error", err) } } return nil }) if err != nil { - logging.Error("Error walking workspace", "error", err) + slog.Error("Error walking workspace", "error", err) } // Event loop @@ -381,18 +381,18 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str if err != nil { if os.IsNotExist(err) { // File was deleted between event and processing - ignore - logging.Debug("File deleted between create event and stat", "path", event.Name) + slog.Debug("File deleted between create event and stat", "path", event.Name) continue } - logging.Error("Error getting file info", "path", event.Name, "error", err) + slog.Error("Error getting file info", "path", event.Name, "error", err) continue } - + if info.IsDir() { // Skip excluded directories if !shouldExcludeDir(event.Name) { if err := watcher.Add(event.Name); err != nil { - logging.Error("Error adding directory to watcher", "path", event.Name, "error", err) + slog.Error("Error adding directory to watcher", "path", event.Name, "error", err) } } } else { @@ -406,7 +406,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str // Debug logging if cnf.DebugLSP { matched, kind := w.isPathWatched(event.Name) - logging.Debug("File event", + slog.Debug("File event", "path", event.Name, "operation", event.Op.String(), "watched", matched, @@ -427,7 +427,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str // Just send the notification if needed info, err := os.Stat(event.Name) if err != nil { - logging.Error("Error getting file info", "path", event.Name, "error", err) + slog.Error("Error getting file info", "path", event.Name, "error", err) return } if !info.IsDir() && watchKind&protocol.WatchCreate != 0 { @@ -455,7 +455,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str if !ok { return } - logging.Error("Error watching file", "error", err) + slog.Error("Error watching file", "error", err) } } } @@ -580,7 +580,7 @@ func matchesSimpleGlob(pattern, path string) bool { // Fall back to simple matching for simpler patterns matched, err := filepath.Match(pattern, path) if err != nil { - logging.Error("Error matching pattern", "pattern", pattern, "path", path, "error", err) + slog.Error("Error matching pattern", "pattern", pattern, "path", path, "error", err) return false } @@ -591,7 +591,7 @@ func matchesSimpleGlob(pattern, path string) bool { func (w *WorkspaceWatcher) matchesPattern(path string, pattern protocol.GlobPattern) bool { patternInfo, err := pattern.AsPattern() if err != nil { - logging.Error("Error parsing pattern", "pattern", pattern, "error", err) + slog.Error("Error parsing pattern", "pattern", pattern, "error", err) return false } @@ -616,7 +616,7 @@ func (w *WorkspaceWatcher) matchesPattern(path string, pattern protocol.GlobPatt // Make path relative to basePath for matching relPath, err := filepath.Rel(basePath, path) if err != nil { - logging.Error("Error getting relative path", "path", path, "basePath", basePath, "error", err) + slog.Error("Error getting relative path", "path", path, "basePath", basePath, "error", err) return false } relPath = filepath.ToSlash(relPath) @@ -654,15 +654,15 @@ func (w *WorkspaceWatcher) debounceHandleFileEvent(ctx context.Context, uri stri func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, changeType protocol.FileChangeType) { // If the file is open and it's a change event, use didChange notification filePath := uri[7:] // Remove "file://" prefix - + if changeType == protocol.FileChangeType(protocol.Deleted) { // Always clear diagnostics for deleted files w.client.ClearDiagnosticsForURI(protocol.DocumentUri(uri)) - + // If the file was open, close it in the LSP client if w.client.IsFileOpen(filePath) { if err := w.client.CloseFile(ctx, filePath); err != nil { - logging.Debug("Error closing deleted file in LSP client", "file", filePath, "error", err) + slog.Debug("Error closing deleted file in LSP client", "file", filePath, "error", err) // Continue anyway - the file is gone } } @@ -671,19 +671,19 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan if _, err := os.Stat(filePath); err != nil { if os.IsNotExist(err) { // File was deleted between the event and now - treat as delete - logging.Debug("File deleted between change event and processing", "file", filePath) + slog.Debug("File deleted between change event and processing", "file", filePath) w.handleFileEvent(ctx, uri, protocol.FileChangeType(protocol.Deleted)) return } - logging.Error("Error getting file info", "path", filePath, "error", err) + slog.Error("Error getting file info", "path", filePath, "error", err) return } - + // File exists and is open, notify change if w.client.IsFileOpen(filePath) { err := w.client.NotifyChange(ctx, filePath) if err != nil { - logging.Error("Error notifying change", "error", err) + slog.Error("Error notifying change", "error", err) } return } @@ -692,17 +692,17 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan if _, err := os.Stat(filePath); err != nil { if os.IsNotExist(err) { // File was deleted between the event and now - ignore - logging.Debug("File deleted between create event and processing", "file", filePath) + slog.Debug("File deleted between create event and processing", "file", filePath) return } - logging.Error("Error getting file info", "path", filePath, "error", err) + slog.Error("Error getting file info", "path", filePath, "error", err) return } } // Notify LSP server about the file event using didChangeWatchedFiles if err := w.notifyFileEvent(ctx, uri, changeType); err != nil { - logging.Error("Error notifying LSP server about file event", "error", err) + slog.Error("Error notifying LSP server about file event", "error", err) } } @@ -710,7 +710,7 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan func (w *WorkspaceWatcher) notifyFileEvent(ctx context.Context, uri string, changeType protocol.FileChangeType) error { cnf := config.Get() if cnf.DebugLSP { - logging.Debug("Notifying file event", + slog.Debug("Notifying file event", "uri", uri, "changeType", changeType, ) @@ -874,7 +874,7 @@ func shouldExcludeFile(filePath string) bool { if strings.HasSuffix(filePath, "~") { return true } - + // Skip numeric temporary files (often created by editors) if _, err := strconv.Atoi(fileName); err == nil { return true @@ -890,7 +890,7 @@ func shouldExcludeFile(filePath string) bool { // Skip large files if info.Size() > maxFileSize { if cnf.DebugLSP { - logging.Debug("Skipping large file", + slog.Debug("Skipping large file", "path", filePath, "size", info.Size(), "maxSize", maxFileSize, @@ -913,13 +913,13 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) { if err != nil { if os.IsNotExist(err) { // File was deleted between event and processing - ignore - logging.Debug("File deleted between event and openMatchingFile", "path", path) + slog.Debug("File deleted between event and openMatchingFile", "path", path) return } - logging.Error("Error getting file info", "path", path, "error", err) + slog.Error("Error getting file info", "path", path, "error", err) return } - + if info.IsDir() { return } @@ -938,10 +938,10 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) { // This helps with project initialization for certain language servers if isHighPriorityFile(path, serverName) { if cnf.DebugLSP { - logging.Debug("Opening high-priority file", "path", path, "serverName", serverName) + slog.Debug("Opening high-priority file", "path", path, "serverName", serverName) } if err := w.client.OpenFile(ctx, path); err != nil && cnf.DebugLSP { - logging.Error("Error opening high-priority file", "path", path, "error", err) + slog.Error("Error opening high-priority file", "path", path, "error", err) } return } @@ -953,7 +953,7 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) { // Check file size - for preloading we're more conservative if info.Size() > (1 * 1024 * 1024) { // 1MB limit for preloaded files if cnf.DebugLSP { - logging.Debug("Skipping large file for preloading", "path", path, "size", info.Size()) + slog.Debug("Skipping large file for preloading", "path", path, "size", info.Size()) } return } @@ -985,7 +985,7 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) { if shouldOpen { // Don't need to check if it's already open - the client.OpenFile handles that if err := w.client.OpenFile(ctx, path); err != nil && cnf.DebugLSP { - logging.Error("Error opening file", "path", path, "error", err) + slog.Error("Error opening file", "path", path, "error", err) } } } |
