@@ -146,6 +146,32 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
146146 log .Printf (" --> didOpen(%s@%d as '%s')" , res .TextDocument .URI , res .TextDocument .Version , p .TextDocument .LanguageID )
147147 params = res
148148
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+
149175 case * lsp.CompletionParams :
150176 // method: "textDocument/completion"
151177 uri = p .TextDocument .URI
@@ -163,10 +189,6 @@ func (handler *InoHandler) HandleMessageFromIDE(ctx context.Context, conn *jsonr
163189 err = handler .ino2cppTextDocumentPositionParams (doc )
164190 log .Printf (" --> hover(%s:%d:%d)\n " , doc .TextDocument .URI , doc .Position .Line , doc .Position .Character )
165191
166- case * lsp.DidChangeTextDocumentParams : // "textDocument/didChange":
167- log .Printf ("UNHANDLED " + req .Method )
168- uri = p .TextDocument .URI
169- err = handler .ino2cppDidChangeTextDocumentParams (ctx , p )
170192 case * lsp.DidSaveTextDocumentParams : // "textDocument/didSave":
171193 log .Printf ("UNHANDLED " + req .Method )
172194 uri = p .TextDocument .URI
@@ -377,6 +399,69 @@ func (handler *InoHandler) didOpen(ctx context.Context, params *lsp.DidOpenTextD
377399 return nil , nil
378400}
379401
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+
380465func (handler * InoHandler ) updateFileData (ctx context.Context , data * FileData , change * lsp.TextDocumentContentChangeEvent ) (err error ) {
381466 rang := change .Range
382467 if rang == nil || rang .Start .Line != rang .End .Line {
@@ -496,21 +581,6 @@ func (handler *InoHandler) sketchToBuildPathTextDocumentIdentifier(doc *lsp.Text
496581 return nil
497582}
498583
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-
514584func (handler * InoHandler ) ino2cppTextDocumentPositionParams (params * lsp.TextDocumentPositionParams ) error {
515585 sourceURI := params .TextDocument .URI
516586 if strings .HasSuffix (string (sourceURI ), ".ino" ) {
0 commit comments