forked from qt-creator/qt-creator
LanguageClient: avoid creating a QTextDocument for every contents change
clone the document when it is opened and adjust it after each contents change Change-Id: I4fd511a3b142b1875f1da7d241ab5cddf49322e8 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -289,9 +289,10 @@ public:
|
||||
~OpenedDocument()
|
||||
{
|
||||
QObject::disconnect(contentsChangedConnection);
|
||||
delete document;
|
||||
}
|
||||
QMetaObject::Connection contentsChangedConnection;
|
||||
QString documentContents;
|
||||
QTextDocument *document = nullptr;
|
||||
};
|
||||
QMap<TextEditor::TextDocument *, OpenedDocument> m_openedDocument;
|
||||
|
||||
@@ -628,7 +629,7 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
||||
}
|
||||
}
|
||||
|
||||
d->m_openedDocument[document].documentContents = document->plainText();
|
||||
d->m_openedDocument[document].document = document->document()->clone(this);
|
||||
d->m_openedDocument[document].contentsChangedConnection
|
||||
= connect(document,
|
||||
&TextDocument::contentsChangedWithPosition,
|
||||
@@ -1076,6 +1077,19 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||
}
|
||||
}
|
||||
|
||||
const QString &text = document->textAt(position, charsAdded);
|
||||
QTextCursor cursor(d->m_openedDocument[document].document);
|
||||
// Workaround https://bugreports.qt.io/browse/QTBUG-80662
|
||||
// The contentsChanged gives a character count that can be wrong for QTextCursor
|
||||
// when there are special characters removed/added (like formating characters).
|
||||
// Also, characterCount return the number of characters + 1 because of the hidden
|
||||
// paragraph separator character.
|
||||
// This implementation is based on QWidgetTextControlPrivate::_q_contentsChanged.
|
||||
// For charsAdded, textAt handles the case itself.
|
||||
cursor.setPosition(qMin(d->m_openedDocument[document].document->characterCount() - 1,
|
||||
position + charsRemoved));
|
||||
cursor.setPosition(position, QTextCursor::KeepAnchor);
|
||||
|
||||
if (syncKind != TextDocumentSyncKind::None) {
|
||||
if (syncKind == TextDocumentSyncKind::Incremental) {
|
||||
// If the new change is a pure insertion and its range is adjacent to the range of the
|
||||
@@ -1083,7 +1097,6 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||
// For the typical case of the user typing a continuous sequence of characters,
|
||||
// this will save a lot of TextDocumentContentChangeEvent elements in the data stream,
|
||||
// as otherwise we'd send tons of single-character changes.
|
||||
const QString &text = document->textAt(position, charsAdded);
|
||||
auto &queue = d->m_documentsToUpdate[document];
|
||||
bool append = true;
|
||||
if (!queue.isEmpty() && charsRemoved == 0) {
|
||||
@@ -1096,17 +1109,6 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||
}
|
||||
}
|
||||
if (append) {
|
||||
QTextDocument oldDoc(d->m_openedDocument[document].documentContents);
|
||||
QTextCursor cursor(&oldDoc);
|
||||
// Workaround https://bugreports.qt.io/browse/QTBUG-80662
|
||||
// The contentsChanged gives a character count that can be wrong for QTextCursor
|
||||
// when there are special characters removed/added (like formating characters).
|
||||
// Also, characterCount return the number of characters + 1 because of the hidden
|
||||
// paragraph separator character.
|
||||
// This implementation is based on QWidgetTextControlPrivate::_q_contentsChanged.
|
||||
// For charsAdded, textAt handles the case itself.
|
||||
cursor.setPosition(qMin(oldDoc.characterCount() - 1, position + charsRemoved));
|
||||
cursor.setPosition(position, QTextCursor::KeepAnchor);
|
||||
DidChangeTextDocumentParams::TextDocumentContentChangeEvent change;
|
||||
change.setRange(Range(cursor));
|
||||
change.setRangeLength(cursor.selectionEnd() - cursor.selectionStart());
|
||||
@@ -1117,8 +1119,8 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
||||
d->m_documentsToUpdate[document] = {
|
||||
DidChangeTextDocumentParams::TextDocumentContentChangeEvent(document->plainText())};
|
||||
}
|
||||
d->m_openedDocument[document].documentContents = document->plainText();
|
||||
}
|
||||
cursor.insertText(text);
|
||||
|
||||
++d->m_documentVersions[document->filePath()];
|
||||
using namespace TextEditor;
|
||||
|
Reference in New Issue
Block a user