From cd1a9e16e0d6b5db28f28ab7527b8ccf83d9bf20 Mon Sep 17 00:00:00 2001
From: Petr Mironychev <9195189+Palm1r@users.noreply.github.com>
Date: Wed, 11 Sep 2024 01:25:00 +0200
Subject: [PATCH] Add basic cache manager
---
CMakeLists.txt | 1 +
LLMClientInterface.cpp | 16 +++++---
QodeAssistClient.cpp | 4 ++
core/ChangesManager.cpp | 86 +++++++++++++++++++++++++++++++++++++++++
core/ChangesManager.h | 62 +++++++++++++++++++++++++++++
5 files changed, 163 insertions(+), 6 deletions(-)
create mode 100644 core/ChangesManager.cpp
create mode 100644 core/ChangesManager.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e98f4f..f1e9092 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,4 +54,5 @@ add_qtc_plugin(QodeAssist
settings/CustomPromptSettings.hpp settings/CustomPromptSettings.cpp
settings/PresetPromptsSettings.hpp settings/PresetPromptsSettings.cpp
settings/SettingsUtils.hpp
+ core/ChangesManager.h core/ChangesManager.cpp
)
diff --git a/LLMClientInterface.cpp b/LLMClientInterface.cpp
index a473ac1..3facf56 100644
--- a/LLMClientInterface.cpp
+++ b/LLMClientInterface.cpp
@@ -29,6 +29,7 @@
#include "LLMProvidersManager.hpp"
#include "PromptTemplateManager.hpp"
#include "QodeAssistUtils.hpp"
+#include "core/ChangesManager.h"
#include "settings/ContextSettings.hpp"
#include "settings/GeneralSettings.hpp"
@@ -277,14 +278,17 @@ ContextData LLMClientInterface::prepareContext(const QJsonObject &request,
DocumentContextReader reader(widget->textDocument());
+ QString recentChanges = ChangesManager::instance().getRecentChangesContext();
+
QString contextBefore = сontextBefore(widget, lineNumber, cursorPosition);
QString contextAfter = сontextAfter(widget, lineNumber, cursorPosition);
- QString instructions = QString("%1%2").arg(Settings::contextSettings().useSpecificInstructions()
- ? reader.getSpecificInstructions()
- : QString(),
- Settings::contextSettings().useFilePathInContext()
- ? reader.getLanguageAndFileInfo()
- : QString());
+ QString instructions = QString("%1%2%3").arg(Settings::contextSettings().useSpecificInstructions()
+ ? reader.getSpecificInstructions()
+ : QString(),
+ Settings::contextSettings().useFilePathInContext()
+ ? reader.getLanguageAndFileInfo()
+ : QString(),
+ recentChanges);
return {QString("%1%2").arg(contextBefore, accumulatedCompletion), contextAfter, instructions};
}
diff --git a/QodeAssistClient.cpp b/QodeAssistClient.cpp
index d8593ec..1f3bf53 100644
--- a/QodeAssistClient.cpp
+++ b/QodeAssistClient.cpp
@@ -31,6 +31,7 @@
#include "LLMClientInterface.hpp"
#include "LLMSuggestion.hpp"
+#include "core/ChangesManager.h"
#include "settings/GeneralSettings.hpp"
using namespace LanguageServerProtocol;
@@ -83,6 +84,9 @@ void QodeAssistClient::openDocument(TextEditor::TextDocument *document)
auto textEditor = BaseTextEditor::currentTextEditor();
if (!textEditor || textEditor->document() != document)
return;
+
+ ChangesManager::instance().addChange(document, position, charsRemoved, charsAdded);
+
TextEditorWidget *widget = textEditor->editorWidget();
if (widget->isReadOnly() || widget->multiTextCursor().hasMultipleCursors())
return;
diff --git a/core/ChangesManager.cpp b/core/ChangesManager.cpp
new file mode 100644
index 0000000..fcee753
--- /dev/null
+++ b/core/ChangesManager.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 Petr Mironychev
+ *
+ * This file is part of QodeAssist.
+ *
+ * QodeAssist is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * QodeAssist is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with QodeAssist. If not, see .
+ */
+
+#include "ChangesManager.h"
+#include "QodeAssistUtils.hpp"
+
+namespace QodeAssist {
+
+ChangesManager &ChangesManager::instance()
+{
+ static ChangesManager instance;
+ return instance;
+}
+
+ChangesManager::ChangesManager()
+ : QObject(nullptr)
+{
+}
+
+ChangesManager::~ChangesManager()
+{
+}
+
+void ChangesManager::addChange(TextEditor::TextDocument *document,
+ int position,
+ int charsRemoved,
+ int charsAdded)
+{
+ auto &documentQueue = m_documentChanges[document];
+
+ QTextBlock block = document->document()->findBlock(position);
+ int lineNumber = block.blockNumber();
+ QString lineContent = block.text();
+ QString fileName = document->filePath().fileName();
+
+ ChangeInfo change{fileName, lineNumber, lineContent};
+
+ auto it = std::find_if(documentQueue.begin(),
+ documentQueue.end(),
+ [lineNumber](const ChangeInfo &c) { return c.lineNumber == lineNumber; });
+
+ if (it != documentQueue.end()) {
+ it->lineContent = lineContent;
+ } else {
+ documentQueue.enqueue(change);
+
+ if (documentQueue.size() > MAX_CACHED_CHANGES) {
+ documentQueue.dequeue();
+ }
+ }
+
+ logMessage(QString("ChangesManager: Updated %1 line %2: '%3'")
+ .arg(fileName)
+ .arg(lineNumber)
+ .arg(lineContent));
+ logMessage(QString("ChangesManager: Document queue size %1").arg(documentQueue.size()));
+}
+
+QString ChangesManager::getRecentChangesContext() const
+{
+ QString context;
+ for (const auto &documentChanges : m_documentChanges) {
+ for (const auto &change : documentChanges) {
+ context += change.lineContent + "\n";
+ }
+ }
+ return context;
+}
+
+} // namespace QodeAssist
diff --git a/core/ChangesManager.h b/core/ChangesManager.h
new file mode 100644
index 0000000..4bd759b
--- /dev/null
+++ b/core/ChangesManager.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 Petr Mironychev
+ *
+ * This file is part of QodeAssist.
+ *
+ * QodeAssist is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * QodeAssist is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with QodeAssist. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+namespace QodeAssist {
+
+class ChangesManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ struct ChangeInfo
+ {
+ QString fileName;
+ int lineNumber;
+ QString lineContent;
+ };
+
+ static ChangesManager &instance();
+
+ void addChange(TextEditor::TextDocument *document,
+ int position,
+ int charsRemoved,
+ int charsAdded);
+ QString getRecentChangesContext() const;
+
+private:
+ ChangesManager();
+ ~ChangesManager();
+ ChangesManager(const ChangesManager &) = delete;
+ ChangesManager &operator=(const ChangesManager &) = delete;
+
+ void cleanupOldChanges();
+ static const int MAX_CACHED_CHANGES = 50;
+
+ QHash> m_documentChanges;
+};
+
+} // namespace QodeAssist