Skip to content

Commit 039617b

Browse files
committed
first implementation of textDocument/didChange
1 parent 8d099f9 commit 039617b

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

Diff for: handler/handler.go

+89-19
Original file line numberDiff line numberDiff line change
@@ -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+
380465
func (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-
514584
func (handler *InoHandler) ino2cppTextDocumentPositionParams(params *lsp.TextDocumentPositionParams) error {
515585
sourceURI := params.TextDocument.URI
516586
if strings.HasSuffix(string(sourceURI), ".ino") {

0 commit comments

Comments
 (0)