|
|
@@ -11,7 +11,7 @@ import (
|
|
|
|
|
|
"github.com/bmatcuk/doublestar/v4"
|
|
|
"github.com/charmbracelet/crush/internal/config"
|
|
|
- "github.com/charmbracelet/crush/internal/logging"
|
|
|
+ "log/slog"
|
|
|
"github.com/charmbracelet/crush/internal/lsp"
|
|
|
"github.com/charmbracelet/crush/internal/lsp/protocol"
|
|
|
"github.com/fsnotify/fsnotify"
|
|
|
@@ -45,7 +45,7 @@ func NewWorkspaceWatcher(client *lsp.Client) *WorkspaceWatcher {
|
|
|
func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watchers []protocol.FileSystemWatcher) {
|
|
|
cfg := config.Get()
|
|
|
|
|
|
- logging.Debug("Adding file watcher registrations")
|
|
|
+ slog.Debug("Adding file watcher registrations")
|
|
|
w.registrationMu.Lock()
|
|
|
defer w.registrationMu.Unlock()
|
|
|
|
|
|
@@ -54,33 +54,33 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
|
|
|
|
|
|
// Print detailed registration information for debugging
|
|
|
if cfg.Options.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
|
|
|
@@ -89,13 +89,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
|
|
|
@@ -123,7 +123,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
|
|
|
filesOpened += highPriorityFilesOpened
|
|
|
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Opened high-priority files",
|
|
|
+ slog.Debug("Opened high-priority files",
|
|
|
"count", highPriorityFilesOpened,
|
|
|
"serverName", serverName)
|
|
|
}
|
|
|
@@ -131,7 +131,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 cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Reached file limit with high-priority files",
|
|
|
+ slog.Debug("Reached file limit with high-priority files",
|
|
|
"filesOpened", filesOpened,
|
|
|
"maxFiles", maxFilesToOpen)
|
|
|
}
|
|
|
@@ -149,7 +149,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
|
|
|
if d.IsDir() {
|
|
|
if path != w.workspacePath && shouldExcludeDir(path) {
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Skipping excluded directory", "path", path)
|
|
|
+ slog.Debug("Skipping excluded directory", "path", path)
|
|
|
}
|
|
|
return filepath.SkipDir
|
|
|
}
|
|
|
@@ -177,7 +177,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
|
|
|
|
|
|
elapsedTime := time.Since(startTime)
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Limited workspace scan complete",
|
|
|
+ slog.Debug("Limited workspace scan complete",
|
|
|
"filesOpened", filesOpened,
|
|
|
"maxFiles", maxFilesToOpen,
|
|
|
"elapsedTime", elapsedTime.Seconds(),
|
|
|
@@ -186,11 +186,11 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
|
|
|
}
|
|
|
|
|
|
if err != nil && cfg.Options.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 cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Using on-demand file loading for server", "server", serverName)
|
|
|
+ slog.Debug("Using on-demand file loading for server", "server", serverName)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -266,7 +266,7 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
|
|
|
matches, err := doublestar.Glob(os.DirFS(w.workspacePath), pattern)
|
|
|
if err != nil {
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Error finding high-priority files", "pattern", pattern, "error", err)
|
|
|
+ slog.Debug("Error finding high-priority files", "pattern", pattern, "error", err)
|
|
|
}
|
|
|
continue
|
|
|
}
|
|
|
@@ -300,12 +300,12 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
|
|
|
fullPath := filesToOpen[j]
|
|
|
if err := w.client.OpenFile(ctx, fullPath); err != nil {
|
|
|
if cfg.Options.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 cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Opened high-priority file", "path", fullPath)
|
|
|
+ slog.Debug("Opened high-priority file", "path", fullPath)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -334,7 +334,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) {
|
|
|
@@ -343,7 +343,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()
|
|
|
|
|
|
@@ -357,7 +357,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
|
|
|
if d.IsDir() && path != workspacePath {
|
|
|
if shouldExcludeDir(path) {
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Skipping excluded directory", "path", path)
|
|
|
+ slog.Debug("Skipping excluded directory", "path", path)
|
|
|
}
|
|
|
return filepath.SkipDir
|
|
|
}
|
|
|
@@ -367,14 +367,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
|
|
|
@@ -396,7 +396,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
|
|
|
// 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 {
|
|
|
@@ -411,7 +411,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
|
|
|
// Debug logging
|
|
|
if cfg.Options.DebugLSP {
|
|
|
matched, kind := w.isPathWatched(event.Name)
|
|
|
- logging.Debug("File event",
|
|
|
+ slog.Debug("File event",
|
|
|
"path", event.Name,
|
|
|
"operation", event.Op.String(),
|
|
|
"watched", matched,
|
|
|
@@ -431,7 +431,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 {
|
|
|
@@ -459,7 +459,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)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -584,7 +584,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
|
|
|
}
|
|
|
|
|
|
@@ -595,7 +595,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
|
|
|
}
|
|
|
|
|
|
@@ -620,7 +620,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)
|
|
|
@@ -663,14 +663,14 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan
|
|
|
} else if changeType == protocol.FileChangeType(protocol.Changed) && 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
|
|
|
}
|
|
|
|
|
|
// 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)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -678,7 +678,7 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan
|
|
|
func (w *WorkspaceWatcher) notifyFileEvent(ctx context.Context, uri string, changeType protocol.FileChangeType) error {
|
|
|
cfg := config.Get()
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Notifying file event",
|
|
|
+ slog.Debug("Notifying file event",
|
|
|
"uri", uri,
|
|
|
"changeType", changeType,
|
|
|
)
|
|
|
@@ -853,7 +853,7 @@ func shouldExcludeFile(filePath string) bool {
|
|
|
// Skip large files
|
|
|
if info.Size() > maxFileSize {
|
|
|
if cfg.Options.DebugLSP {
|
|
|
- logging.Debug("Skipping large file",
|
|
|
+ slog.Debug("Skipping large file",
|
|
|
"path", filePath,
|
|
|
"size", info.Size(),
|
|
|
"maxSize", maxFileSize,
|
|
|
@@ -891,10 +891,10 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
|
|
|
// This helps with project initialization for certain language servers
|
|
|
if isHighPriorityFile(path, serverName) {
|
|
|
if cfg.Options.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 && cfg.Options.DebugLSP {
|
|
|
- logging.Error("Error opening high-priority file", "path", path, "error", err)
|
|
|
+ slog.Error("Error opening high-priority file", "path", path, "error", err)
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
@@ -906,7 +906,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 cfg.Options.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
|
|
|
}
|
|
|
@@ -938,7 +938,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 && cfg.Options.DebugLSP {
|
|
|
- logging.Error("Error opening file", "path", path, "error", err)
|
|
|
+ slog.Error("Error opening file", "path", path, "error", err)
|
|
|
}
|
|
|
}
|
|
|
}
|