mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-11-12 21:12:44 -05:00
feat: Add settings for auto apply changes
This commit is contained in:
@ -20,6 +20,7 @@
|
|||||||
#include "FileEditItem.hpp"
|
#include "FileEditItem.hpp"
|
||||||
|
|
||||||
#include "Logger.hpp"
|
#include "Logger.hpp"
|
||||||
|
#include "settings/GeneralSettings.hpp"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@ -89,10 +90,15 @@ void FileEditItem::parseFromContent(const QString &content)
|
|||||||
emit editModeChanged();
|
emit editModeChanged();
|
||||||
emit originalContentChanged();
|
emit originalContentChanged();
|
||||||
emit newContentChanged();
|
emit newContentChanged();
|
||||||
|
emit contextBeforeChanged();
|
||||||
|
emit contextAfterChanged();
|
||||||
emit addedLinesChanged();
|
emit addedLinesChanged();
|
||||||
emit removedLinesChanged();
|
emit removedLinesChanged();
|
||||||
|
|
||||||
|
bool autoApplyEnabled = Settings::generalSettings().autoApplyFileEdits.value();
|
||||||
|
if (autoApplyEnabled) {
|
||||||
applyEditInternal(true);
|
applyEditInternal(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileEditItem::applyEdit()
|
void FileEditItem::applyEdit()
|
||||||
@ -102,9 +108,16 @@ void FileEditItem::applyEdit()
|
|||||||
|
|
||||||
void FileEditItem::applyEditInternal(bool isAutomatic, int retryCount)
|
void FileEditItem::applyEditInternal(bool isAutomatic, int retryCount)
|
||||||
{
|
{
|
||||||
if (!isAutomatic && m_status != EditStatus::Reverted && m_status != EditStatus::Rejected) {
|
if (isAutomatic) {
|
||||||
|
if (m_status != EditStatus::Pending) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (m_status != EditStatus::Pending && m_status != EditStatus::Reverted
|
||||||
|
&& m_status != EditStatus::Rejected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!acquireFileLock(m_filePath)) {
|
if (!acquireFileLock(m_filePath)) {
|
||||||
if (retryCount >= MAX_RETRY_COUNT) {
|
if (retryCount >= MAX_RETRY_COUNT) {
|
||||||
|
|||||||
@ -51,6 +51,8 @@ public:
|
|||||||
Q_PROPERTY(QString editMode READ editMode NOTIFY editModeChanged FINAL)
|
Q_PROPERTY(QString editMode READ editMode NOTIFY editModeChanged FINAL)
|
||||||
Q_PROPERTY(QString originalContent READ originalContent NOTIFY originalContentChanged FINAL)
|
Q_PROPERTY(QString originalContent READ originalContent NOTIFY originalContentChanged FINAL)
|
||||||
Q_PROPERTY(QString newContent READ newContent NOTIFY newContentChanged FINAL)
|
Q_PROPERTY(QString newContent READ newContent NOTIFY newContentChanged FINAL)
|
||||||
|
Q_PROPERTY(QString contextBefore READ contextBefore NOTIFY contextBeforeChanged FINAL)
|
||||||
|
Q_PROPERTY(QString contextAfter READ contextAfter NOTIFY contextAfterChanged FINAL)
|
||||||
Q_PROPERTY(int addedLines READ addedLines NOTIFY addedLinesChanged FINAL)
|
Q_PROPERTY(int addedLines READ addedLines NOTIFY addedLinesChanged FINAL)
|
||||||
Q_PROPERTY(int removedLines READ removedLines NOTIFY removedLinesChanged FINAL)
|
Q_PROPERTY(int removedLines READ removedLines NOTIFY removedLinesChanged FINAL)
|
||||||
Q_PROPERTY(EditStatus status READ status NOTIFY statusChanged FINAL)
|
Q_PROPERTY(EditStatus status READ status NOTIFY statusChanged FINAL)
|
||||||
@ -64,6 +66,8 @@ public:
|
|||||||
QString editMode() const { return m_editMode; }
|
QString editMode() const { return m_editMode; }
|
||||||
QString originalContent() const { return m_originalContent; }
|
QString originalContent() const { return m_originalContent; }
|
||||||
QString newContent() const { return m_newContent; }
|
QString newContent() const { return m_newContent; }
|
||||||
|
QString contextBefore() const { return m_contextBefore; }
|
||||||
|
QString contextAfter() const { return m_contextAfter; }
|
||||||
int addedLines() const { return m_addedLines; }
|
int addedLines() const { return m_addedLines; }
|
||||||
int removedLines() const { return m_removedLines; }
|
int removedLines() const { return m_removedLines; }
|
||||||
EditStatus status() const { return m_status; }
|
EditStatus status() const { return m_status; }
|
||||||
@ -79,6 +83,8 @@ signals:
|
|||||||
void editModeChanged();
|
void editModeChanged();
|
||||||
void originalContentChanged();
|
void originalContentChanged();
|
||||||
void newContentChanged();
|
void newContentChanged();
|
||||||
|
void contextBeforeChanged();
|
||||||
|
void contextAfterChanged();
|
||||||
void addedLinesChanged();
|
void addedLinesChanged();
|
||||||
void removedLinesChanged();
|
void removedLinesChanged();
|
||||||
void statusChanged();
|
void statusChanged();
|
||||||
|
|||||||
@ -38,13 +38,6 @@ FileEditItem {
|
|||||||
readonly property int headerPadding: 8
|
readonly property int headerPadding: 8
|
||||||
readonly property int statusIndicatorWidth: 4
|
readonly property int statusIndicatorWidth: 4
|
||||||
|
|
||||||
readonly property var originalLines: originalContent.split('\n')
|
|
||||||
readonly property var newLines: newContent.split('\n')
|
|
||||||
readonly property string firstOriginalLine: originalLines[0] || ""
|
|
||||||
readonly property string firstNewLine: newLines[0] || ""
|
|
||||||
readonly property bool hasMultipleOriginalLines: originalLines.length > 1
|
|
||||||
readonly property bool hasMultipleNewLines: newLines.length > 1
|
|
||||||
|
|
||||||
readonly property bool isPending: status === FileEditItem.Pending
|
readonly property bool isPending: status === FileEditItem.Pending
|
||||||
readonly property bool isApplied: status === FileEditItem.Applied
|
readonly property bool isApplied: status === FileEditItem.Applied
|
||||||
readonly property bool isReverted: status === FileEditItem.Reverted
|
readonly property bool isReverted: status === FileEditItem.Reverted
|
||||||
@ -159,10 +152,21 @@ FileEditItem {
|
|||||||
Text {
|
Text {
|
||||||
id: headerText
|
id: headerText
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("File Edit: %1 (+%2 -%3)")
|
text: {
|
||||||
|
var modeText = ""
|
||||||
|
switch(root.editMode) {
|
||||||
|
case "replace": modeText = qsTr("Replace"); break;
|
||||||
|
case "insert_before": modeText = qsTr("Insert Before"); break;
|
||||||
|
case "insert_after": modeText = qsTr("Insert After"); break;
|
||||||
|
case "append": modeText = qsTr("Append"); break;
|
||||||
|
default: modeText = root.editMode;
|
||||||
|
}
|
||||||
|
return qsTr("%1: %2 (+%3 -%4)")
|
||||||
|
.arg(modeText)
|
||||||
.arg(root.filePath)
|
.arg(root.filePath)
|
||||||
.arg(root.addedLines)
|
.arg(root.addedLines)
|
||||||
.arg(root.removedLines)
|
.arg(root.removedLines)
|
||||||
|
}
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.bold: true
|
font.bold: true
|
||||||
color: palette.text
|
color: palette.text
|
||||||
@ -194,7 +198,7 @@ FileEditItem {
|
|||||||
|
|
||||||
QoAButton {
|
QoAButton {
|
||||||
text: qsTr("Apply")
|
text: qsTr("Apply")
|
||||||
enabled: root.isReverted || root.isRejected
|
enabled: root.isPending || root.isReverted || root.isRejected
|
||||||
visible: !root.isApplied
|
visible: !root.isApplied
|
||||||
onClicked: root.applyEdit()
|
onClicked: root.applyEdit()
|
||||||
}
|
}
|
||||||
@ -220,22 +224,76 @@ FileEditItem {
|
|||||||
spacing: 4
|
spacing: 4
|
||||||
visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
|
||||||
|
// Context before (if available)
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: "Old: " + root.firstOriginalLine + (root.hasMultipleOriginalLines ? "..." : "")
|
visible: root.contextBefore.length > 0
|
||||||
|
text: root.contextBefore
|
||||||
|
font.family: root.codeFontFamily
|
||||||
|
font.pixelSize: root.codeFontSize
|
||||||
|
color: palette.mid
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
opacity: 0.6
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: oldContentText.implicitHeight + 8
|
||||||
|
color: Qt.rgba(1, 0.2, 0.2, 0.1)
|
||||||
|
radius: 4
|
||||||
|
border.width: 1
|
||||||
|
border.color: Qt.rgba(1, 0.2, 0.2, 0.3)
|
||||||
|
visible: root.originalContent.length > 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: oldContentText
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
margins: 4
|
||||||
|
}
|
||||||
|
text: "- " + root.originalContent
|
||||||
font.family: root.codeFontFamily
|
font.family: root.codeFontFamily
|
||||||
font.pixelSize: root.codeFontSize
|
font.pixelSize: root.codeFontSize
|
||||||
color: Qt.rgba(1, 0.2, 0.2, 0.9)
|
color: Qt.rgba(1, 0.2, 0.2, 0.9)
|
||||||
elide: Text.ElideRight
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: newContentText.implicitHeight + 8
|
||||||
|
color: Qt.rgba(0.2, 0.8, 0.2, 0.1)
|
||||||
|
radius: 4
|
||||||
|
border.width: 1
|
||||||
|
border.color: Qt.rgba(0.2, 0.8, 0.2, 0.3)
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: newContentText
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
margins: 4
|
||||||
|
}
|
||||||
|
text: "+ " + root.newContent
|
||||||
|
font.family: root.codeFontFamily
|
||||||
|
font.pixelSize: root.codeFontSize
|
||||||
|
color: Qt.rgba(0.2, 0.8, 0.2, 0.9)
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: "New: " + root.firstNewLine + (root.hasMultipleNewLines ? "..." : "")
|
visible: root.contextAfter.length > 0
|
||||||
|
text: root.contextAfter
|
||||||
font.family: root.codeFontFamily
|
font.family: root.codeFontFamily
|
||||||
font.pixelSize: root.codeFontSize
|
font.pixelSize: root.codeFontSize
|
||||||
color: Qt.rgba(0.2, 0.8, 0.2, 0.9)
|
color: palette.mid
|
||||||
elide: Text.ElideRight
|
wrapMode: Text.Wrap
|
||||||
|
opacity: 0.6
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
|||||||
@ -226,6 +226,13 @@ GeneralSettings::GeneralSettings()
|
|||||||
Tr::tr("Allow tools to write and modify files on disk (WARNING: Use with caution!)"));
|
Tr::tr("Allow tools to write and modify files on disk (WARNING: Use with caution!)"));
|
||||||
allowFileSystemWrite.setDefaultValue(false);
|
allowFileSystemWrite.setDefaultValue(false);
|
||||||
|
|
||||||
|
autoApplyFileEdits.setSettingsKey(Constants::CA_AUTO_APPLY_FILE_EDITS);
|
||||||
|
autoApplyFileEdits.setLabelText(Tr::tr("Automatically apply file edits"));
|
||||||
|
autoApplyFileEdits.setToolTip(
|
||||||
|
Tr::tr("When enabled, file edits suggested by AI will be applied automatically. "
|
||||||
|
"When disabled, you will need to manually approve each edit."));
|
||||||
|
autoApplyFileEdits.setDefaultValue(false);
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
|
|
||||||
Logger::instance().setLoggingEnabled(enableLogging());
|
Logger::instance().setLoggingEnabled(enableLogging());
|
||||||
@ -272,7 +279,7 @@ GeneralSettings::GeneralSettings()
|
|||||||
auto caGroup = Group{
|
auto caGroup = Group{
|
||||||
title(TrConstants::CHAT_ASSISTANT),
|
title(TrConstants::CHAT_ASSISTANT),
|
||||||
Column{caGrid,
|
Column{caGrid,
|
||||||
Column{useTools, allowFileSystemRead, allowFileSystemWrite},
|
Column{useTools, allowFileSystemRead, allowFileSystemWrite, autoApplyFileEdits},
|
||||||
caTemplateDescription}};
|
caTemplateDescription}};
|
||||||
|
|
||||||
auto rootLayout = Column{
|
auto rootLayout = Column{
|
||||||
@ -520,6 +527,7 @@ void GeneralSettings::resetPageToDefaults()
|
|||||||
resetAspect(useTools);
|
resetAspect(useTools);
|
||||||
resetAspect(allowFileSystemRead);
|
resetAspect(allowFileSystemRead);
|
||||||
resetAspect(allowFileSystemWrite);
|
resetAspect(allowFileSystemWrite);
|
||||||
|
resetAspect(autoApplyFileEdits);
|
||||||
writeSettings();
|
writeSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -103,6 +103,7 @@ public:
|
|||||||
Utils::BoolAspect useTools{this};
|
Utils::BoolAspect useTools{this};
|
||||||
Utils::BoolAspect allowFileSystemRead{this};
|
Utils::BoolAspect allowFileSystemRead{this};
|
||||||
Utils::BoolAspect allowFileSystemWrite{this};
|
Utils::BoolAspect allowFileSystemWrite{this};
|
||||||
|
Utils::BoolAspect autoApplyFileEdits{this};
|
||||||
|
|
||||||
Utils::StringAspect caTemplateDescription{this};
|
Utils::StringAspect caTemplateDescription{this};
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,7 @@ const char MAX_FILE_THRESHOLD[] = "QodeAssist.maxFileThreshold";
|
|||||||
const char CC_MULTILINE_COMPLETION[] = "QodeAssist.ccMultilineCompletion";
|
const char CC_MULTILINE_COMPLETION[] = "QodeAssist.ccMultilineCompletion";
|
||||||
const char CC_MODEL_OUTPUT_HANDLER[] = "QodeAssist.ccModelOutputHandler";
|
const char CC_MODEL_OUTPUT_HANDLER[] = "QodeAssist.ccModelOutputHandler";
|
||||||
const char CUSTOM_JSON_TEMPLATE[] = "QodeAssist.customJsonTemplate";
|
const char CUSTOM_JSON_TEMPLATE[] = "QodeAssist.customJsonTemplate";
|
||||||
|
const char CA_AUTO_APPLY_FILE_EDITS[] = "QodeAssist.caAutoApplyFileEdits";
|
||||||
const char CA_TOKENS_THRESHOLD[] = "QodeAssist.caTokensThreshold";
|
const char CA_TOKENS_THRESHOLD[] = "QodeAssist.caTokensThreshold";
|
||||||
const char CA_LINK_OPEN_FILES[] = "QodeAssist.caLinkOpenFiles";
|
const char CA_LINK_OPEN_FILES[] = "QodeAssist.caLinkOpenFiles";
|
||||||
const char CA_AUTOSAVE[] = "QodeAssist.caAutosave";
|
const char CA_AUTOSAVE[] = "QodeAssist.caAutosave";
|
||||||
|
|||||||
Reference in New Issue
Block a user