diff --git a/bin/app/data/ApplicationSettings_template.xml b/bin/app/data/ApplicationSettings_template.xml
index 340f4ac2..741c5938 100644
--- a/bin/app/data/ApplicationSettings_template.xml
+++ b/bin/app/data/ApplicationSettings_template.xml
@@ -35,6 +35,10 @@
+
+
+
+
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 92f6a7db..c404704f 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -35,6 +35,9 @@ add_files(
add_files(
LIB_FILES
+ component/controller/helper/SnippetMerger.cpp
+ component/controller/helper/SnippetMerger.h
+
component/controller/CodeController.cpp
component/controller/CodeController.h
component/controller/Controller.cpp
diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp
index 537fca3a..5efb36ea 100644
--- a/src/lib/component/controller/CodeController.cpp
+++ b/src/lib/component/controller/CodeController.cpp
@@ -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 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 CodeController::getSnippetsForFile(cons
{
std::shared_ptr textAccess = TextAccess::createFromFile(file->getFilePath().str());
- std::vector> ranges;
+ std::deque 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> mergers;
+ file->forEachStartTokenLocation(
+ [&](TokenLocation* location)
+ {
+ buildMergerHierarchy(location, fileScopedMerger, mergers);
+ }
+ );
+
+ ranges = fileScopedMerger.merge();
}
+ const int snippetExpandRange = ApplicationSettings::getInstance()->getCodeSnippetExpandRange();
std::vector snippets;
- for (const std::pair& range: ranges)
+ for (const SnippetMerger::Range& range: ranges)
{
CodeView::CodeSnippetParams params;
params.locationFile = *file;
- params.startLineNumber = std::max(1, range.first - s_lineRadius);
- params.endLineNumber = std::min(textAccess->getLineCount(), range.second + s_lineRadius);
+ params.startLineNumber = std::max(1, range.start.row - (range.start.strong ? 0 : snippetExpandRange));
+ params.endLineNumber = std::min(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 CodeController::getSnippetsForFile(cons
return snippets;
}
-std::vector> CodeController::getSnippetRangesForFile(const TokenLocationFile* file) const
+std::shared_ptr CodeController::buildMergerHierarchy(
+ TokenLocation* location, SnippetMerger& fileScopedMerger, std::map>& mergers) const
{
- std::vector> ranges;
- uint start = 0;
- uint end = 0;
+ const TokenLocation* currentLocation = location;
+ std::shared_ptr currentMerger = std::make_shared(
+ currentLocation->getStartTokenLocation()->getLineNumber(),
+ currentLocation->getEndTokenLocation()->getLineNumber()
+ );
- file->forEachTokenLocation(
- [&](TokenLocation* location) -> void
+ std::shared_ptr locationFile = m_storageAccess->getTokenLocationOfParentScope(currentLocation);
+ if (locationFile->getTokenLocationLineCount() == 0)
+ {
+ fileScopedMerger.addChild(currentMerger);
+ return currentMerger;
+ }
+
+ std::shared_ptr nextMerger;
+ locationFile->forEachStartTokenLocation( // contains just 1 start location
+ [&](TokenLocation* scopeLocation)
{
- uint lineNumber = location->getLineNumber();
-
- if (location->isStartTokenLocation())
+ std::map>::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;
}
diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h
index 38dc4151..7ce8cb5d 100644
--- a/src/lib/component/controller/CodeController.h
+++ b/src/lib/component/controller/CodeController.h
@@ -2,6 +2,7 @@
#define CODE_CONTROLLER_H
#include
+#include