ui: Iterate code references within the same line when holding Shift (#936)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#include "CodeController.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#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<int, int> referencePos = findClosestReferenceIndex(
|
||||
m_references, currentFilePath, currentLineNumber, next);
|
||||
m_references, currentFilePath, currentLineNumber, currentColumnNumber, next);
|
||||
std::pair<int, int> 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<int>(m_references[referenceIndex].lineNumber) -
|
||||
static_cast<int>(currentLineNumber)) <
|
||||
std::abs(
|
||||
static_cast<int>(m_localReferences[localReferenceIndex].lineNumber) -
|
||||
static_cast<int>(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<Id, Id>::const_iterator it = scopeLocationIds.find(i);
|
||||
if (it != scopeLocationIds.end())
|
||||
@@ -1055,6 +1068,7 @@ void CodeController::createLocalReferences(const std::set<Id>& 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<int, int> CodeController::findClosestReferenceIndex(
|
||||
const std::vector<Reference>& references,
|
||||
const FilePath& currentFilePath,
|
||||
size_t currentLineNumber,
|
||||
size_t currentColumnNumber,
|
||||
bool next) const
|
||||
{
|
||||
int referenceIndex = -1;
|
||||
@@ -1182,7 +1197,8 @@ std::pair<int, int> 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<int>(i);
|
||||
}
|
||||
@@ -1191,7 +1207,8 @@ std::pair<int, int> 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<int>(i), 0};
|
||||
}
|
||||
@@ -1215,7 +1232,13 @@ std::pair<int, int> 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)
|
||||
|
||||
@@ -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<Reference>& references,
|
||||
const FilePath& currentFilePath,
|
||||
size_t currentLineNumber,
|
||||
size_t currentColumnNumber,
|
||||
bool next) const;
|
||||
|
||||
void expandVisibleFiles(bool useSingleFileCache);
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
class MessageToNextCodeReference: public Message<MessageToNextCodeReference>
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -82,24 +82,24 @@ bool CodeFocusHandler::hasCurrentFocus() const
|
||||
}
|
||||
|
||||
void CodeFocusHandler::setFocusedLocationId(
|
||||
QtCodeArea* area, size_t lineNumber, size_t columnNumber, Id locationId, const std::vector<Id>& tokenIds, bool fromMouse)
|
||||
QtCodeArea* area, size_t lineNumber, size_t columnNumber, Id locationId, const std::vector<Id>& 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
|
||||
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
QtCodeArea* area = nullptr;
|
||||
QPushButton* scopeLine = nullptr;
|
||||
size_t lineNumber = 0;
|
||||
size_t columnNumber = 0;
|
||||
Id locationId = 0;
|
||||
std::vector<Id> tokenIds;
|
||||
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
size_t columnNumber,
|
||||
Id locationId,
|
||||
const std::vector<Id>& tokenIds,
|
||||
bool updateTargetColumn,
|
||||
bool fromMouse);
|
||||
void setFocusedScopeLine(QtCodeArea* area, QPushButton* scopeLine, size_t lineNumber);
|
||||
void setFocusedFile(QtCodeFile* file);
|
||||
|
||||
@@ -356,6 +356,19 @@ std::pair<size_t, size_t> QtCodeArea::getLineNumbersForLocationId(Id locationId)
|
||||
return std::pair<size_t, size_t>(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);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
|
||||
size_t getLineNumberForLocationId(Id locationId) const;
|
||||
std::pair<size_t, size_t> getLineNumbersForLocationId(Id locationId) const;
|
||||
size_t getColumnNumberForLocationId(Id locationId) const;
|
||||
|
||||
Id getLocationIdOfFirstActiveLocation(Id tokenId) const;
|
||||
Id getLocationIdOfFirstActiveScopeLocation(Id tokenId) const;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user