@@ -50,7 +50,6 @@ type INOLanguageServer struct {
5050 closing chan bool
5151 clangdStarted * sync.Cond
5252 dataMux sync.RWMutex
53- lspInitializeParams * lsp.InitializeParams
5453 buildPath * paths.Path
5554 buildSketchRoot * paths.Path
5655 buildSketchCpp * paths.Path
@@ -245,21 +244,70 @@ func (handler *INOLanguageServer) CheckCppDocumentSymbols() error {
245244 return nil
246245}
247246
248- func (handler * INOLanguageServer ) startClangd (inoParams * lsp.InitializeParams ) {
247+ func (ls * INOLanguageServer ) startClangd (inoParams * lsp.InitializeParams ) error {
249248 logger := NewLSPFunctionLogger (color .HiCyanString , "INIT --- " )
250- logger .Logf ("initializing workbench" )
249+ logger .Logf ("initializing workbench: %s" , inoParams . RootURI )
251250
252251 // Start clangd asynchronously
253- handler .writeLock (logger , false ) // do not wait for clangd... we are starting it :-)
254- defer handler .writeUnlock (logger )
252+ ls .writeLock (logger , false ) // do not wait for clangd... we are starting it :-)
253+ defer ls .writeUnlock (logger )
254+
255+ ls .sketchRoot = inoParams .RootURI .AsPath ()
256+ ls .sketchName = ls .sketchRoot .Base ()
257+ ls .buildSketchCpp = ls .buildSketchRoot .Join (ls .sketchName + ".ino.cpp" )
258+
259+ if err := ls .generateBuildEnvironment (logger ); err != nil {
260+ return err
261+ }
262+
263+ if cppContent , err := ls .buildSketchCpp .ReadFile (); err == nil {
264+ ls .sketchMapper = sourcemapper .CreateInoMapper (cppContent )
265+ ls .sketchMapper .CppText .Version = 1
266+ } else {
267+ return errors .WithMessage (err , "reading generated cpp file from sketch" )
268+ }
255269
256- // TODO: Inline this function
257- handler .initializeWorkbench (logger , inoParams )
270+ // Let's start clangd!
271+ dataFolder , err := extractDataFolderFromArduinoCLI (logger )
272+ if err != nil {
273+ logger .Logf ("error: %s" , err )
274+ }
275+
276+ // Start clangd
277+ ls .Clangd = NewClangdLSPClient (logger , ls .buildPath , ls .buildSketchCpp , dataFolder , ls )
278+ go func () {
279+ defer streams .CatchAndLogPanic ()
280+ ls .Clangd .Run ()
281+ logger .Logf ("Lost connection with clangd!" )
282+ ls .Close ()
283+ }()
284+
285+ // Send initialization command to clangd (1 sec. timeout)
286+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
287+ defer cancel ()
288+ cppInitializeParams := * inoParams
289+ cppInitializeParams .RootPath = ls .buildSketchRoot .String ()
290+ cppInitializeParams .RootURI = lsp .NewDocumentURIFromPath (ls .buildSketchRoot )
291+ if initRes , clangErr , err := ls .Clangd .conn .Initialize (ctx , & cppInitializeParams ); err != nil {
292+ logger .Logf ("error initilizing clangd: %v" , err )
293+ return err
294+ } else if clangErr != nil {
295+ logger .Logf ("error initilizing clangd: %v" , clangErr .AsError ())
296+ return clangErr .AsError ()
297+ } else {
298+ logger .Logf ("clangd successfully started: %s" , string (lsp .EncodeMessage (initRes )))
299+ }
300+
301+ if err := ls .Clangd .conn .Initialized (& lsp.InitializedParams {}); err != nil {
302+ logger .Logf ("error sending initialized notification to clangd: %v" , err )
303+ return err
304+ }
258305
259306 // signal that clangd is running now...
260- handler .clangdStarted .Broadcast ()
307+ ls .clangdStarted .Broadcast ()
261308
262309 logger .Logf ("Done initializing workbench" )
310+ return nil
263311}
264312
265313func (handler * INOLanguageServer ) InitializeReqFromIDE (ctx context.Context , logger jsonrpc.FunctionLogger , inoParams * lsp.InitializeParams ) (* lsp.InitializeResult , * jsonrpc.ResponseError ) {
@@ -1051,26 +1099,9 @@ func (ls *INOLanguageServer) CleanUp() {
10511099 }
10521100}
10531101
1054- func (ls * INOLanguageServer ) initializeWorkbench (logger jsonrpc.FunctionLogger , params * lsp.InitializeParams ) error {
1055- // TODO: This function must be split into two
1056- // -> start clang (when params != nil)
1057- // -> reser clang status (when params == nil)
1058- // the two flows shares very little
1059-
1060- currCppTextVersion := 0
1061- if params != nil {
1062- logger .Logf (" --> initialize(%s)" , params .RootURI )
1063- ls .sketchRoot = params .RootURI .AsPath ()
1064- ls .sketchName = ls .sketchRoot .Base ()
1065- ls .buildSketchCpp = ls .buildSketchRoot .Join (ls .sketchName + ".ino.cpp" )
1066-
1067- ls .lspInitializeParams = params
1068- ls .lspInitializeParams .RootPath = ls .buildSketchRoot .String ()
1069- ls .lspInitializeParams .RootURI = lsp .NewDocumentURIFromPath (ls .buildSketchRoot )
1070- } else {
1071- logger .Logf (" --> RE-initialize()" )
1072- currCppTextVersion = ls .sketchMapper .CppText .Version
1073- }
1102+ func (ls * INOLanguageServer ) initializeWorkbench (logger jsonrpc.FunctionLogger ) error {
1103+ logger .Logf ("--> RE-initialize()" )
1104+ currCppTextVersion := ls .sketchMapper .CppText .Version
10741105
10751106 if err := ls .generateBuildEnvironment (logger ); err != nil {
10761107 return err
@@ -1083,69 +1114,31 @@ func (ls *INOLanguageServer) initializeWorkbench(logger jsonrpc.FunctionLogger,
10831114 return errors .WithMessage (err , "reading generated cpp file from sketch" )
10841115 }
10851116
1086- if params == nil {
1087- // If we are restarting re-synchronize clangd
1088- cppURI := lsp .NewDocumentURIFromPath (ls .buildSketchCpp )
1089-
1090- logger .Logf ("Sending 'didSave' notification to Clangd" )
1091-
1092- didSaveParams := & lsp.DidSaveTextDocumentParams {
1093- TextDocument : lsp.TextDocumentIdentifier {URI : cppURI },
1094- }
1095- if err := ls .Clangd .conn .TextDocumentDidSave (didSaveParams ); err != nil {
1096- logger .Logf (" error reinitilizing clangd:" , err )
1097- return err
1098- }
1099-
1100- logger .Logf ("Sending 'didChange' notification to Clangd" )
1101- didChangeParams := & lsp.DidChangeTextDocumentParams {
1102- TextDocument : lsp.VersionedTextDocumentIdentifier {
1103- TextDocumentIdentifier : lsp.TextDocumentIdentifier {URI : cppURI },
1104- Version : ls .sketchMapper .CppText .Version ,
1105- },
1106- ContentChanges : []lsp.TextDocumentContentChangeEvent {
1107- {Text : ls .sketchMapper .CppText .Text },
1108- },
1109- }
1110- if err := ls .Clangd .conn .TextDocumentDidChange (didChangeParams ); err != nil {
1111- logger .Logf (" error reinitilizing clangd:" , err )
1112- return err
1113- }
1114- } else {
1115- // Otherwise start clangd!
1116- dataFolder , err := extractDataFolderFromArduinoCLI (logger )
1117- if err != nil {
1118- logger .Logf (" error: %s" , err )
1119- }
1120-
1121- // Start clangd
1122- ls .Clangd = NewClangdLSPClient (logger , ls .buildPath , ls .buildSketchCpp , dataFolder , ls )
1123- go func () {
1124- defer streams .CatchAndLogPanic ()
1125- ls .Clangd .Run ()
1126- logger .Logf ("Lost connection with clangd!" )
1127- ls .Close ()
1128- }()
1129-
1130- // Send initialization command to clangd
1131- ctx , cancel := context .WithTimeout (context .Background (), time .Second )
1132- defer cancel ()
1133- initRes , clangErr , err := ls .Clangd .conn .Initialize (ctx , ls .lspInitializeParams )
1134- if err != nil {
1135- logger .Logf (" error initilizing clangd: %v" , err )
1136- return err
1137- }
1138- if clangErr != nil {
1139- logger .Logf (" error initilizing clangd: %v" , clangErr .AsError ())
1140- return clangErr .AsError ()
1141- } else {
1142- logger .Logf ("clangd successfully started: %s" , string (lsp .EncodeMessage (initRes )))
1143- }
1117+ // Send didSave to notify clang that the source cpp is changed
1118+ logger .Logf ("Sending 'didSave' notification to Clangd" )
1119+ cppURI := lsp .NewDocumentURIFromPath (ls .buildSketchCpp )
1120+ didSaveParams := & lsp.DidSaveTextDocumentParams {
1121+ TextDocument : lsp.TextDocumentIdentifier {URI : cppURI },
1122+ }
1123+ if err := ls .Clangd .conn .TextDocumentDidSave (didSaveParams ); err != nil {
1124+ logger .Logf ("error reinitilizing clangd:" , err )
1125+ return err
1126+ }
11441127
1145- if err := ls .Clangd .conn .Initialized (& lsp.InitializedParams {}); err != nil {
1146- logger .Logf (" error sending initialized notification to clangd: %v" , err )
1147- return err
1148- }
1128+ // Send the full text to clang
1129+ logger .Logf ("Sending full-text 'didChange' notification to Clangd" )
1130+ didChangeParams := & lsp.DidChangeTextDocumentParams {
1131+ TextDocument : lsp.VersionedTextDocumentIdentifier {
1132+ TextDocumentIdentifier : lsp.TextDocumentIdentifier {URI : cppURI },
1133+ Version : ls .sketchMapper .CppText .Version ,
1134+ },
1135+ ContentChanges : []lsp.TextDocumentContentChangeEvent {
1136+ {Text : ls .sketchMapper .CppText .Text },
1137+ },
1138+ }
1139+ if err := ls .Clangd .conn .TextDocumentDidChange (didChangeParams ); err != nil {
1140+ logger .Logf ("error reinitilizing clangd:" , err )
1141+ return err
11491142 }
11501143
11511144 return nil
@@ -1359,6 +1352,7 @@ func (ls *INOLanguageServer) didChange(logger jsonrpc.FunctionLogger, inoDidChan
13591352 if dirty {
13601353 ls .scheduleRebuildEnvironment ()
13611354 }
1355+ ls .sketchMapper .DebugLogAll ()
13621356
13631357 logger .Logf ("New version:----------+\n " + ls .sketchMapper .CppText .Text + "\n ----------------------" )
13641358
0 commit comments