From 9de9da742333d6114b337abf4b64b15aa23afa9f Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 9 Jun 2017 13:36:35 +0200 Subject: [PATCH] CppEditor: Do not start CppUseSelectionsUpdater for same identifier Saves some cycles when navigating with the text cursor over the characters. Change-Id: Ie9a23d97ac09ca45a32178cae5b8945d0c623811 Reviewed-by: Marco Bubke --- .../cppeditor/cppuseselectionsupdater.cpp | 36 ++++++++++++++++--- .../cppeditor/cppuseselectionsupdater.h | 5 +-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.cpp b/src/plugins/cppeditor/cppuseselectionsupdater.cpp index f857f460d30..bc6530fe058 100644 --- a/src/plugins/cppeditor/cppuseselectionsupdater.cpp +++ b/src/plugins/cppeditor/cppuseselectionsupdater.cpp @@ -28,6 +28,8 @@ #include "cppeditor.h" #include "cppeditordocument.h" +#include + #include #include @@ -57,6 +59,23 @@ void CppUseSelectionsUpdater::abortSchedule() m_timer.stop(); } +static QTextCursor cursorAtWordStart(const QTextCursor &textCursor) +{ + const int originalPosition = textCursor.position(); + QTextCursor cursor(textCursor); + cursor.movePosition(QTextCursor::StartOfWord); + const int wordStartPosition = cursor.position(); + + if (originalPosition == wordStartPosition) { + // Cursor is not on an identifier, check whether we are right after one. + const QChar c = textCursor.document()->characterAt(originalPosition - 1); + if (CppTools::isValidIdentifierChar(c)) + cursor.movePosition(QTextCursor::PreviousWord); + } + + return cursor; +} + void CppUseSelectionsUpdater::update(CallType callType) { auto *cppEditorWidget = qobject_cast(m_editorWidget); @@ -67,9 +86,12 @@ void CppUseSelectionsUpdater::update(CallType callType) CppTools::CursorInfoParams params; params.semanticInfo = cppEditorWidget->semanticInfo(); - params.textCursor = cppEditorWidget->textCursor(); + params.textCursor = cursorAtWordStart(cppEditorWidget->textCursor()); if (callType == Asynchronous) { + if (isSameIdentifierAsBefore(params.textCursor)) + return; + if (m_runnerWatcher) m_runnerWatcher->cancel(); @@ -78,7 +100,7 @@ void CppUseSelectionsUpdater::update(CallType callType) this, &CppUseSelectionsUpdater::onFindUsesFinished); m_runnerRevision = m_editorWidget->document()->revision(); - m_runnerCursorPosition = m_editorWidget->position(); + m_runnerWordStartPosition = params.textCursor.position(); m_runnerWatcher->setFuture(cppEditorDocument->cursorInfo(params)); } else { // synchronous case @@ -89,6 +111,13 @@ void CppUseSelectionsUpdater::update(CallType callType) } } +bool CppUseSelectionsUpdater::isSameIdentifierAsBefore(const QTextCursor &cursorAtWordStart) const +{ + return m_runnerRevision != -1 + && m_runnerRevision == m_editorWidget->document()->revision() + && m_runnerWordStartPosition == cursorAtWordStart.position(); +} + void CppUseSelectionsUpdater::processResults(const CursorInfo &result) { ExtraSelections localVariableSelections; @@ -111,8 +140,7 @@ void CppUseSelectionsUpdater::onFindUsesFinished() return; if (m_runnerRevision != m_editorWidget->document()->revision()) return; - // Optimizable: If the cursor is still on the same identifier the results should be valid. - if (m_runnerCursorPosition != m_editorWidget->position()) + if (m_runnerWordStartPosition != cursorAtWordStart(m_editorWidget->textCursor()).position()) return; processResults(m_runnerWatcher->result()); diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.h b/src/plugins/cppeditor/cppuseselectionsupdater.h index 1790bb7efa0..b2474362850 100644 --- a/src/plugins/cppeditor/cppuseselectionsupdater.h +++ b/src/plugins/cppeditor/cppuseselectionsupdater.h @@ -57,6 +57,7 @@ signals: private: CppUseSelectionsUpdater(); + bool isSameIdentifierAsBefore(const QTextCursor &cursorAtWordStart) const; void processResults(const CppTools::CursorInfo &result); void onFindUsesFinished(); @@ -75,8 +76,8 @@ private: QTimer m_timer; QScopedPointer> m_runnerWatcher; - int m_runnerRevision; - int m_runnerCursorPosition; + int m_runnerRevision = -1; + int m_runnerWordStartPosition = -1; }; } // namespace Internal