@@ -301,9 +301,14 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
301301 }
302302 if err == nil && handler .buildSketchSymbolsLoad {
303303 handler .buildSketchSymbolsLoad = false
304- log .Println ("Resfreshing document symbols" )
304+ log .Println ("--! Resfreshing document symbols" )
305305 err = handler .refreshCppDocumentSymbols ()
306306 }
307+ if err == nil && handler .buildSketchSymbolsCheck {
308+ handler .buildSketchSymbolsCheck = false
309+ log .Println ("--! Resfreshing document symbols" )
310+ err = handler .checkCppDocumentSymbols ()
311+ }
307312 if err != nil {
308313 // Exit the process and trigger a restart by the client in case of a severe error
309314 if err .Error () == "context deadline exceeded" {
@@ -414,8 +419,40 @@ func (handler *InoHandler) refreshCppDocumentSymbols() error {
414419 if symbols , ok := result .([]lsp.DocumentSymbol ); ! ok {
415420 return errors .WithMessage (err , "quering source code symbols (2)" )
416421 } else {
422+ // Filter non-functions symbols
423+ i := 0
424+ for _ , symbol := range symbols {
425+ if symbol .Kind != lsp .SKFunction {
426+ continue
427+ }
428+ symbols [i ] = symbol
429+ i ++
430+ }
431+ symbols = symbols [:i ]
432+ for _ , symbol := range symbols {
433+ log .Printf (" symbol: %s %s" , symbol .Kind , symbol .Name )
434+ }
417435 handler .buildSketchSymbols = symbols
418- log .Printf ("%+v\n " , symbols )
436+ }
437+ return nil
438+ }
439+
440+ func (handler * InoHandler ) checkCppDocumentSymbols () error {
441+ oldSymbols := handler .buildSketchSymbols
442+ if err := handler .refreshCppDocumentSymbols (); err != nil {
443+ return err
444+ }
445+ if len (oldSymbols ) != len (handler .buildSketchSymbols ) {
446+ log .Println ("--! new symbols detected, triggering sketch rebuild!" )
447+ handler .scheduleRebuildEnvironment ()
448+ return nil
449+ }
450+ for i , old := range oldSymbols {
451+ if newName := handler .buildSketchSymbols [i ].Name ; old .Name != newName {
452+ log .Printf ("--! symbols changed, triggering sketch rebuild: '%s' -> '%s'" , old .Name , newName )
453+ handler .scheduleRebuildEnvironment ()
454+ return nil
455+ }
419456 }
420457 return nil
421458}
@@ -519,7 +556,7 @@ func (handler *InoHandler) didChange(ctx context.Context, req *lsp.DidChangeText
519556 // TODO: Detect changes in critical lines (for example function definitions)
520557 // and trigger arduino-preprocessing + clangd restart.
521558
522- log .Println (" uh oh DIRTY CHANGE !" )
559+ log .Println ("--! DIRTY CHANGE, force sketch rebuild !" )
523560 handler .scheduleRebuildEnvironment ()
524561 }
525562
@@ -1044,6 +1081,17 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
10441081 log .Printf (" > %d:%d - %v: %s" , diag .Range .Start .Line , diag .Range .Start .Character , diag .Severity , diag .Code )
10451082 }
10461083 }
1084+
1085+ // If we have an "undefined reference" in the .ino code trigger a
1086+ // check for newly created symbols (that in turn may trigger a
1087+ // new arduino-preprocessing of the sketch).
1088+ if msg .URI .AsPath ().Ext () == ".ino" {
1089+ for _ , diag := range msg .Diagnostics {
1090+ if diag .Code == "undeclared_var_use_suggest" {
1091+ handler .buildSketchSymbolsCheck = true
1092+ }
1093+ }
1094+ }
10471095 if err := handler .StdioConn .Notify (ctx , "textDocument/publishDiagnostics" , msg ); err != nil {
10481096 return nil , err
10491097 }
0 commit comments