Detailed changes
  
  
    
    @@ -23,7 +23,7 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
 	slog.Info("Creating LSP client", "name", name, "command", command, "args", args)
 
 	// Create LSP client.
-	lspClient, err := lsp.NewClient(ctx, command, args...)
+	lspClient, err := lsp.NewClient(ctx, app.config.WorkingDir(), command, args...)
 	if err != nil {
 		slog.Error("Failed to create LSP client for", name, err)
 		return
@@ -60,7 +60,7 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
 	watchCtx, cancelFunc := context.WithCancel(ctx)
 
 	// Create the workspace watcher.
-	workspaceWatcher := watcher.NewWorkspaceWatcher(name, lspClient)
+	workspaceWatcher := watcher.NewWorkspaceWatcher(name, lspClient, app.config.Options.DebugLSP)
 
 	// Store the cancel function to be called during cleanup.
 	app.watcherCancelFuncs.Append(cancelFunc)
  
  
  
    
    @@ -113,7 +113,7 @@ func waitForLspDiagnostics(ctx context.Context, filePath string, lsps map[string
 		maps.Copy(originalDiags, client.GetDiagnostics())
 
 		handler := func(params json.RawMessage) {
-			lsp.HandleDiagnostics(client, params)
+			client.HandleDiagnostics(params)
 			var diagParams protocol.PublishDiagnosticsParams
 			if err := json.Unmarshal(params, &diagParams); err != nil {
 				return
  
  
  
    
    @@ -3,7 +3,6 @@ package lsp
 import (
 	"bufio"
 	"context"
-	"encoding/json"
 	"fmt"
 	"io"
 	"log/slog"
@@ -15,16 +14,17 @@ import (
 	"sync/atomic"
 	"time"
 
-	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/log"
 	"github.com/charmbracelet/crush/internal/lsp/protocol"
 )
 
 type Client struct {
-	Cmd    *exec.Cmd
-	stdin  io.WriteCloser
-	stdout *bufio.Reader
-	stderr io.ReadCloser
+	Cmd     *exec.Cmd
+	stdin   io.WriteCloser
+	stdout  *bufio.Reader
+	stderr  io.ReadCloser
+	workDir string
+	debug   bool
 
 	// Request ID counter
 	nextID atomic.Int32
@@ -53,7 +53,7 @@ type Client struct {
 	serverState atomic.Value
 }
 
-func NewClient(ctx context.Context, command string, args ...string) (*Client, error) {
+func NewClient(ctx context.Context, workDir string, command string, args ...string) (*Client, error) {
 	cmd := exec.CommandContext(ctx, command, args...)
 	// Copy env
 	cmd.Env = os.Environ()
@@ -78,6 +78,7 @@ func NewClient(ctx context.Context, command string, args ...string) (*Client, er
 		stdin:                 stdin,
 		stdout:                bufio.NewReader(stdout),
 		stderr:                stderr,
+		workDir:               workDir,
 		handlers:              make(map[int32]chan *Message),
 		notificationHandlers:  make(map[string]NotificationHandler),
 		serverRequestHandlers: make(map[string]ServerRequestHandler),
@@ -215,12 +216,11 @@ func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir string) (
 	}
 
 	// Register handlers
-	c.RegisterServerRequestHandler("workspace/applyEdit", HandleApplyEdit)
-	c.RegisterServerRequestHandler("workspace/configuration", HandleWorkspaceConfiguration)
-	c.RegisterServerRequestHandler("client/registerCapability", HandleRegisterCapability)
-	c.RegisterNotificationHandler("window/showMessage", HandleServerMessage)
-	c.RegisterNotificationHandler("textDocument/publishDiagnostics",
-		func(params json.RawMessage) { HandleDiagnostics(c, params) })
+	c.RegisterServerRequestHandler("workspace/applyEdit", c.HandleApplyEdit)
+	c.RegisterServerRequestHandler("workspace/configuration", c.HandleWorkspaceConfiguration)
+	c.RegisterServerRequestHandler("client/registerCapability", c.HandleRegisterCapability)
+	c.RegisterNotificationHandler("window/showMessage", c.HandleServerMessage)
+	c.RegisterNotificationHandler("textDocument/publishDiagnostics", c.HandleDiagnostics)
 
 	// Notify the LSP server
 	err := c.Initialized(ctx, protocol.InitializedParams{})
@@ -287,8 +287,6 @@ func (c *Client) SetServerState(state ServerState) {
 // WaitForServerReady waits for the server to be ready by polling the server
 // with a simple request until it responds successfully or times out
 func (c *Client) WaitForServerReady(ctx context.Context) error {
-	cfg := config.Get()
-
 	// Set initial state
 	c.SetServerState(StateStarting)
 
@@ -300,7 +298,7 @@ func (c *Client) WaitForServerReady(ctx context.Context) error {
 	ticker := time.NewTicker(500 * time.Millisecond)
 	defer ticker.Stop()
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Waiting for LSP server to be ready...")
 	}
 
@@ -309,7 +307,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 cfg.Options.DebugLSP {
+		if c.debug {
 			slog.Debug("TypeScript-like server detected, opening key configuration files")
 		}
 		c.openKeyConfigFiles(ctx)
@@ -326,7 +324,7 @@ func (c *Client) WaitForServerReady(ctx context.Context) error {
 			if err == nil {
 				// Server responded successfully
 				c.SetServerState(StateReady)
-				if cfg.Options.DebugLSP {
+				if c.debug {
 					slog.Debug("LSP server is ready")
 				}
 				return nil
@@ -334,7 +332,7 @@ func (c *Client) WaitForServerReady(ctx context.Context) error {
 				slog.Debug("LSP server not ready yet", "error", err, "serverType", serverType)
 			}
 
-			if cfg.Options.DebugLSP {
+			if c.debug {
 				slog.Debug("LSP server not ready yet", "error", err, "serverType", serverType)
 			}
 		}
@@ -377,7 +375,6 @@ func (c *Client) detectServerType() ServerType {
 
 // openKeyConfigFiles opens important configuration files that help initialize the server
 func (c *Client) openKeyConfigFiles(ctx context.Context) {
-	workDir := config.Get().WorkingDir()
 	serverType := c.detectServerType()
 
 	var filesToOpen []string
@@ -386,22 +383,22 @@ func (c *Client) openKeyConfigFiles(ctx context.Context) {
 	case ServerTypeTypeScript:
 		// TypeScript servers need these config files to properly initialize
 		filesToOpen = []string{
-			filepath.Join(workDir, "tsconfig.json"),
-			filepath.Join(workDir, "package.json"),
-			filepath.Join(workDir, "jsconfig.json"),
+			filepath.Join(c.workDir, "tsconfig.json"),
+			filepath.Join(c.workDir, "package.json"),
+			filepath.Join(c.workDir, "jsconfig.json"),
 		}
 
 		// Also find and open a few TypeScript files to help the server initialize
-		c.openTypeScriptFiles(ctx, workDir)
+		c.openTypeScriptFiles(ctx, c.workDir)
 	case ServerTypeGo:
 		filesToOpen = []string{
-			filepath.Join(workDir, "go.mod"),
-			filepath.Join(workDir, "go.sum"),
+			filepath.Join(c.workDir, "go.mod"),
+			filepath.Join(c.workDir, "go.sum"),
 		}
 	case ServerTypeRust:
 		filesToOpen = []string{
-			filepath.Join(workDir, "Cargo.toml"),
-			filepath.Join(workDir, "Cargo.lock"),
+			filepath.Join(c.workDir, "Cargo.toml"),
+			filepath.Join(c.workDir, "Cargo.lock"),
 		}
 	}
 
@@ -470,8 +467,7 @@ func (c *Client) pingTypeScriptServer(ctx context.Context) error {
 	}
 
 	// If we have no open TypeScript files, try to find and open one
-	workDir := config.Get().WorkingDir()
-	err := filepath.WalkDir(workDir, func(path string, d os.DirEntry, err error) error {
+	err := filepath.WalkDir(c.workDir, func(path string, d os.DirEntry, err error) error {
 		if err != nil {
 			return err
 		}
@@ -502,7 +498,6 @@ func (c *Client) pingTypeScriptServer(ctx context.Context) error {
 
 // openTypeScriptFiles finds and opens TypeScript files to help initialize the server
 func (c *Client) openTypeScriptFiles(ctx context.Context, workDir string) {
-	cfg := config.Get()
 	filesOpened := 0
 	maxFilesToOpen := 5 // Limit to a reasonable number of files
 
@@ -532,7 +527,7 @@ func (c *Client) openTypeScriptFiles(ctx context.Context, workDir string) {
 			// Try to open the file
 			if err := c.OpenFile(ctx, path); err == nil {
 				filesOpened++
-				if cfg.Options.DebugLSP {
+				if c.debug {
 					slog.Debug("Opened TypeScript file for initialization", "file", path)
 				}
 			}
@@ -541,11 +536,11 @@ func (c *Client) openTypeScriptFiles(ctx context.Context, workDir string) {
 		return nil
 	})
 
-	if err != nil && cfg.Options.DebugLSP {
+	if err != nil && c.debug {
 		slog.Debug("Error walking directory for TypeScript files", "error", err)
 	}
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Opened TypeScript files for initialization", "count", filesOpened)
 	}
 }
@@ -670,7 +665,6 @@ func (c *Client) NotifyChange(ctx context.Context, filepath string) error {
 }
 
 func (c *Client) CloseFile(ctx context.Context, filepath string) error {
-	cfg := config.Get()
 	uri := string(protocol.URIFromPath(filepath))
 
 	c.openFilesMu.Lock()
@@ -686,7 +680,7 @@ func (c *Client) CloseFile(ctx context.Context, filepath string) error {
 		},
 	}
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Closing file", "file", filepath)
 	}
 	if err := c.Notify(ctx, "textDocument/didClose", params); err != nil {
@@ -710,7 +704,6 @@ func (c *Client) IsFileOpen(filepath string) bool {
 
 // CloseAllFiles closes all currently open files
 func (c *Client) CloseAllFiles(ctx context.Context) {
-	cfg := config.Get()
 	c.openFilesMu.Lock()
 	filesToClose := make([]string, 0, len(c.openFiles))
 
@@ -729,12 +722,12 @@ func (c *Client) CloseAllFiles(ctx context.Context) {
 	// Then close them all
 	for _, filePath := range filesToClose {
 		err := c.CloseFile(ctx, filePath)
-		if err != nil && cfg.Options.DebugLSP {
+		if err != nil && c.debug {
 			slog.Warn("Error closing file", "file", filePath, "error", err)
 		}
 	}
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Closed all files", "files", filesToClose)
 	}
 }
@@ -792,3 +785,7 @@ func (c *Client) ClearDiagnosticsForURI(uri protocol.DocumentURI) {
 	defer c.diagnosticsMu.Unlock()
 	delete(c.diagnostics, uri)
 }
+
+func (c *Client) DebugMode() {
+	c.debug = true
+}
  
  
  
    
    @@ -4,19 +4,17 @@ import (
 	"encoding/json"
 	"log/slog"
 
-	"github.com/charmbracelet/crush/internal/config"
-
 	"github.com/charmbracelet/crush/internal/lsp/protocol"
 	"github.com/charmbracelet/crush/internal/lsp/util"
 )
 
 // Requests
 
-func HandleWorkspaceConfiguration(params json.RawMessage) (any, error) {
+func (c *Client) HandleWorkspaceConfiguration(params json.RawMessage) (any, error) {
 	return []map[string]any{{}}, nil
 }
 
-func HandleRegisterCapability(params json.RawMessage) (any, error) {
+func (c *Client) HandleRegisterCapability(params json.RawMessage) (any, error) {
 	var registerParams protocol.RegistrationParams
 	if err := json.Unmarshal(params, ®isterParams); err != nil {
 		slog.Error("Error unmarshaling registration params", "error", err)
@@ -47,7 +45,7 @@ func HandleRegisterCapability(params json.RawMessage) (any, error) {
 	return nil, nil
 }
 
-func HandleApplyEdit(params json.RawMessage) (any, error) {
+func (c *Client) HandleApplyEdit(params json.RawMessage) (any, error) {
 	var edit protocol.ApplyWorkspaceEditParams
 	if err := json.Unmarshal(params, &edit); err != nil {
 		return nil, err
@@ -82,28 +80,27 @@ func notifyFileWatchRegistration(id string, watchers []protocol.FileSystemWatche
 
 // Notifications
 
-func HandleServerMessage(params json.RawMessage) {
-	cfg := config.Get()
+func (c *Client) HandleServerMessage(params json.RawMessage) {
 	var msg struct {
 		Type    int    `json:"type"`
 		Message string `json:"message"`
 	}
 	if err := json.Unmarshal(params, &msg); err == nil {
-		if cfg.Options.DebugLSP {
+		if c.debug {
 			slog.Debug("Server message", "type", msg.Type, "message", msg.Message)
 		}
 	}
 }
 
-func HandleDiagnostics(client *Client, params json.RawMessage) {
+func (c *Client) HandleDiagnostics(params json.RawMessage) {
 	var diagParams protocol.PublishDiagnosticsParams
 	if err := json.Unmarshal(params, &diagParams); err != nil {
 		slog.Error("Error unmarshaling diagnostics params", "error", err)
 		return
 	}
 
-	client.diagnosticsMu.Lock()
-	defer client.diagnosticsMu.Unlock()
+	c.diagnosticsMu.Lock()
+	defer c.diagnosticsMu.Unlock()
 
-	client.diagnostics[diagParams.URI] = diagParams.Diagnostics
+	c.diagnostics[diagParams.URI] = diagParams.Diagnostics
 }
  
  
  
    
    @@ -8,19 +8,16 @@ import (
 	"io"
 	"log/slog"
 	"strings"
-
-	"github.com/charmbracelet/crush/internal/config"
 )
 
 // WriteMessage writes an LSP message to the given writer
-func WriteMessage(w io.Writer, msg *Message) error {
+func WriteMessage(w io.Writer, msg *Message, debug bool) error {
 	data, err := json.Marshal(msg)
 	if err != nil {
 		return fmt.Errorf("failed to marshal message: %w", err)
 	}
-	cfg := config.Get()
 
-	if cfg.Options.DebugLSP {
+	if debug {
 		slog.Debug("Sending message to server", "method", msg.Method, "id", msg.ID)
 	}
 
@@ -38,8 +35,7 @@ func WriteMessage(w io.Writer, msg *Message) error {
 }
 
 // ReadMessage reads a single LSP message from the given reader
-func ReadMessage(r *bufio.Reader) (*Message, error) {
-	cfg := config.Get()
+func ReadMessage(r *bufio.Reader, debug bool) (*Message, error) {
 	// Read headers
 	var contentLength int
 	for {
@@ -49,7 +45,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) {
 		}
 		line = strings.TrimSpace(line)
 
-		if cfg.Options.DebugLSP {
+		if debug {
 			slog.Debug("Received header", "line", line)
 		}
 
@@ -65,7 +61,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) {
 		}
 	}
 
-	if cfg.Options.DebugLSP {
+	if debug {
 		slog.Debug("Content-Length", "length", contentLength)
 	}
 
@@ -76,7 +72,7 @@ func ReadMessage(r *bufio.Reader) (*Message, error) {
 		return nil, fmt.Errorf("failed to read content: %w", err)
 	}
 
-	if cfg.Options.DebugLSP {
+	if debug {
 		slog.Debug("Received content", "content", string(content))
 	}
 
@@ -91,11 +87,10 @@ func ReadMessage(r *bufio.Reader) (*Message, error) {
 
 // handleMessages reads and dispatches messages in a loop
 func (c *Client) handleMessages() {
-	cfg := config.Get()
 	for {
-		msg, err := ReadMessage(c.stdout)
+		msg, err := ReadMessage(c.stdout, c.debug)
 		if err != nil {
-			if cfg.Options.DebugLSP {
+			if c.debug {
 				slog.Error("Error reading message", "error", err)
 			}
 			return
@@ -103,7 +98,7 @@ func (c *Client) handleMessages() {
 
 		// Handle server->client request (has both Method and ID)
 		if msg.Method != "" && msg.ID != 0 {
-			if cfg.Options.DebugLSP {
+			if c.debug {
 				slog.Debug("Received request from server", "method", msg.Method, "id", msg.ID)
 			}
 
@@ -143,7 +138,7 @@ func (c *Client) handleMessages() {
 			}
 
 			// Send response back to server
-			if err := WriteMessage(c.stdin, response); err != nil {
+			if err := WriteMessage(c.stdin, response, c.debug); err != nil {
 				slog.Error("Error sending response to server", "error", err)
 			}
 
@@ -157,11 +152,11 @@ func (c *Client) handleMessages() {
 			c.notificationMu.RUnlock()
 
 			if ok {
-				if cfg.Options.DebugLSP {
+				if c.debug {
 					slog.Debug("Handling notification", "method", msg.Method)
 				}
 				go handler(msg.Params)
-			} else if cfg.Options.DebugLSP {
+			} else if c.debug {
 				slog.Debug("No handler for notification", "method", msg.Method)
 			}
 			continue
@@ -174,12 +169,12 @@ func (c *Client) handleMessages() {
 			c.handlersMu.RUnlock()
 
 			if ok {
-				if cfg.Options.DebugLSP {
+				if c.debug {
 					slog.Debug("Received response for request", "id", msg.ID)
 				}
 				ch <- msg
 				close(ch)
-			} else if cfg.Options.DebugLSP {
+			} else if c.debug {
 				slog.Debug("No handler for response", "id", msg.ID)
 			}
 		}
@@ -188,10 +183,9 @@ func (c *Client) handleMessages() {
 
 // Call makes a request and waits for the response
 func (c *Client) Call(ctx context.Context, method string, params any, result any) error {
-	cfg := config.Get()
 	id := c.nextID.Add(1)
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Making call", "method", method, "id", id)
 	}
 
@@ -213,11 +207,11 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any
 	}()
 
 	// Send request
-	if err := WriteMessage(c.stdin, msg); err != nil {
+	if err := WriteMessage(c.stdin, msg, c.debug); err != nil {
 		return fmt.Errorf("failed to send request: %w", err)
 	}
 
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Request sent", "method", method, "id", id)
 	}
 
@@ -226,7 +220,7 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any
 	case <-ctx.Done():
 		return ctx.Err()
 	case resp := <-ch:
-		if cfg.Options.DebugLSP {
+		if c.debug {
 			slog.Debug("Received response", "id", id)
 		}
 
@@ -252,8 +246,7 @@ func (c *Client) Call(ctx context.Context, method string, params any, result any
 
 // Notify sends a notification (a request without an ID that doesn't expect a response)
 func (c *Client) Notify(ctx context.Context, method string, params any) error {
-	cfg := config.Get()
-	if cfg.Options.DebugLSP {
+	if c.debug {
 		slog.Debug("Sending notification", "method", method)
 	}
 
@@ -262,7 +255,7 @@ func (c *Client) Notify(ctx context.Context, method string, params any) error {
 		return fmt.Errorf("failed to create notification: %w", err)
 	}
 
-	if err := WriteMessage(c.stdin, msg); err != nil {
+	if err := WriteMessage(c.stdin, msg, c.debug); err != nil {
 		return fmt.Errorf("failed to send notification: %w", err)
 	}
 
  
  
  
    
    @@ -11,9 +11,8 @@ import (
 	"time"
 
 	"github.com/bmatcuk/doublestar/v4"
-	"github.com/charmbracelet/crush/internal/config"
-	"github.com/charmbracelet/crush/internal/csync"
 
+	"github.com/charmbracelet/crush/internal/csync"
 	"github.com/charmbracelet/crush/internal/lsp"
 	"github.com/charmbracelet/crush/internal/lsp/protocol"
 	"github.com/fsnotify/fsnotify"
@@ -23,6 +22,7 @@ import (
 type WorkspaceWatcher struct {
 	client        *lsp.Client
 	name          string
+	debug         bool
 	workspacePath string
 
 	debounceTime time.Duration
@@ -41,10 +41,11 @@ func init() {
 }
 
 // NewWorkspaceWatcher creates a new workspace watcher
-func NewWorkspaceWatcher(name string, client *lsp.Client) *WorkspaceWatcher {
+func NewWorkspaceWatcher(name string, client *lsp.Client, debub bool) *WorkspaceWatcher {
 	return &WorkspaceWatcher{
 		name:          name,
 		client:        client,
+		debug:         debub,
 		debounceTime:  300 * time.Millisecond,
 		debounceMap:   csync.NewMap[string, *time.Timer](),
 		registrations: []protocol.FileSystemWatcher{},
@@ -53,8 +54,6 @@ func NewWorkspaceWatcher(name string, client *lsp.Client) *WorkspaceWatcher {
 
 // AddRegistrations adds file watchers to track
 func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watchers []protocol.FileSystemWatcher) {
-	cfg := config.Get()
-
 	slog.Debug("Adding file watcher registrations")
 	w.registrationMu.Lock()
 	defer w.registrationMu.Unlock()
@@ -63,7 +62,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 	w.registrations = append(w.registrations, watchers...)
 
 	// Print detailed registration information for debugging
-	if cfg.Options.DebugLSP {
+	if w.debug {
 		slog.Debug("Adding file watcher registrations",
 			"id", id,
 			"watchers", len(watchers),
@@ -132,7 +131,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 			highPriorityFilesOpened := w.openHighPriorityFiles(ctx, serverName)
 			filesOpened += highPriorityFilesOpened
 
-			if cfg.Options.DebugLSP {
+			if w.debug {
 				slog.Debug("Opened high-priority files",
 					"count", highPriorityFilesOpened,
 					"serverName", serverName)
@@ -140,7 +139,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 {
+				if w.debug {
 					slog.Debug("Reached file limit with high-priority files",
 						"filesOpened", filesOpened,
 						"maxFiles", maxFilesToOpen)
@@ -158,7 +157,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 				// Skip directories that should be excluded
 				if d.IsDir() {
 					if path != w.workspacePath && shouldExcludeDir(path) {
-						if cfg.Options.DebugLSP {
+						if w.debug {
 							slog.Debug("Skipping excluded directory", "path", path)
 						}
 						return filepath.SkipDir
@@ -186,7 +185,7 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 			})
 
 			elapsedTime := time.Since(startTime)
-			if cfg.Options.DebugLSP {
+			if w.debug {
 				slog.Debug("Limited workspace scan complete",
 					"filesOpened", filesOpened,
 					"maxFiles", maxFilesToOpen,
@@ -195,11 +194,11 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 				)
 			}
 
-			if err != nil && cfg.Options.DebugLSP {
+			if err != nil && w.debug {
 				slog.Debug("Error scanning workspace for files to open", "error", err)
 			}
 		}()
-	} else if cfg.Options.DebugLSP {
+	} else if w.debug {
 		slog.Debug("Using on-demand file loading for server", "server", serverName)
 	}
 }
@@ -207,7 +206,6 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
 // openHighPriorityFiles opens important files for the server type
 // Returns the number of files opened
 func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName string) int {
-	cfg := config.Get()
 	filesOpened := 0
 
 	// Define patterns for high-priority files based on server type
@@ -275,7 +273,7 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
 		// Use doublestar.Glob to find files matching the pattern (supports ** patterns)
 		matches, err := doublestar.Glob(os.DirFS(w.workspacePath), pattern)
 		if err != nil {
-			if cfg.Options.DebugLSP {
+			if w.debug {
 				slog.Debug("Error finding high-priority files", "pattern", pattern, "error", err)
 			}
 			continue
@@ -287,7 +285,7 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
 
 			// Skip directories and excluded files
 			info, err := os.Stat(fullPath)
-			if err != nil || info.IsDir() || shouldExcludeFile(fullPath) {
+			if err != nil || info.IsDir() || shouldExcludeFile(fullPath, w.debug) {
 				continue
 			}
 
@@ -309,12 +307,12 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
 		for j := i; j < end; j++ {
 			fullPath := filesToOpen[j]
 			if err := w.client.OpenFile(ctx, fullPath); err != nil {
-				if cfg.Options.DebugLSP {
+				if w.debug {
 					slog.Debug("Error opening high-priority file", "path", fullPath, "error", err)
 				}
 			} else {
 				filesOpened++
-				if cfg.Options.DebugLSP {
+				if w.debug {
 					slog.Debug("Opened high-priority file", "path", fullPath)
 				}
 			}
@@ -331,7 +329,6 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
 
 // WatchWorkspace sets up file watching for a workspace
 func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath string) {
-	cfg := config.Get()
 	w.workspacePath = workspacePath
 
 	slog.Debug("Starting workspace watcher", "workspacePath", workspacePath, "serverName", w.name)
@@ -356,7 +353,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
 		// Skip excluded directories (except workspace root)
 		if d.IsDir() && path != workspacePath {
 			if shouldExcludeDir(path) {
-				if cfg.Options.DebugLSP {
+				if w.debug {
 					slog.Debug("Skipping excluded directory", "path", path)
 				}
 				return filepath.SkipDir
@@ -401,7 +398,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
 						}
 					} else {
 						// For newly created files
-						if !shouldExcludeFile(event.Name) {
+						if !shouldExcludeFile(event.Name, w.debug) {
 							w.openMatchingFile(ctx, event.Name)
 						}
 					}
@@ -409,7 +406,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
 			}
 
 			// Debug logging
-			if cfg.Options.DebugLSP {
+			if w.debug {
 				matched, kind := w.isPathWatched(event.Name)
 				slog.Debug("File event",
 					"path", event.Name,
@@ -650,8 +647,6 @@ func (w *WorkspaceWatcher) debounceHandleFileEvent(ctx context.Context, uri stri
 	// Create new timer
 	w.debounceMap.Set(key, time.AfterFunc(w.debounceTime, func() {
 		w.handleFileEvent(ctx, uri, changeType)
-
-		// Cleanup timer after execution
 		w.debounceMap.Del(key)
 	}))
 }
@@ -684,8 +679,7 @@ func (w *WorkspaceWatcher) handleFileEvent(ctx context.Context, uri string, chan
 
 // notifyFileEvent sends a didChangeWatchedFiles notification for a file event
 func (w *WorkspaceWatcher) notifyFileEvent(ctx context.Context, uri string, changeType protocol.FileChangeType) error {
-	cfg := config.Get()
-	if cfg.Options.DebugLSP {
+	if w.debug {
 		slog.Debug("Notifying file event",
 			"uri", uri,
 			"changeType", changeType,
@@ -798,9 +792,8 @@ func shouldExcludeDir(dirPath string) bool {
 }
 
 // shouldExcludeFile returns true if the file should be excluded from opening
-func shouldExcludeFile(filePath string) bool {
+func shouldExcludeFile(filePath string, debug bool) bool {
 	fileName := filepath.Base(filePath)
-	cfg := config.Get()
 	// Skip dot files
 	if strings.HasPrefix(fileName, ".") {
 		return true
@@ -826,12 +819,11 @@ func shouldExcludeFile(filePath string) bool {
 
 	// Skip large files
 	if info.Size() > maxFileSize {
-		if cfg.Options.DebugLSP {
+		if debug {
 			slog.Debug("Skipping large file",
 				"path", filePath,
 				"size", info.Size(),
 				"maxSize", maxFileSize,
-				"debug", cfg.Options.Debug,
 				"sizeMB", float64(info.Size())/(1024*1024),
 				"maxSizeMB", float64(maxFileSize)/(1024*1024),
 			)
@@ -844,7 +836,6 @@ func shouldExcludeFile(filePath string) bool {
 
 // openMatchingFile opens a file if it matches any of the registered patterns
 func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
-	cfg := config.Get()
 	// Skip directories
 	info, err := os.Stat(path)
 	if err != nil || info.IsDir() {
@@ -852,7 +843,7 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
 	}
 
 	// Skip excluded files
-	if shouldExcludeFile(path) {
+	if shouldExcludeFile(path, w.debug) {
 		return
 	}
 
@@ -867,10 +858,10 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
 	// Check if the file is a high-priority file that should be opened immediately
 	// This helps with project initialization for certain language servers
 	if isHighPriorityFile(path, serverName) {
-		if cfg.Options.DebugLSP {
+		if w.debug {
 			slog.Debug("Opening high-priority file", "path", path, "serverName", serverName)
 		}
-		if err := w.client.OpenFile(ctx, path); err != nil && cfg.Options.DebugLSP {
+		if err := w.client.OpenFile(ctx, path); err != nil && w.debug {
 			slog.Error("Error opening high-priority file", "path", path, "error", err)
 		}
 		return
@@ -884,7 +875,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 {
+		if w.debug {
 			slog.Debug("Skipping large file for preloading", "path", path, "size", info.Size())
 		}
 		return
@@ -912,7 +903,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 {
+		if err := w.client.OpenFile(ctx, path); err != nil && w.debug {
 			slog.Error("Error opening file", "path", path, "error", err)
 		}
 	}