ui: snippet sizes
* added SnippetMerger class that conducts the merging and snapping of TokenLocations to create snippets. * added parameters for snippet snapping and merging to ApplicationSettings. * added forEachStartTokenLocation() and forEachEndTokenLocation() to TokenLocationLine and TokenLocationFile. * added < and > operators to TokenLocation that compare the location part (not the id).
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationCollection.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
CodeController::CodeController(StorageAccess* storageAccess)
|
||||
@@ -29,12 +30,13 @@ void CodeController::handleMessage(MessageActivateTokenLocation* message)
|
||||
void CodeController::handleMessage(MessageActivateTokens* message)
|
||||
{
|
||||
std::vector<Id> activeTokenIds = message->tokenIds;
|
||||
Id declarationId = 0;
|
||||
Id declarationId = 0; // 0 means that no token is found.
|
||||
|
||||
if (activeTokenIds.size() == 1)
|
||||
{
|
||||
activeTokenIds = m_storageAccess->getActiveTokenIdsForId(activeTokenIds[0], &declarationId);
|
||||
}
|
||||
// TODO: what about declarationId if more than 1 token is active? FIX THIS!
|
||||
|
||||
CodeView* view = getView();
|
||||
view->setActiveTokenIds(activeTokenIds);
|
||||
@@ -144,24 +146,37 @@ std::vector<CodeView::CodeSnippetParams> CodeController::getSnippetsForFile(cons
|
||||
{
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(file->getFilePath().str());
|
||||
|
||||
std::vector<std::pair<uint, uint>> ranges;
|
||||
std::deque<SnippetMerger::Range> ranges;
|
||||
|
||||
if (file->isWholeCopy)
|
||||
{
|
||||
ranges.push_back(std::make_pair(1, textAccess->getLineCount()));
|
||||
ranges.push_back(SnippetMerger::Range(
|
||||
SnippetMerger::Border(1, true),
|
||||
SnippetMerger::Border(textAccess->getLineCount(), true)
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
ranges = getSnippetRangesForFile(file);
|
||||
SnippetMerger fileScopedMerger(1, textAccess->getLineCount());
|
||||
std::map<int, std::shared_ptr<SnippetMerger>> mergers;
|
||||
file->forEachStartTokenLocation(
|
||||
[&](TokenLocation* location)
|
||||
{
|
||||
buildMergerHierarchy(location, fileScopedMerger, mergers);
|
||||
}
|
||||
);
|
||||
|
||||
ranges = fileScopedMerger.merge();
|
||||
}
|
||||
|
||||
const int snippetExpandRange = ApplicationSettings::getInstance()->getCodeSnippetExpandRange();
|
||||
std::vector<CodeView::CodeSnippetParams> snippets;
|
||||
for (const std::pair<uint, uint>& range: ranges)
|
||||
for (const SnippetMerger::Range& range: ranges)
|
||||
{
|
||||
CodeView::CodeSnippetParams params;
|
||||
params.locationFile = *file;
|
||||
params.startLineNumber = std::max<int>(1, range.first - s_lineRadius);
|
||||
params.endLineNumber = std::min<int>(textAccess->getLineCount(), range.second + s_lineRadius);
|
||||
params.startLineNumber = std::max<int>(1, range.start.row - (range.start.strong ? 0 : snippetExpandRange));
|
||||
params.endLineNumber = std::min<int>(textAccess->getLineCount(), range.end.row + (range.end.strong ? 0 : snippetExpandRange));
|
||||
|
||||
for (const std::string& line: textAccess->getLines(params.startLineNumber, params.endLineNumber))
|
||||
{
|
||||
@@ -174,40 +189,38 @@ std::vector<CodeView::CodeSnippetParams> CodeController::getSnippetsForFile(cons
|
||||
return snippets;
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint, uint>> CodeController::getSnippetRangesForFile(const TokenLocationFile* file) const
|
||||
std::shared_ptr<SnippetMerger> CodeController::buildMergerHierarchy(
|
||||
TokenLocation* location, SnippetMerger& fileScopedMerger, std::map<int, std::shared_ptr<SnippetMerger>>& mergers) const
|
||||
{
|
||||
std::vector<std::pair<uint, uint>> ranges;
|
||||
uint start = 0;
|
||||
uint end = 0;
|
||||
const TokenLocation* currentLocation = location;
|
||||
std::shared_ptr<SnippetMerger> currentMerger = std::make_shared<SnippetMerger>(
|
||||
currentLocation->getStartTokenLocation()->getLineNumber(),
|
||||
currentLocation->getEndTokenLocation()->getLineNumber()
|
||||
);
|
||||
|
||||
file->forEachTokenLocation(
|
||||
[&](TokenLocation* location) -> void
|
||||
std::shared_ptr<TokenLocationFile> locationFile = m_storageAccess->getTokenLocationOfParentScope(currentLocation);
|
||||
if (locationFile->getTokenLocationLineCount() == 0)
|
||||
{
|
||||
fileScopedMerger.addChild(currentMerger);
|
||||
return currentMerger;
|
||||
}
|
||||
|
||||
std::shared_ptr<SnippetMerger> nextMerger;
|
||||
locationFile->forEachStartTokenLocation( // contains just 1 start location
|
||||
[&](TokenLocation* scopeLocation)
|
||||
{
|
||||
uint lineNumber = location->getLineNumber();
|
||||
|
||||
if (location->isStartTokenLocation())
|
||||
std::map<int, std::shared_ptr<SnippetMerger>>::iterator it = mergers.find(scopeLocation->getId());
|
||||
if (it == mergers.end())
|
||||
{
|
||||
if (start && end && lineNumber > end + 2 * s_lineRadius + 1)
|
||||
{
|
||||
ranges.push_back(std::make_pair(uint(start), uint(end)));
|
||||
start = end = 0;
|
||||
}
|
||||
|
||||
if (!start)
|
||||
{
|
||||
start = lineNumber;
|
||||
}
|
||||
|
||||
lineNumber = location->getEndTokenLocation()->getLineNumber();
|
||||
nextMerger = buildMergerHierarchy(scopeLocation, fileScopedMerger, mergers);
|
||||
mergers[scopeLocation->getId()] = nextMerger;
|
||||
}
|
||||
|
||||
if (lineNumber > end)
|
||||
else
|
||||
{
|
||||
end = lineNumber;
|
||||
nextMerger = it->second;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
ranges.push_back(std::make_pair(uint(start), uint(end)));
|
||||
return ranges;
|
||||
nextMerger->addChild(currentMerger);
|
||||
return currentMerger;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CODE_CONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
#include "component/view/CodeView.h"
|
||||
@@ -13,6 +14,10 @@
|
||||
#include "utility/messaging/type/MessageShowFile.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
|
||||
|
||||
#include "component/controller/helper/SnippetMerger.h"
|
||||
|
||||
class StorageAccess;
|
||||
class TokenLocationFile;
|
||||
|
||||
@@ -42,7 +47,8 @@ private:
|
||||
std::vector<CodeView::CodeSnippetParams> getSnippetsForActiveTokenIds(
|
||||
const std::vector<Id>& ids, Id declarationId) const;
|
||||
std::vector<CodeView::CodeSnippetParams> getSnippetsForFile(const TokenLocationFile* file) const;
|
||||
std::vector<std::pair<uint, uint>> getSnippetRangesForFile(const TokenLocationFile* file) const;
|
||||
std::shared_ptr<SnippetMerger> buildMergerHierarchy(
|
||||
TokenLocation* location, SnippetMerger& fileScopedMerger, std::map<int, std::shared_ptr<SnippetMerger>>& mergers) const;
|
||||
|
||||
StorageAccess* m_storageAccess;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "component/controller/helper/SnippetMerger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "settings/ApplicationSettings.h"
|
||||
|
||||
SnippetMerger::SnippetMerger(int startRow, int endRow)
|
||||
: m_start(startRow)
|
||||
, m_end(endRow)
|
||||
{
|
||||
}
|
||||
|
||||
void SnippetMerger::addChild(std::shared_ptr<SnippetMerger> child)
|
||||
{
|
||||
m_children.push_back(child);
|
||||
}
|
||||
|
||||
std::deque<SnippetMerger::Range> SnippetMerger::merge() const
|
||||
{
|
||||
std::deque<Range> merged;
|
||||
if (m_children.size() == 0)
|
||||
{
|
||||
merged.push_back(Range(Border(m_start, false), Border(m_end, false)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < m_children.size(); i++)
|
||||
{
|
||||
std::deque<Range> mergedFromChild = m_children[i]->merge();
|
||||
for (size_t j = 0; j < mergedFromChild.size(); j++)
|
||||
{
|
||||
merged.push_back(mergedFromChild[j]);
|
||||
}
|
||||
}
|
||||
std::sort(merged.begin(), merged.end(),
|
||||
[](const Range& a, const Range& b)
|
||||
{
|
||||
return a.start.row < b.start.row;
|
||||
}
|
||||
);
|
||||
|
||||
// merge children
|
||||
const int snippetExpandRange = ApplicationSettings::getInstance()->getCodeSnippetExpandRange();
|
||||
const int snippetMergeRange = 2 * snippetExpandRange + 1; // +1 since snippets that end/start with consequtive
|
||||
// lines should be merged as well.
|
||||
for (size_t i = 0; i < merged.size() - 1; i++)
|
||||
{
|
||||
const Range first = merged[i];
|
||||
const Range second = merged[i + 1];
|
||||
if (first.end.row + snippetMergeRange >= second.start.row)
|
||||
{
|
||||
merged.erase(merged.begin() + i, merged.begin() + i + 2);
|
||||
merged.insert(merged.begin() + i, Range(
|
||||
first.start.row < second.start.row ? first.start : second.start,
|
||||
first.end.row > second.end.row ? first.end : second.end
|
||||
));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// snap to own borders
|
||||
const int snippetSnapRange = ApplicationSettings::getInstance()->getCodeSnippetSnapRange();
|
||||
if (m_start + snippetSnapRange >= merged.front().start.row)
|
||||
{
|
||||
merged.front().start.row = m_start;
|
||||
merged.front().start.strong = true;
|
||||
}
|
||||
if (m_end - snippetSnapRange <= merged.back().end.row)
|
||||
{
|
||||
merged.back().end.row = m_end;
|
||||
merged.back().end.strong = true;
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef SNIPPET_MERGER_H
|
||||
#define SNIPPET_MERGER_H
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class SnippetMerger
|
||||
{
|
||||
public:
|
||||
struct Border
|
||||
{
|
||||
Border(int row, bool strong): row(row), strong(strong) {}
|
||||
int row;
|
||||
bool strong;
|
||||
};
|
||||
struct Range
|
||||
{
|
||||
Range (Border start, Border end): start(start), end(end) {}
|
||||
Border start;
|
||||
Border end;
|
||||
};
|
||||
|
||||
SnippetMerger(int startRow, int endRow);
|
||||
void addChild(std::shared_ptr<SnippetMerger> child);
|
||||
std::deque<Range> merge() const;
|
||||
|
||||
private:
|
||||
const int m_start;
|
||||
const int m_end;
|
||||
std::vector<std::shared_ptr<SnippetMerger>> m_children;
|
||||
};
|
||||
|
||||
#endif // SNIPPET_MERGER_H
|
||||
Reference in New Issue
Block a user