diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index fe86a79a..604fe8f2 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -1,6 +1,5 @@ #include "CodeController.h" -#include #include #include "Application.h" @@ -538,6 +537,7 @@ void CodeController::handleMessage(MessageToNextCodeReference* message) { FilePath currentFilePath = message->filePath; size_t currentLineNumber = message->lineNumber; + size_t currentColumnNumber = message->columnNumber; bool next = message->next; bool inListMode = getView()->isInListMode(); @@ -547,9 +547,9 @@ void CodeController::handleMessage(MessageToNextCodeReference* message) } std::pair referencePos = findClosestReferenceIndex( - m_references, currentFilePath, currentLineNumber, next); + m_references, currentFilePath, currentLineNumber, currentColumnNumber, next); std::pair localReferencePos = findClosestReferenceIndex( - m_localReferences, currentFilePath, currentLineNumber, next); + m_localReferences, currentFilePath, currentLineNumber, currentColumnNumber, next); int referenceIndex = referencePos.first; int referenceFileIndex = referencePos.second; @@ -576,18 +576,29 @@ void CodeController::handleMessage(MessageToNextCodeReference* message) } else if (referenceFileIndex == 0) { - if (std::abs( - static_cast(m_references[referenceIndex].lineNumber) - - static_cast(currentLineNumber)) < - std::abs( - static_cast(m_localReferences[localReferenceIndex].lineNumber) - - static_cast(currentLineNumber))) + if (m_references[referenceIndex].lineNumber == m_localReferences[localReferenceIndex].lineNumber) { - localReferenceIndex = -1; + if ((next && m_references[referenceIndex].columnNumber < m_localReferences[localReferenceIndex].columnNumber) || + (!next && m_references[referenceIndex].columnNumber > m_localReferences[localReferenceIndex].columnNumber)) + { + localReferenceIndex = -1; + } + else + { + referenceIndex = -1; + } } else { - referenceIndex = -1; + if ((next && m_references[referenceIndex].lineNumber < m_localReferences[localReferenceIndex].lineNumber) || + (!next && m_references[referenceIndex].lineNumber > m_localReferences[localReferenceIndex].lineNumber)) + { + localReferenceIndex = -1; + } + else + { + referenceIndex = -1; + } } } else @@ -1005,6 +1016,7 @@ void CodeController::createReferences() ref.locationId = location->getLocationId(); ref.locationType = location->getType(); ref.lineNumber = location->getLineNumber(); + ref.columnNumber = location->getColumnNumber(); m_references.push_back(ref); return; } @@ -1017,6 +1029,7 @@ void CodeController::createReferences() ref.locationId = location->getLocationId(); ref.locationType = location->getType(); ref.lineNumber = location->getLineNumber(); + ref.columnNumber = location->getColumnNumber(); std::map::const_iterator it = scopeLocationIds.find(i); if (it != scopeLocationIds.end()) @@ -1055,6 +1068,7 @@ void CodeController::createLocalReferences(const std::set& localSymbolIds) ref.locationId = location->getLocationId(); ref.locationType = location->getType(); ref.lineNumber = location->getLineNumber(); + ref.columnNumber = location->getColumnNumber(); m_localReferences.push_back(ref); return; } @@ -1171,6 +1185,7 @@ std::pair CodeController::findClosestReferenceIndex( const std::vector& references, const FilePath& currentFilePath, size_t currentLineNumber, + size_t currentColumnNumber, bool next) const { int referenceIndex = -1; @@ -1182,7 +1197,8 @@ std::pair CodeController::findClosestReferenceIndex( { if (!next) { - if (references[i].lineNumber < currentLineNumber) + if (references[i].lineNumber < currentLineNumber || + (references[i].lineNumber == currentLineNumber && references[i].columnNumber < currentColumnNumber)) { referenceIndex = static_cast(i); } @@ -1191,7 +1207,8 @@ std::pair CodeController::findClosestReferenceIndex( return {referenceIndex, beforeCurrentFile ? -1 : 0}; } } - else if (references[i].lineNumber > currentLineNumber) + else if (references[i].lineNumber > currentLineNumber || + (references[i].lineNumber == currentLineNumber && references[i].columnNumber > currentColumnNumber)) { return {static_cast(i), 0}; } @@ -1215,7 +1232,13 @@ std::pair CodeController::findClosestReferenceIndex( } } - return {referenceIndex, beforeCurrentFile ? -1 : 1}; + int fileIndex = beforeCurrentFile ? -1 : 1; + if (referenceIndex >= 0 && references[referenceIndex].filePath == currentFilePath) + { + fileIndex = 0; + } + + return {referenceIndex, fileIndex}; } void CodeController::expandVisibleFiles(bool useSingleFileCache) diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index 29c62154..3b857458 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -82,6 +82,7 @@ private: Id scopeLocationId = 0; LocationType locationType = LOCATION_TOKEN; size_t lineNumber = 0; + size_t columnNumber = 0; }; void handleMessage(MessageActivateErrors* message) override; @@ -147,6 +148,7 @@ private: const std::vector& references, const FilePath& currentFilePath, size_t currentLineNumber, + size_t currentColumnNumber, bool next) const; void expandVisibleFiles(bool useSingleFileCache); diff --git a/src/lib/utility/messaging/type/code/MessageToNextCodeReference.h b/src/lib/utility/messaging/type/code/MessageToNextCodeReference.h index a635f47c..732719fd 100644 --- a/src/lib/utility/messaging/type/code/MessageToNextCodeReference.h +++ b/src/lib/utility/messaging/type/code/MessageToNextCodeReference.h @@ -7,8 +7,8 @@ class MessageToNextCodeReference: public Message { public: - MessageToNextCodeReference(const FilePath& filePath, size_t lineNumber, bool next) - : filePath(filePath), lineNumber(lineNumber), next(next) + MessageToNextCodeReference(const FilePath& filePath, size_t lineNumber, size_t columnNumber, bool next) + : filePath(filePath), lineNumber(lineNumber), columnNumber(columnNumber), next(next) { setSchedulerId(TabId::currentTab()); } @@ -20,7 +20,7 @@ public: virtual void print(std::wostream& os) const { - os << filePath.wstr() << L' ' << lineNumber << L' '; + os << filePath.wstr() << L' ' << lineNumber << L':' << columnNumber << L' '; if (next) { @@ -34,6 +34,7 @@ public: const FilePath filePath; const size_t lineNumber; + const size_t columnNumber; const bool next; }; diff --git a/src/lib_gui/qt/element/code/CodeFocusHandler.cpp b/src/lib_gui/qt/element/code/CodeFocusHandler.cpp index edcda969..d03f284d 100644 --- a/src/lib_gui/qt/element/code/CodeFocusHandler.cpp +++ b/src/lib_gui/qt/element/code/CodeFocusHandler.cpp @@ -82,24 +82,24 @@ bool CodeFocusHandler::hasCurrentFocus() const } void CodeFocusHandler::setFocusedLocationId( - QtCodeArea* area, size_t lineNumber, size_t columnNumber, Id locationId, const std::vector& tokenIds, bool fromMouse) + QtCodeArea* area, size_t lineNumber, size_t columnNumber, Id locationId, const std::vector& tokenIds, bool updateTargetColumn, bool fromMouse) { - if (columnNumber) + if (updateTargetColumn) { m_targetColumn = columnNumber; } - setCurrentFocus({nullptr, area, nullptr, lineNumber, locationId, tokenIds}, fromMouse); + setCurrentFocus({nullptr, area, nullptr, lineNumber, columnNumber, locationId, tokenIds}, fromMouse); } void CodeFocusHandler::setFocusedScopeLine(QtCodeArea* area, QPushButton* scopeLine, size_t lineNumber) { - setCurrentFocus({nullptr, area, scopeLine, lineNumber, 0, {}}, false); + setCurrentFocus({nullptr, area, scopeLine, lineNumber, 0, 0, {}}, false); } void CodeFocusHandler::setFocusedFile(QtCodeFile* file) { - setCurrentFocus({file, nullptr, nullptr, 0, 0, {}}, false); + setCurrentFocus({file, nullptr, nullptr, 0, 0, 0, {}}, false); } size_t CodeFocusHandler::getTargetColumn() const diff --git a/src/lib_gui/qt/element/code/CodeFocusHandler.h b/src/lib_gui/qt/element/code/CodeFocusHandler.h index bb5cbe1c..9ffa4c33 100644 --- a/src/lib_gui/qt/element/code/CodeFocusHandler.h +++ b/src/lib_gui/qt/element/code/CodeFocusHandler.h @@ -26,6 +26,7 @@ public: QtCodeArea* area = nullptr; QPushButton* scopeLine = nullptr; size_t lineNumber = 0; + size_t columnNumber = 0; Id locationId = 0; std::vector tokenIds; @@ -52,6 +53,7 @@ public: size_t columnNumber, Id locationId, const std::vector& tokenIds, + bool updateTargetColumn, bool fromMouse); void setFocusedScopeLine(QtCodeArea* area, QPushButton* scopeLine, size_t lineNumber); void setFocusedFile(QtCodeFile* file); diff --git a/src/lib_gui/qt/element/code/QtCodeArea.cpp b/src/lib_gui/qt/element/code/QtCodeArea.cpp index efa23052..28803d3e 100644 --- a/src/lib_gui/qt/element/code/QtCodeArea.cpp +++ b/src/lib_gui/qt/element/code/QtCodeArea.cpp @@ -356,6 +356,19 @@ std::pair QtCodeArea::getLineNumbersForLocationId(Id locationId) return std::pair(0, 0); } +size_t QtCodeArea::getColumnNumberForLocationId(Id locationId) const +{ + for (const Annotation& annotation: m_annotations) + { + if (annotation.locationId == locationId) + { + return annotation.startCol + 1; + } + } + + return 0; +} + Id QtCodeArea::getLocationIdOfFirstActiveLocation(Id tokenId) const { for (const Annotation& annotation: m_annotations) @@ -1048,9 +1061,10 @@ void QtCodeArea::focusAnnotation(const Annotation* annotation, bool updateTarget m_navigator->setFocusedLocationId( this, annotation->startLine, - updateTargetColumn ? annotation->startCol : 0, + annotation->startCol + 1, annotation->locationId, utility::toVector(annotation->tokenIds), + updateTargetColumn, fromMouse); } diff --git a/src/lib_gui/qt/element/code/QtCodeArea.h b/src/lib_gui/qt/element/code/QtCodeArea.h index b39de503..b7a180dd 100644 --- a/src/lib_gui/qt/element/code/QtCodeArea.h +++ b/src/lib_gui/qt/element/code/QtCodeArea.h @@ -72,6 +72,7 @@ public: size_t getLineNumberForLocationId(Id locationId) const; std::pair getLineNumbersForLocationId(Id locationId) const; + size_t getColumnNumberForLocationId(Id locationId) const; Id getLocationIdOfFirstActiveLocation(Id tokenId) const; Id getLocationIdOfFirstActiveScopeLocation(Id tokenId) const; diff --git a/src/lib_gui/qt/element/code/QtCodeFileList.cpp b/src/lib_gui/qt/element/code/QtCodeFileList.cpp index 0db1b542..0ee37743 100644 --- a/src/lib_gui/qt/element/code/QtCodeFileList.cpp +++ b/src/lib_gui/qt/element/code/QtCodeFileList.cpp @@ -299,7 +299,8 @@ void QtCodeFileList::scrollTo( if (focusTarget) { - m_navigator->setFocusedLocationId(snippet->getArea(), lineNumber, 0, locationId, {}, false); + m_navigator->setFocusedLocationId(snippet->getArea(), lineNumber, + snippet->getArea()->getColumnNumberForLocationId(locationId), locationId, {}, false, false); } } diff --git a/src/lib_gui/qt/element/code/QtCodeFileSingle.cpp b/src/lib_gui/qt/element/code/QtCodeFileSingle.cpp index 27d6cfa6..0581d331 100644 --- a/src/lib_gui/qt/element/code/QtCodeFileSingle.cpp +++ b/src/lib_gui/qt/element/code/QtCodeFileSingle.cpp @@ -217,7 +217,8 @@ void QtCodeFileSingle::scrollTo( if (focusTarget && locationId) { - m_navigator->setFocusedLocationId(m_area, lineNumber, 0, locationId, {}, false); + m_navigator->setFocusedLocationId(m_area, lineNumber, m_area->getColumnNumberForLocationId(locationId), + locationId, {}, false, false); } } diff --git a/src/lib_gui/qt/element/code/QtCodeNavigator.cpp b/src/lib_gui/qt/element/code/QtCodeNavigator.cpp index c36af3f2..db21ef61 100644 --- a/src/lib_gui/qt/element/code/QtCodeNavigator.cpp +++ b/src/lib_gui/qt/element/code/QtCodeNavigator.cpp @@ -703,60 +703,48 @@ void QtCodeNavigator::keyPressEvent(QKeyEvent* event) currentFilePath = currentFocus.area->getFilePath(); } + auto moveFocus = [=](CodeFocusHandler::Direction direction) { + if (!alt && !ctrl) + { + if (shift) + { + MessageToNextCodeReference( + currentFilePath, currentFocus.lineNumber, currentFocus.columnNumber, + direction == CodeFocusHandler::Direction::DOWN || direction == CodeFocusHandler::Direction::RIGHT + ).dispatch(); + } + else + { + m_current->moveFocus(currentFocus, direction); + scrollToFocus(); + } + } + }; + switch (event->key()) { case Qt::Key_Up: case Qt::Key_K: case Qt::Key_W: - if (!alt && !ctrl) - { - if (shift) - { - MessageToNextCodeReference(currentFilePath, currentFocus.lineNumber, false).dispatch(); - } - else - { - m_current->moveFocus(currentFocus, CodeFocusHandler::Direction::UP); - scrollToFocus(); - } - } + moveFocus(CodeFocusHandler::Direction::UP); break; case Qt::Key_Down: case Qt::Key_J: case Qt::Key_S: - if (!alt && !ctrl) - { - if (shift) - { - MessageToNextCodeReference(currentFilePath, currentFocus.lineNumber, true).dispatch(); - } - else - { - m_current->moveFocus(currentFocus, CodeFocusHandler::Direction::DOWN); - scrollToFocus(); - } - } + moveFocus(CodeFocusHandler::Direction::DOWN); break; case Qt::Key_Left: case Qt::Key_H: case Qt::Key_A: - if (!alt && !ctrl) - { - m_current->moveFocus(currentFocus, CodeFocusHandler::Direction::LEFT); - scrollToFocus(); - } + moveFocus(CodeFocusHandler::Direction::LEFT); break; case Qt::Key_Right: case Qt::Key_L: case Qt::Key_D: - if (!alt && !ctrl) - { - m_current->moveFocus(currentFocus, CodeFocusHandler::Direction::RIGHT); - scrollToFocus(); - } + moveFocus(CodeFocusHandler::Direction::RIGHT); break; case Qt::Key_E: diff --git a/src/lib_gui/qt/window/QtKeyboardShortcuts.cpp b/src/lib_gui/qt/window/QtKeyboardShortcuts.cpp index a294ad5a..f562749a 100644 --- a/src/lib_gui/qt/window/QtKeyboardShortcuts.cpp +++ b/src/lib_gui/qt/window/QtKeyboardShortcuts.cpp @@ -222,7 +222,7 @@ QTableWidget* QtKeyboardShortcuts::createCodeViewShortcutsTable() {Shortcut(QStringLiteral("Move Focus Within Code"), QStringLiteral("WASD | HJKL | Arrows")), Shortcut( QStringLiteral("Move Focus to Closest Reference"), - QStringLiteral("Shift + WS | Shift + JK | Shift + Up/Down")), + QStringLiteral("Shift + WASD | Shift + HJKL | Shift + Arrows")), Shortcut(QStringLiteral("Activate Focused Location"), QStringLiteral("Enter | E")), Shortcut::defaultOrMac( QStringLiteral("Activate Location in New Tab"),