9
9
"regexp"
10
10
"strconv"
11
11
"strings"
12
+ "sync"
12
13
"time"
13
14
14
15
"github.com/arduino/arduino-cli/arduino/builder"
@@ -59,26 +60,30 @@ func NewInoHandler(stdio io.ReadWriteCloser, board lsp.Board) *InoHandler {
59
60
if enableLogging {
60
61
log .Println ("Initial board configuration:" , board )
61
62
}
63
+
64
+ go handler .rebuildEnvironmentLoop ()
62
65
return handler
63
66
}
64
67
65
68
// InoHandler is a JSON-RPC handler that delegates messages to clangd.
66
69
type InoHandler struct {
67
- StdioConn * jsonrpc2.Conn
68
- ClangdConn * jsonrpc2.Conn
69
- lspInitializeParams * lsp.InitializeParams
70
- buildPath * paths.Path
71
- buildSketchRoot * paths.Path
72
- buildSketchCpp * paths.Path
73
- buildSketchCppVersion int
74
- buildSketchSymbols []lsp.DocumentSymbol
75
- buildSketchSymbolsLoad bool
76
- buildSketchSymbolsCheck bool
77
- sketchRoot * paths.Path
78
- sketchName string
79
- sketchMapper * sourcemapper.InoMapper
80
- sketchTrackedFilesCount int
81
- trackedFiles map [lsp.DocumentURI ]* lsp.TextDocumentItem
70
+ StdioConn * jsonrpc2.Conn
71
+ ClangdConn * jsonrpc2.Conn
72
+ lspInitializeParams * lsp.InitializeParams
73
+ buildPath * paths.Path
74
+ buildSketchRoot * paths.Path
75
+ buildSketchCpp * paths.Path
76
+ buildSketchCppVersion int
77
+ buildSketchSymbols []lsp.DocumentSymbol
78
+ buildSketchSymbolsLoad bool
79
+ buildSketchSymbolsCheck bool
80
+ rebuildSketchDeadline * time.Time
81
+ rebuildSketchDeadlineMutex sync.Mutex
82
+ sketchRoot * paths.Path
83
+ sketchName string
84
+ sketchMapper * sourcemapper.InoMapper
85
+ sketchTrackedFilesCount int
86
+ trackedFiles map [lsp.DocumentURI ]* lsp.TextDocumentItem
82
87
83
88
config lsp.BoardConfig
84
89
synchronizer Synchronizer
@@ -324,13 +329,18 @@ func (handler *InoHandler) exit() {
324
329
}
325
330
326
331
func (handler * InoHandler ) initializeWorkbench (params * lsp.InitializeParams ) error {
327
- rootURI := params .RootURI
328
- log .Printf ("--> initializeWorkbench(%s)\n " , rootURI )
332
+ currCppTextVersion := 0
333
+ if params != nil {
334
+ log .Printf ("--> initialize(%s)\n " , params .RootURI )
335
+ handler .lspInitializeParams = params
336
+ handler .sketchRoot = params .RootURI .AsPath ()
337
+ handler .sketchName = handler .sketchRoot .Base ()
338
+ } else {
339
+ currCppTextVersion = handler .sketchMapper .CppText .Version
340
+ log .Printf ("--> RE-initialize()\n " )
341
+ }
329
342
330
- handler .lspInitializeParams = params
331
- handler .sketchRoot = rootURI .AsPath ()
332
- handler .sketchName = handler .sketchRoot .Base ()
333
- if buildPath , err := generateBuildEnvironment (handler .sketchRoot , handler .config .SelectedBoard .Fqbn ); err == nil {
343
+ if buildPath , err := handler .generateBuildEnvironment (); err == nil {
334
344
handler .buildPath = buildPath
335
345
handler .buildSketchRoot = buildPath .Join ("sketch" )
336
346
} else {
@@ -343,22 +353,48 @@ func (handler *InoHandler) initializeWorkbench(params *lsp.InitializeParams) err
343
353
344
354
if cppContent , err := handler .buildSketchCpp .ReadFile (); err == nil {
345
355
handler .sketchMapper = sourcemapper .CreateInoMapper (cppContent )
356
+ handler .sketchMapper .CppText .Version = currCppTextVersion + 1
346
357
} else {
347
358
return errors .WithMessage (err , "reading generated cpp file from sketch" )
348
359
}
349
360
350
- clangdStdout , clangdStdin , clangdStderr := startClangd (handler .buildPath , handler .buildSketchCpp )
351
- clangdStdio := streams .NewReadWriteCloser (clangdStdin , clangdStdout )
352
- if enableLogging {
353
- clangdStdio = streams .LogReadWriteCloserAs (clangdStdio , "inols-clangd.log" )
354
- go io .Copy (streams .OpenLogFileAs ("inols-clangd-err.log" ), clangdStderr )
361
+ if params == nil {
362
+ // If we are restarting re-synchronize clangd
363
+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
364
+ defer cancel ()
365
+
366
+ cppURI := lsp .NewDocumenteURIFromPath (handler .buildSketchCpp )
367
+ cppTextDocumentIdentifier := lsp.TextDocumentIdentifier {URI : cppURI }
368
+
369
+ syncEvent := & lsp.DidChangeTextDocumentParams {
370
+ TextDocument : lsp.VersionedTextDocumentIdentifier {
371
+ TextDocumentIdentifier : cppTextDocumentIdentifier ,
372
+ Version : handler .sketchMapper .CppText .Version ,
373
+ },
374
+ ContentChanges : []lsp.TextDocumentContentChangeEvent {
375
+ {Text : handler .sketchMapper .CppText .Text }, // Full text change
376
+ },
377
+ }
378
+
379
+ if err := handler .ClangdConn .Notify (ctx , "textDocument/didChange" , syncEvent ); err != nil {
380
+ log .Println (" error reinitilizing clangd:" , err )
381
+ return err
382
+ }
355
383
} else {
356
- go io .Copy (os .Stderr , clangdStderr )
357
- }
384
+ // Otherwise start clangd!
385
+ clangdStdout , clangdStdin , clangdStderr := startClangd (handler .buildPath , handler .buildSketchCpp )
386
+ clangdStdio := streams .NewReadWriteCloser (clangdStdin , clangdStdout )
387
+ if enableLogging {
388
+ clangdStdio = streams .LogReadWriteCloserAs (clangdStdio , "inols-clangd.log" )
389
+ go io .Copy (streams .OpenLogFileAs ("inols-clangd-err.log" ), clangdStderr )
390
+ } else {
391
+ go io .Copy (os .Stderr , clangdStderr )
392
+ }
358
393
359
- clangdStream := jsonrpc2 .NewBufferedStream (clangdStdio , jsonrpc2.VSCodeObjectCodec {})
360
- clangdHandler := jsonrpc2 .AsyncHandler (jsonrpc2 .HandlerWithError (handler .FromClangd ))
361
- handler .ClangdConn = jsonrpc2 .NewConn (context .Background (), clangdStream , clangdHandler )
394
+ clangdStream := jsonrpc2 .NewBufferedStream (clangdStdio , jsonrpc2.VSCodeObjectCodec {})
395
+ clangdHandler := jsonrpc2 .AsyncHandler (jsonrpc2 .HandlerWithError (handler .FromClangd ))
396
+ handler .ClangdConn = jsonrpc2 .NewConn (context .Background (), clangdStream , clangdHandler )
397
+ }
362
398
363
399
return nil
364
400
}
@@ -483,6 +519,7 @@ func (handler *InoHandler) didChange(ctx context.Context, req *lsp.DidChangeText
483
519
// and trigger arduino-preprocessing + clangd restart.
484
520
485
521
log .Println (" uh oh DIRTY CHANGE!" )
522
+ handler .scheduleRebuildEnvironment ()
486
523
}
487
524
488
525
// log.Println("New version:----------")
0 commit comments