Commit 53098231 authored by Waqar Ahmed's avatar Waqar Ahmed
Browse files

Clean up SemanticHighlighter interface

parent 1f784e69
......@@ -636,29 +636,18 @@ public:
auto server = m_serverManager->findServer(view);
if (server) {
auto resultId = m_semHighlightingManager.resultIdForDoc(view->document());
m_semHighlightingManager.setLegend(&server->capabilities().semanticTokenProvider.legend);
// m_semHighlightingManager.setTypes(server->capabilities().semanticTokenProvider.types);
// m_semHighlightingManager.setTypes(server->capabilities().semanticTokenProvider.types);
QPointer<KTextEditor::View> v = view;
auto h = [this, v](const LSPSemanticTokensDelta &st) {
auto h = [this, v, server](const LSPSemanticTokensDelta &st) {
if (!v) {
return;
}
auto doc = v->document();
m_semHighlightingManager.setCurrentView(v);
for (const auto &semTokenEdit : st.edits) {
m_semHighlightingManager.update(doc, st.resultId, semTokenEdit.start, semTokenEdit.deleteCount, semTokenEdit.data);
}
if (!st.data.empty()) {
m_semHighlightingManager.insert(doc, st.resultId, st.data);
}
m_semHighlightingManager.highlight(doc);
const auto legend = &server->capabilities().semanticTokenProvider.legend;
m_semHighlightingManager.processTokens(st, v, legend);
};
auto resultId = m_semHighlightingManager.resultIdForDoc(view->document());
if (!server->capabilities().semanticTokenProvider.fullDelta) {
server->documentSemanticTokensFull(view->document()->url(), resultId, this, h);
} else {
......
......@@ -5,31 +5,35 @@
SPDX-License-Identifier: MIT
*/
#include "lspsemantichighlighting.h"
#include "lspclientprotocol.h"
#include "semantic_tokens_legend.h"
#include <KTextEditor/MovingInterface>
#include <KTextEditor/View>
#include "semantic_tokens_legend.h"
void SemanticHighlighter::remove(KTextEditor::Document *doc)
void SemanticHighlighter::processTokens(const LSPSemanticTokensDelta &tokens, KTextEditor::View *view, const SemanticTokensLegend *legend)
{
m_docUrlToResultId.remove(doc);
Q_ASSERT(view);
auto it = m_docSemanticInfo.find(doc);
if (it == m_docSemanticInfo.end()) {
return;
for (const auto &semTokenEdit : tokens.edits) {
update(view->document(), tokens.resultId, semTokenEdit.start, semTokenEdit.deleteCount, semTokenEdit.data);
}
auto &movingRanges = it->movingRanges;
for (auto mr : movingRanges) {
delete mr;
if (!tokens.data.empty()) {
insert(view->document(), tokens.resultId, tokens.data);
}
m_docSemanticInfo.remove(doc);
highlight(view, legend);
}
void SemanticHighlighter::remove(KTextEditor::Document *doc)
{
m_docResultId.erase(doc);
m_docSemanticInfo.erase(doc);
}
void SemanticHighlighter::insert(KTextEditor::Document *doc, const QString &resultId, const std::vector<uint32_t> &data)
{
m_docUrlToResultId[doc] = resultId;
m_docResultId[doc] = resultId;
TokensData &tokensData = m_docSemanticInfo[doc];
tokensData.tokens = data;
}
......@@ -44,7 +48,7 @@ void SemanticHighlighter::update(KTextEditor::Document *doc, const QString &resu
return;
}
auto &existingTokens = toks->tokens;
auto &existingTokens = toks->second.tokens;
// replace
if (deleteCount > 0) {
......@@ -53,22 +57,17 @@ void SemanticHighlighter::update(KTextEditor::Document *doc, const QString &resu
existingTokens.insert(existingTokens.begin() + start, data.begin(), data.end());
// Update result Id
m_docUrlToResultId[doc] = resultId;
m_docResultId[doc] = resultId;
}
void SemanticHighlighter::highlight(KTextEditor::Document *doc)
void SemanticHighlighter::highlight(KTextEditor::View *view, const SemanticTokensLegend *legend)
{
Q_ASSERT(m_legend);
if (!view || !m_legend) {
return;
}
Q_ASSERT(legend);
if (!doc) {
qWarning() << "View doesn't have doc!";
if (!view || !legend) {
return;
}
auto doc = view->document();
auto miface = qobject_cast<KTextEditor::MovingInterface *>(doc);
TokensData &semanticData = m_docSemanticInfo[doc];
......@@ -102,29 +101,29 @@ void SemanticHighlighter::highlight(KTextEditor::Document *doc)
start = deltaStart;
}
// QString text = doc->line(currentLine);
// text = text.mid(start, len);
// QString text = doc->line(currentLine);
// text = text.mid(start, len);
KTextEditor::Range r(currentLine, start, currentLine, start + len);
// Check if we have a moving ranges already available in the cache
const auto index = i / 5;
if (index < movingRanges.size()) {
KTextEditor::MovingRange *range = movingRanges[index];
auto &range = movingRanges[index];
if (range) {
range->setRange(r);
range->setAttribute(m_legend->attrForIndex(type));
range->setAttribute(legend->attrForIndex(type));
reusedRanges++;
continue;
}
}
KTextEditor::MovingRange *mr = miface->newMovingRange(r);
mr->setAttribute(m_legend->attrForIndex(type));
movingRanges.push_back(mr);
std::unique_ptr<KTextEditor::MovingRange> mr(miface->newMovingRange(r));
mr->setAttribute(legend->attrForIndex(type));
movingRanges.push_back(std::move(mr));
newRanges++;
// std::cout << "Token: " << text.toStdString() << " => " << m_types.at(type).toStdString() << ", Line: {" << currentLine << ", " << deltaLine
// std::cout << "Token: " << text.toStdString() << " => " << m_types.at(type).toStdString() << ", Line: {" << currentLine << ", " << deltaLine
// << "}\n";
}
......@@ -133,7 +132,7 @@ void SemanticHighlighter::highlight(KTextEditor::Document *doc)
*/
int totalCreatedRanges = reusedRanges + newRanges;
if (totalCreatedRanges < (int)movingRanges.size()) {
std::for_each(movingRanges.begin() + totalCreatedRanges, movingRanges.end(), [](KTextEditor::MovingRange *mr) {
std::for_each(movingRanges.begin() + totalCreatedRanges, movingRanges.end(), [](const std::unique_ptr<KTextEditor::MovingRange> &mr) {
mr->setRange(KTextEditor::Range::invalid());
});
}
......
......@@ -18,24 +18,37 @@
#include <KTextEditor/View>
class SemanticTokensLegend;
struct LSPSemanticTokensDelta;
class SemanticHighlighter
{
public:
QString resultIdForDoc(KTextEditor::Document *doc) const
{
auto it = m_docResultId.find(doc);
if (it != m_docResultId.end()) {
return it->second;
}
return QString();
}
/**
* Does the actual highlighting
* Unregister a doc from highlighter and remove all its associated moving ranges and tokens
*/
void highlight(KTextEditor::Document *doc);
void remove(KTextEditor::Document *doc);
void processTokens(const LSPSemanticTokensDelta &tokens, KTextEditor::View *view, const SemanticTokensLegend *legend);
private:
/**
* Insert tokens @p data for doc with @p url
* Does the actual highlighting
*/
void insert(KTextEditor::Document *doc, const QString &resultId, const std::vector<uint32_t> &data);
void highlight(KTextEditor::View *view, const SemanticTokensLegend *legend);
/**
* Unregister a doc from highlighter and remove all its moving ranges and tokens
* Insert tokens @p data for doc with @p url
*/
void remove(KTextEditor::Document *doc);
void insert(KTextEditor::Document *doc, const QString &resultId, const std::vector<uint32_t> &data);
/**
* This function is more or less useless for Kate? Maybe because MovingRange already handles this for us
......@@ -46,36 +59,15 @@ public:
*/
void update(KTextEditor::Document *doc, const QString &resultId, uint32_t start, uint32_t deleteCount, const std::vector<uint32_t> &data);
QString resultIdForDoc(KTextEditor::Document *doc) const
{
return m_docUrlToResultId.value(doc);
}
void setCurrentView(KTextEditor::View *v)
{
view = v;
}
void setLegend(const SemanticTokensLegend *legend)
{
m_legend = legend;
}
private:
/**
* A simple struct which holds the tokens recieved by server +
* moving ranges that were created to highlight those tokens
*/
struct TokensData {
std::vector<uint32_t> tokens;
std::vector<KTextEditor::MovingRange *> movingRanges;
std::vector<std::unique_ptr<KTextEditor::MovingRange>> movingRanges;
};
/**
* The current active view
*/
QPointer<KTextEditor::View> view;
/**
* token types specified in server caps. Uncomment for debuggin
*/
......@@ -84,16 +76,11 @@ private:
/**
* Doc => result-id mapping
*/
QHash<KTextEditor::Document *, QString> m_docUrlToResultId;
std::unordered_map<KTextEditor::Document *, QString> m_docResultId;
/**
* semantic token and moving range mapping for doc
*/
QHash<KTextEditor::Document *, TokensData> m_docSemanticInfo;
/**
* Legend which is basically used to fetch color for a type
*/
const SemanticTokensLegend *m_legend = nullptr;
std::unordered_map<KTextEditor::Document *, TokensData> m_docSemanticInfo;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment