@@ -59,6 +59,7 @@ type InoHandler struct {
5959 sketchMapper * sourcemapper.InoMapper
6060 sketchTrackedFilesCount int
6161 docs map [lsp.DocumentURI ]* lsp.TextDocumentItem
62+ docHasDiagnostics map [lsp.DocumentURI ]bool
6263
6364 config lsp.BoardConfig
6465 synchronizer Synchronizer
@@ -68,6 +69,7 @@ type InoHandler struct {
6869func NewInoHandler (stdio io.ReadWriteCloser , board lsp.Board ) * InoHandler {
6970 handler := & InoHandler {
7071 docs : map [lsp.DocumentURI ]* lsp.TextDocumentItem {},
72+ docHasDiagnostics : map [lsp.DocumentURI ]bool {},
7173 config : lsp.BoardConfig {
7274 SelectedBoard : board ,
7375 },
@@ -1040,23 +1042,6 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
10401042 // we should transform back N diagnostics of sketch.cpp.ino into
10411043 // their .ino counter parts (that may span over multiple files...)
10421044
1043- // Remove diagnostics from all .ino if there are no errors coming from clang
1044- if len (p .Diagnostics ) == 0 {
1045- // XXX: Optimize this to publish "empty diagnostics" only to .ino that are
1046- // currently showing previous diagnostics.
1047-
1048- for sourceURI := range handler .docs {
1049- msg := lsp.PublishDiagnosticsParams {
1050- URI : sourceURI ,
1051- Diagnostics : []lsp.Diagnostic {},
1052- }
1053- if err := handler .StdioConn .Notify (ctx , "textDocument/publishDiagnostics" , msg ); err != nil {
1054- return nil , err
1055- }
1056- }
1057- return nil , nil
1058- }
1059-
10601045 convertedDiagnostics := map [string ][]lsp.Diagnostic {}
10611046 for _ , cppDiag := range p .Diagnostics {
10621047 inoSource , inoRange := handler .sketchMapper .CppToInoRange (cppDiag .Range )
@@ -1070,11 +1055,13 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
10701055 }
10711056
10721057 // Push back to IDE the converted diagnostics
1058+ docsWithDiagnostics := map [lsp.DocumentURI ]bool {}
10731059 for filename , inoDiags := range convertedDiagnostics {
10741060 msg := lsp.PublishDiagnosticsParams {
10751061 URI : lsp .NewDocumentURI (filename ),
10761062 Diagnostics : inoDiags ,
10771063 }
1064+ docsWithDiagnostics [msg .URI ] = true
10781065 if enableLogging {
10791066 log .Printf ("<-- publishDiagnostics(%s):" , msg .URI )
10801067 for _ , diag := range msg .Diagnostics {
@@ -1097,6 +1084,30 @@ func (handler *InoHandler) FromClangd(ctx context.Context, connection *jsonrpc2.
10971084 }
10981085 }
10991086
1087+ // Remove diagnostics from all .ino where there are no errors coming from clang
1088+ for sourceURI := range handler .docs {
1089+ if ! handler .docHasDiagnostics [sourceURI ] {
1090+ // skip if the document didn't have previously sent diagnostics
1091+ continue
1092+ }
1093+ if docsWithDiagnostics [sourceURI ] {
1094+ // skip if we already sent updated diagnostics
1095+ continue
1096+ }
1097+ // otherwise clear previous diagnostics
1098+ msg := lsp.PublishDiagnosticsParams {
1099+ URI : sourceURI ,
1100+ Diagnostics : []lsp.Diagnostic {},
1101+ }
1102+ if enableLogging {
1103+ log .Printf ("<-- publishDiagnostics(%s):" , msg .URI )
1104+ }
1105+ if err := handler .StdioConn .Notify (ctx , "textDocument/publishDiagnostics" , msg ); err != nil {
1106+ return nil , err
1107+ }
1108+ }
1109+
1110+ handler .docHasDiagnostics = docsWithDiagnostics
11001111 return nil , err
11011112 }
11021113
0 commit comments