thur
thur

Reputation: 1074

How to get the entire document text in onDidChangeTextDocument on vscode Language Server implementation?

I want to parse a file allways that the user change it, so I implement the onDidChangeTextDocument method from connection.

But this event just give me the URI and the content changes. How can I get the entiry document?

Obs.: I also tried to implement the onDidChangeContent from documents, but it was never called.

Upvotes: 3

Views: 2739

Answers (3)

蓝月萧枫
蓝月萧枫

Reputation: 1

Usage like for this:

import { TextDocument } from 'vscode-languageserver-textdocument'

const documents = new Map<string, TextDocument>()

connect.onDidOpenTextDocument(e => {
  console.log('onDidOpenTextDocument', e.textDocument.uri)
  const doc = TextDocument.create(e.textDocument.uri, 'api', e.textDocument.version, e.textDocument.text)
  documents.set(e.textDocument.uri, doc)
})

connect.onDidCloseTextDocument(e => {
    console.info('onDidCloseTextDocument', e)
  documents.delete(e.textDocument.uri)
})

connect.onDidChangeTextDocument(e => {
    console.log('onDidChangeTextDocument', JSON.stringify(e.contentChanges))
  const doc = documents.get(e.textDocument.uri)
  TextDocument.update(doc, e.contentChanges, e.textDocument.version)
})

Upvotes: 0

Mike Lischke
Mike Lischke

Reputation: 53347

The document is in the event passed in to onDidChangeTextDocument. This is how I handle it:

var changeTimeout;
vscode.workspace.onDidChangeTextDocument(function (event) {
    if (changeTimeout != null)
        clearTimeout(changeTimeout);
    changeTimeout = setInterval(function () {
        clearTimeout(changeTimeout);
        changeTimeout = null;
        backend.reparse(event.document.fileName, event.document.getText());
        processDiagnostic(event.document);
    }, 500);
});

This is what MS writes in the documentation:

// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent((change) => {
    let diagnostics: Diagnostic[] = [];
    let lines = change.document.getText().split(/\r?\n/g);
    lines.forEach((line, i) => {
        let index = line.indexOf('typescript');
        if (index >= 0) {
            diagnostics.push({
                severity: DiagnosticSeverity.Warning,
                range: {
                    start: { line: i, character: index},
                    end: { line: i, character: index + 10 }
                },
                message: `${line.substr(index, 10)} should be spelled TypeScript`,
                source: 'ex'
            });
        }
    })
    // Send the computed diagnostics to VS Code.
    connection.sendDiagnostics({ uri: change.document.uri, diagnostics });
});

so the document (and so the text) should be available in the event.

Upvotes: 5

Theadd
Theadd

Reputation: 38

Obs.: I also tried to implement the onDidChangeContent from documents, but it was never called.

What I wonder is why onDidChangeContent stops being called when using any of those: onDidChangeTextDocument, onDidOpenTextDocument, onDidCloseTextDocument. It seems we can only use one way or the other.

So, what you're looking for is this:

documents.onDidChangeContent(change => {
  connection.console.log(change.document.getText())
})

All change.document members: uri,languageId,version,getText,update,getLineOffsets,positionAt,offsetAt,lineCount

Upvotes: 1

Related Questions