@@ -146,6 +146,32 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
146
146
log .Printf (" --> didOpen(%s@%d as '%s')" , res .TextDocument .URI , res .TextDocument .Version , p .TextDocument .LanguageID )
147
147
params = res
148
148
149
+ case * lsp.DidChangeTextDocumentParams :
150
+ // notification "textDocument/didChange"
151
+ uri = p .TextDocument .URI
152
+ log .Printf ("--> didChange(%s@%d)" , p .TextDocument .URI , p .TextDocument .Version )
153
+ for _ , change := range p .ContentChanges {
154
+ log .Printf (" > %s -> '%s'" , change .Range , strconv .Quote (change .Text ))
155
+ }
156
+
157
+ res , err := handler .didChange (ctx , p )
158
+ if err != nil {
159
+ log .Printf (" --E error: %s" , err )
160
+ return nil , err
161
+ }
162
+ if res == nil {
163
+ log .Println (" --X notification is not propagated to clangd" )
164
+ return nil , err // do not propagate to clangd
165
+ }
166
+
167
+ p = res
168
+ log .Printf (" --> didChange(%s@%d)" , p .TextDocument .URI , p .TextDocument .Version )
169
+ for _ , change := range p .ContentChanges {
170
+ log .Printf (" > %s -> '%s'" , change .Range , strconv .Quote (change .Text ))
171
+ }
172
+ err = handler .ClangdConn .Notify (ctx , req .Method , p )
173
+ return nil , err
174
+
149
175
case * lsp.CompletionParams :
150
176
// method: "textDocument/completion"
151
177
uri = p .TextDocument .URI
@@ -163,10 +189,6 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
163
189
err = handler .ino2cppTextDocumentPositionParams (doc )
164
190
log .Printf (" --> hover(%s:%d:%d)\n " , doc .TextDocument .URI , doc .Position .Line , doc .Position .Character )
165
191
166
- case * lsp.DidChangeTextDocumentParams : // "textDocument/didChange":
167
- log .Printf ("UNHANDLED " + req .Method )
168
- uri = p .TextDocument .URI
169
- err = handler .ino2cppDidChangeTextDocumentParams (ctx , p )
170
192
case * lsp.DidSaveTextDocumentParams : // "textDocument/didSave":
171
193
log .Printf ("UNHANDLED " + req .Method )
172
194
uri = p .TextDocument .URI
@@ -377,6 +399,69 @@ func (handler *InoHandler) didOpen(ctx context.Context, params *lsp.DidOpenTextD
377
399
return nil , nil
378
400
}
379
401
402
+ func (handler * InoHandler ) didChange (ctx context.Context , req * lsp.DidChangeTextDocumentParams ) (* lsp.DidChangeTextDocumentParams , error ) {
403
+ doc := req .TextDocument
404
+
405
+ trackedDoc , ok := handler .trackedFiles [doc .URI ]
406
+ if ! ok {
407
+ return nil , unknownURI (doc .URI )
408
+ }
409
+ if trackedDoc .Version + 1 != doc .Version {
410
+ return nil , errors .Errorf ("document out-of-sync: expected version %d but got %d" , trackedDoc .Version + 1 , doc .Version )
411
+ }
412
+ trackedDoc .Version ++
413
+
414
+ if doc .URI .AsPath ().Ext () == ".ino" {
415
+ // If changes are applied to a .ino file we increment the global .ino.cpp versioning
416
+ // for each increment of the single .ino file.
417
+
418
+ cppChanges := []lsp.TextDocumentContentChangeEvent {}
419
+ for _ , inoChange := range req .ContentChanges {
420
+ dirty := handler .sketchMapper .ApplyTextChange (doc .URI , inoChange )
421
+ if dirty {
422
+ // TODO: Detect changes in critical lines (for example function definitions)
423
+ // and trigger arduino-preprocessing + clangd restart.
424
+
425
+ log .Println (" uh oh DIRTY CHANGE!" )
426
+ }
427
+
428
+ // log.Println("New version:----------")
429
+ // log.Println(handler.sketchMapper.CppText.Text)
430
+ // log.Println("----------------------")
431
+
432
+ cppRange , ok := handler .sketchMapper .InoToCppLSPRangeOk (doc .URI , * inoChange .Range )
433
+ if ! ok {
434
+ return nil , errors .Errorf ("invalid change range %s:%s" , doc .URI , * inoChange .Range )
435
+ }
436
+ cppChange := lsp.TextDocumentContentChangeEvent {
437
+ Range : & cppRange ,
438
+ RangeLength : inoChange .RangeLength ,
439
+ Text : inoChange .Text ,
440
+ }
441
+ cppChanges = append (cppChanges , cppChange )
442
+ }
443
+
444
+ // build a cpp equivalent didChange request
445
+ cppReq := & lsp.DidChangeTextDocumentParams {
446
+ ContentChanges : cppChanges ,
447
+ TextDocument : lsp.VersionedTextDocumentIdentifier {
448
+ TextDocumentIdentifier : lsp.TextDocumentIdentifier {
449
+ URI : lsp .NewDocumenteURIFromPath (handler .buildSketchCpp ),
450
+ },
451
+ Version : handler .sketchMapper .CppText .Version ,
452
+ },
453
+ }
454
+ return cppReq , nil
455
+ } else {
456
+
457
+ // TODO
458
+ return nil , unknownURI (doc .URI )
459
+
460
+ }
461
+
462
+ return nil , unknownURI (doc .URI )
463
+ }
464
+
380
465
func (handler * InoHandler ) updateFileData (ctx context.Context , data * FileData , change * lsp.TextDocumentContentChangeEvent ) (err error ) {
381
466
rang := change .Range
382
467
if rang == nil || rang .Start .Line != rang .End .Line {
@@ -496,21 +581,6 @@ func (handler *InoHandler) sketchToBuildPathTextDocumentIdentifier(doc *lsp.Text
496
581
return nil
497
582
}
498
583
499
- func (handler * InoHandler ) ino2cppDidChangeTextDocumentParams (ctx context.Context , params * lsp.DidChangeTextDocumentParams ) error {
500
- handler .sketchToBuildPathTextDocumentIdentifier (& params .TextDocument .TextDocumentIdentifier )
501
- if data , ok := handler .data [params .TextDocument .URI ]; ok {
502
- for index := range params .ContentChanges {
503
- err := handler .updateFileData (ctx , data , & params .ContentChanges [index ])
504
- if err != nil {
505
- return err
506
- }
507
- }
508
- data .version = params .TextDocument .Version
509
- return nil
510
- }
511
- return unknownURI (params .TextDocument .URI )
512
- }
513
-
514
584
func (handler * InoHandler ) ino2cppTextDocumentPositionParams (params * lsp.TextDocumentPositionParams ) error {
515
585
sourceURI := params .TextDocument .URI
516
586
if strings .HasSuffix (string (sourceURI ), ".ino" ) {
0 commit comments