forked from qt-creator/qt-creator
LanguageClient: send partial document in update notification
Reduce the amount of transferred data between client and server by sending events which just contain the changed part of the document instead of the full content if the server supports those events. Change-Id: I596930c405bd7a71e4219e328b449fca67664750 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -83,7 +83,7 @@ public:
|
|||||||
void setTextDocument(const VersionedTextDocumentIdentifier &textDocument)
|
void setTextDocument(const VersionedTextDocumentIdentifier &textDocument)
|
||||||
{ insert(textDocumentKey, textDocument); }
|
{ insert(textDocumentKey, textDocument); }
|
||||||
|
|
||||||
class TextDocumentContentChangeEvent : public JsonObject
|
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentContentChangeEvent : public JsonObject
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* An event describing a change to a text document. If range and rangeLength are omitted
|
* An event describing a change to a text document. If range and rangeLength are omitted
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ Client::~Client()
|
|||||||
}
|
}
|
||||||
for (const DocumentUri &uri : m_diagnostics.keys())
|
for (const DocumentUri &uri : m_diagnostics.keys())
|
||||||
removeDiagnostics(uri);
|
removeDiagnostics(uri);
|
||||||
updateEditorToolBar(m_openedDocument);
|
updateEditorToolBar(m_openedDocument.keys());
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClientCapabilities generateClientCapabilities()
|
static ClientCapabilities generateClientCapabilities()
|
||||||
@@ -287,11 +287,13 @@ bool Client::openDocument(Core::IDocument *document)
|
|||||||
item.setText(QString::fromUtf8(document->contents()));
|
item.setText(QString::fromUtf8(document->contents()));
|
||||||
item.setVersion(textDocument ? textDocument->document()->revision() : 0);
|
item.setVersion(textDocument ? textDocument->document()->revision() : 0);
|
||||||
|
|
||||||
connect(document, &Core::IDocument::contentsChanged, this,
|
|
||||||
[this, document](){
|
|
||||||
documentContentsChanged(document);
|
|
||||||
});
|
|
||||||
if (textDocument) {
|
if (textDocument) {
|
||||||
|
connect(textDocument,
|
||||||
|
&TextEditor::TextDocument::contentsChangedWithPosition,
|
||||||
|
this,
|
||||||
|
[this, textDocument](int position, int charsRemoved, int charsAdded) {
|
||||||
|
documentContentsChanged(textDocument, position, charsRemoved, charsAdded);
|
||||||
|
});
|
||||||
textDocument->completionAssistProvider();
|
textDocument->completionAssistProvider();
|
||||||
m_resetAssistProvider << textDocument;
|
m_resetAssistProvider << textDocument;
|
||||||
m_completionProvider.setTriggerCharacters(
|
m_completionProvider.setTriggerCharacters(
|
||||||
@@ -304,9 +306,11 @@ bool Client::openDocument(Core::IDocument *document)
|
|||||||
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
|
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
|
||||||
m_resetAssistProvider.remove(textDocument);
|
m_resetAssistProvider.remove(textDocument);
|
||||||
});
|
});
|
||||||
|
m_openedDocument.insert(document->filePath(), textDocument->plainText());
|
||||||
|
} else {
|
||||||
|
m_openedDocument.insert(document->filePath(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_openedDocument.append(document->filePath());
|
|
||||||
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
|
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
|
||||||
if (textDocument)
|
if (textDocument)
|
||||||
requestDocumentSymbols(textDocument);
|
requestDocumentSymbols(textDocument);
|
||||||
@@ -410,7 +414,10 @@ void Client::documentWillSave(Core::IDocument *document)
|
|||||||
sendContent(WillSaveTextDocumentNotification(params));
|
sendContent(WillSaveTextDocumentNotification(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::documentContentsChanged(Core::IDocument *document)
|
void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||||
|
int position,
|
||||||
|
int charsRemoved,
|
||||||
|
int charsAdded)
|
||||||
{
|
{
|
||||||
if (!m_openedDocument.contains(document->filePath()))
|
if (!m_openedDocument.contains(document->filePath()))
|
||||||
return;
|
return;
|
||||||
@@ -430,7 +437,21 @@ void Client::documentContentsChanged(Core::IDocument *document)
|
|||||||
const auto uri = DocumentUri::fromFileName(document->filePath());
|
const auto uri = DocumentUri::fromFileName(document->filePath());
|
||||||
VersionedTextDocumentIdentifier docId(uri);
|
VersionedTextDocumentIdentifier docId(uri);
|
||||||
docId.setVersion(textDocument ? textDocument->document()->revision() : 0);
|
docId.setVersion(textDocument ? textDocument->document()->revision() : 0);
|
||||||
const DidChangeTextDocumentParams params(docId, QString::fromUtf8(document->contents()));
|
DidChangeTextDocumentParams params;
|
||||||
|
params.setTextDocument(docId);
|
||||||
|
if (syncKind == TextDocumentSyncKind::Incremental) {
|
||||||
|
DidChangeTextDocumentParams::TextDocumentContentChangeEvent change;
|
||||||
|
QTextDocument oldDoc(m_openedDocument[document->filePath()]);
|
||||||
|
QTextCursor cursor(&oldDoc);
|
||||||
|
cursor.setPosition(position + charsRemoved);
|
||||||
|
cursor.setPosition(position, QTextCursor::KeepAnchor);
|
||||||
|
change.setRange(Range(cursor));
|
||||||
|
change.setText(document->textAt(position, charsAdded));
|
||||||
|
params.setContentChanges({change});
|
||||||
|
} else {
|
||||||
|
params.setContentChanges({document->plainText()});
|
||||||
|
}
|
||||||
|
m_openedDocument[document->filePath()] = document->plainText();
|
||||||
sendContent(DidChangeTextDocumentNotification(params));
|
sendContent(DidChangeTextDocumentNotification(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,7 +851,7 @@ bool Client::reset()
|
|||||||
m_state = Uninitialized;
|
m_state = Uninitialized;
|
||||||
m_responseHandlers.clear();
|
m_responseHandlers.clear();
|
||||||
m_clientInterface->resetBuffer();
|
m_clientInterface->resetBuffer();
|
||||||
updateEditorToolBar(m_openedDocument);
|
updateEditorToolBar(m_openedDocument.keys());
|
||||||
m_openedDocument.clear();
|
m_openedDocument.clear();
|
||||||
m_serverCapabilities = ServerCapabilities();
|
m_serverCapabilities = ServerCapabilities();
|
||||||
m_dynamicCapabilities.reset();
|
m_dynamicCapabilities.reset();
|
||||||
|
|||||||
@@ -96,7 +96,10 @@ public:
|
|||||||
bool documentOpen(const Core::IDocument *document) const;
|
bool documentOpen(const Core::IDocument *document) const;
|
||||||
void documentContentsSaved(Core::IDocument *document);
|
void documentContentsSaved(Core::IDocument *document);
|
||||||
void documentWillSave(Core::IDocument *document);
|
void documentWillSave(Core::IDocument *document);
|
||||||
void documentContentsChanged(Core::IDocument *document);
|
void documentContentsChanged(TextEditor::TextDocument *document,
|
||||||
|
int position,
|
||||||
|
int charsRemoved,
|
||||||
|
int charsAdded);
|
||||||
void registerCapabilities(const QList<LanguageServerProtocol::Registration> ®istrations);
|
void registerCapabilities(const QList<LanguageServerProtocol::Registration> ®istrations);
|
||||||
void unregisterCapabilities(const QList<LanguageServerProtocol::Unregistration> &unregistrations);
|
void unregisterCapabilities(const QList<LanguageServerProtocol::Unregistration> &unregistrations);
|
||||||
bool findLinkAt(LanguageServerProtocol::GotoDefinitionRequest &request);
|
bool findLinkAt(LanguageServerProtocol::GotoDefinitionRequest &request);
|
||||||
@@ -190,7 +193,7 @@ private:
|
|||||||
QHash<QByteArray, ContentHandler> m_contentHandler;
|
QHash<QByteArray, ContentHandler> m_contentHandler;
|
||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
LanguageFilter m_languagFilter;
|
LanguageFilter m_languagFilter;
|
||||||
QList<Utils::FileName> m_openedDocument;
|
QMap<Utils::FileName, QString> m_openedDocument;
|
||||||
Core::Id m_id;
|
Core::Id m_id;
|
||||||
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
||||||
DynamicCapabilities m_dynamicCapabilities;
|
DynamicCapabilities m_dynamicCapabilities;
|
||||||
|
|||||||
Reference in New Issue
Block a user