@@ -96,19 +96,19 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
9696 // Determine server type for specialized handling
9797 serverName := getServerNameFromContext (ctx )
9898 logging .Debug ("Server type detected" , "serverName" , serverName )
99-
99+
100100 // Check if this server has sent file watchers
101101 hasFileWatchers := len (watchers ) > 0
102-
102+
103103 // For servers that need file preloading, we'll use a smart approach
104104 if shouldPreloadFiles (serverName ) || ! hasFileWatchers {
105105 go func () {
106106 startTime := time .Now ()
107107 filesOpened := 0
108-
108+
109109 // Determine max files to open based on server type
110110 maxFilesToOpen := 50 // Default conservative limit
111-
111+
112112 switch serverName {
113113 case "typescript" , "typescript-language-server" , "tsserver" , "vtsls" :
114114 // TypeScript servers benefit from seeing more files
@@ -117,17 +117,17 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
117117 // Java servers need to see many files for project model
118118 maxFilesToOpen = 200
119119 }
120-
120+
121121 // First, open high-priority files
122122 highPriorityFilesOpened := w .openHighPriorityFiles (ctx , serverName )
123123 filesOpened += highPriorityFilesOpened
124-
124+
125125 if cnf .DebugLSP {
126- logging .Debug ("Opened high-priority files" ,
126+ logging .Debug ("Opened high-priority files" ,
127127 "count" , highPriorityFilesOpened ,
128128 "serverName" , serverName )
129129 }
130-
130+
131131 // If we've already opened enough high-priority files, we might not need more
132132 if filesOpened >= maxFilesToOpen {
133133 if cnf .DebugLSP {
@@ -137,9 +137,9 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
137137 }
138138 return
139139 }
140-
140+
141141 // For the remaining slots, walk the directory and open matching files
142-
142+
143143 err := filepath .WalkDir (w .workspacePath , func (path string , d os.DirEntry , err error ) error {
144144 if err != nil {
145145 return err
@@ -199,10 +199,10 @@ func (w *WorkspaceWatcher) AddRegistrations(ctx context.Context, id string, watc
199199func (w * WorkspaceWatcher ) openHighPriorityFiles (ctx context.Context , serverName string ) int {
200200 cnf := config .Get ()
201201 filesOpened := 0
202-
202+
203203 // Define patterns for high-priority files based on server type
204204 var patterns []string
205-
205+
206206 switch serverName {
207207 case "typescript" , "typescript-language-server" , "tsserver" , "vtsls" :
208208 patterns = []string {
@@ -256,7 +256,7 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
256256 "**/.editorconfig" ,
257257 }
258258 }
259-
259+
260260 // For each pattern, find and open matching files
261261 for _ , pattern := range patterns {
262262 // Use doublestar.Glob to find files matching the pattern (supports ** patterns)
@@ -267,17 +267,17 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
267267 }
268268 continue
269269 }
270-
270+
271271 for _ , match := range matches {
272272 // Convert relative path to absolute
273273 fullPath := filepath .Join (w .workspacePath , match )
274-
274+
275275 // Skip directories and excluded files
276276 info , err := os .Stat (fullPath )
277277 if err != nil || info .IsDir () || shouldExcludeFile (fullPath ) {
278278 continue
279279 }
280-
280+
281281 // Open the file
282282 if err := w .client .OpenFile (ctx , fullPath ); err != nil {
283283 if cnf .DebugLSP {
@@ -289,17 +289,17 @@ func (w *WorkspaceWatcher) openHighPriorityFiles(ctx context.Context, serverName
289289 logging .Debug ("Opened high-priority file" , "path" , fullPath )
290290 }
291291 }
292-
292+
293293 // Add a small delay to prevent overwhelming the server
294294 time .Sleep (20 * time .Millisecond )
295-
295+
296296 // Limit the number of files opened per pattern
297297 if filesOpened >= 5 && (serverName != "java" && serverName != "jdtls" ) {
298298 break
299299 }
300300 }
301301 }
302-
302+
303303 return filesOpened
304304}
305305
@@ -310,16 +310,16 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
310310
311311 // Store the watcher in the context for later use
312312 ctx = context .WithValue (ctx , "workspaceWatcher" , w )
313-
313+
314314 // If the server name isn't already in the context, try to detect it
315315 if _ , ok := ctx .Value ("serverName" ).(string ); ! ok {
316316 serverName := getServerNameFromContext (ctx )
317317 ctx = context .WithValue (ctx , "serverName" , serverName )
318318 }
319-
319+
320320 serverName := getServerNameFromContext (ctx )
321321 logging .Debug ("Starting workspace watcher" , "workspacePath" , workspacePath , "serverName" , serverName )
322-
322+
323323 // Register handler for file watcher registrations from the server
324324 lsp .RegisterFileWatchHandler (func (id string , watchers []protocol.FileSystemWatcher ) {
325325 w .AddRegistrations (ctx , id , watchers )
@@ -414,7 +414,11 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
414414 case event .Op & fsnotify .Create != 0 :
415415 // Already handled earlier in the event loop
416416 // Just send the notification if needed
417- info , _ := os .Stat (event .Name )
417+ info , err := os .Stat (event .Name )
418+ if err != nil {
419+ logging .Error ("Error getting file info" , "path" , event .Name , "error" , err )
420+ return
421+ }
418422 if ! info .IsDir () && watchKind & protocol .WatchCreate != 0 {
419423 w .debounceHandleFileEvent (ctx , uri , protocol .FileChangeType (protocol .Created ))
420424 }
@@ -682,7 +686,7 @@ func getServerNameFromContext(ctx context.Context) string {
682686 if serverName , ok := ctx .Value ("serverName" ).(string ); ok && serverName != "" {
683687 return strings .ToLower (serverName )
684688 }
685-
689+
686690 // Otherwise, try to extract server name from the client command path
687691 if w , ok := ctx .Value ("workspaceWatcher" ).(* WorkspaceWatcher ); ok && w != nil && w .client != nil && w .client .Cmd != nil {
688692 path := strings .ToLower (w .client .Cmd .Path )
@@ -865,7 +869,7 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
865869 if watched , _ := w .isPathWatched (path ); watched {
866870 // Get server name for specialized handling
867871 serverName := getServerNameFromContext (ctx )
868-
872+
869873 // Check if the file is a high-priority file that should be opened immediately
870874 // This helps with project initialization for certain language servers
871875 if isHighPriorityFile (path , serverName ) {
@@ -881,21 +885,21 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
881885 // For non-high-priority files, we'll use different strategies based on server type
882886 if shouldPreloadFiles (serverName ) {
883887 // For servers that benefit from preloading, open files but with limits
884-
888+
885889 // Check file size - for preloading we're more conservative
886890 if info .Size () > (1 * 1024 * 1024 ) { // 1MB limit for preloaded files
887891 if cnf .DebugLSP {
888892 logging .Debug ("Skipping large file for preloading" , "path" , path , "size" , info .Size ())
889893 }
890894 return
891895 }
892-
896+
893897 // Check file extension for common source files
894898 ext := strings .ToLower (filepath .Ext (path ))
895-
899+
896900 // Only preload source files for the specific language
897901 shouldOpen := false
898-
902+
899903 switch serverName {
900904 case "typescript" , "typescript-language-server" , "tsserver" , "vtsls" :
901905 shouldOpen = ext == ".ts" || ext == ".js" || ext == ".tsx" || ext == ".jsx"
@@ -913,7 +917,7 @@ func (w *WorkspaceWatcher) openMatchingFile(ctx context.Context, path string) {
913917 // For unknown servers, be conservative
914918 shouldOpen = false
915919 }
916-
920+
917921 if shouldOpen {
918922 // Don't need to check if it's already open - the client.OpenFile handles that
919923 if err := w .client .OpenFile (ctx , path ); err != nil && cnf .DebugLSP {
@@ -943,13 +947,13 @@ func isHighPriorityFile(path string, serverName string) bool {
943947 fileName == "main.js"
944948 case "gopls" :
945949 // For Go, we want to open go.mod files immediately
946- return fileName == "go.mod" ||
950+ return fileName == "go.mod" ||
947951 fileName == "go.sum" ||
948952 // Also open main.go files
949953 fileName == "main.go"
950954 case "rust-analyzer" :
951955 // For Rust, we want to open Cargo.toml files immediately
952- return fileName == "Cargo.toml" ||
956+ return fileName == "Cargo.toml" ||
953957 fileName == "Cargo.lock" ||
954958 // Also open lib.rs and main.rs
955959 fileName == "lib.rs" ||
0 commit comments