mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-05-28 03:10:28 -04:00
feat: Merge suggestion with existing code if looks similar
This commit is contained in:
parent
637a4d9d4c
commit
63c6a38384
@ -59,6 +59,100 @@ QString mergeWithRightText(const QString &suggestion, const QString &rightText)
|
|||||||
return suggestion;
|
return suggestion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int levenshteinDistance(const QString &source, const QString &target)
|
||||||
|
{
|
||||||
|
if (source == target) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sourceCount = source.size();
|
||||||
|
int targetCount = target.size();
|
||||||
|
|
||||||
|
if (sourceCount == 0) {
|
||||||
|
return targetCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetCount == 0) {
|
||||||
|
return sourceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceCount > targetCount) {
|
||||||
|
return levenshteinDistance(target, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> previousColumn;
|
||||||
|
previousColumn.reserve(targetCount + 1);
|
||||||
|
for (int i = 0; i < targetCount + 1; ++i) {
|
||||||
|
previousColumn.append(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> column(targetCount + 1, 0);
|
||||||
|
for (int i = 0; i < sourceCount; ++i) {
|
||||||
|
column[0] = i + 1;
|
||||||
|
for (int j = 0; j < targetCount; ++j) {
|
||||||
|
column[j + 1] = std::min(
|
||||||
|
{1 + column.at(j),
|
||||||
|
1 + previousColumn.at(1 + j),
|
||||||
|
previousColumn.at(j) + ((source.at(i) == target.at(j)) ? 0 : 1)});
|
||||||
|
}
|
||||||
|
column.swap(previousColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return previousColumn.at(targetCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int linesToReplace(const QString &suggestion, const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
int suggestedLineCount = 0;
|
||||||
|
for (int idx = suggestion.indexOf('\n'); idx != -1; idx = suggestion.indexOf('\n', idx + 1)) {
|
||||||
|
++suggestedLineCount;
|
||||||
|
}
|
||||||
|
if (suggestedLineCount == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor lineReadCursor = cursor;
|
||||||
|
lineReadCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
|
int minDifference = 1e6;
|
||||||
|
int bestLineCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < suggestedLineCount; ++i) {
|
||||||
|
lineReadCursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
||||||
|
lineReadCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
|
QString curText = lineReadCursor.selectedText();
|
||||||
|
|
||||||
|
int difference = levenshteinDistance(curText, suggestion);
|
||||||
|
if (difference > minDifference) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bestLineCount = i + 1;
|
||||||
|
minDifference = difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
double minSimilarity = 0.4; // configurable?
|
||||||
|
int threshold = suggestion.length() * minSimilarity;
|
||||||
|
|
||||||
|
return minDifference < threshold ? bestLineCount : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString existingTailToKeep(const QString &suggestedLine, const QString &existingLine)
|
||||||
|
{
|
||||||
|
int minDifference = 1e6;
|
||||||
|
int bestLength = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i <= existingLine.length(); ++i) {
|
||||||
|
int difference = levenshteinDistance(suggestedLine, existingLine.left(i));
|
||||||
|
if (difference > minDifference) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
minDifference = difference;
|
||||||
|
bestLength = i;
|
||||||
|
}
|
||||||
|
return existingLine.mid(bestLength);
|
||||||
|
}
|
||||||
|
|
||||||
LLMSuggestion::LLMSuggestion(
|
LLMSuggestion::LLMSuggestion(
|
||||||
const QList<Data> &suggestions, QTextDocument *sourceDocument, int currentCompletion)
|
const QList<Data> &suggestions, QTextDocument *sourceDocument, int currentCompletion)
|
||||||
: TextEditor::CyclicSuggestion(suggestions, sourceDocument, currentCompletion)
|
: TextEditor::CyclicSuggestion(suggestions, sourceDocument, currentCompletion)
|
||||||
@ -173,14 +267,34 @@ bool LLMSuggestion::apply()
|
|||||||
|
|
||||||
int firstLineEnd = text.indexOf('\n');
|
int firstLineEnd = text.indexOf('\n');
|
||||||
if (firstLineEnd != -1) {
|
if (firstLineEnd != -1) {
|
||||||
QString firstLine = text.left(firstLineEnd);
|
int toReplace = linesToReplace(text, cursor);
|
||||||
QString restOfText = text.mid(firstLineEnd);
|
|
||||||
|
|
||||||
|
if (toReplace == 0) {
|
||||||
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
editCursor.removeSelectedText();
|
editCursor.removeSelectedText();
|
||||||
|
|
||||||
|
QString firstLine = text.left(firstLineEnd);
|
||||||
QString mergedFirstLine = mergeWithRightText(firstLine, textAfterCursor);
|
QString mergedFirstLine = mergeWithRightText(firstLine, textAfterCursor);
|
||||||
|
QString restOfText = text.mid(firstLineEnd);
|
||||||
editCursor.insertText(mergedFirstLine + restOfText);
|
editCursor.insertText(mergedFirstLine + restOfText);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < toReplace; ++i)
|
||||||
|
editCursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor);
|
||||||
|
editCursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
|
||||||
|
|
||||||
|
QTextCursor lastLineCursor = editCursor;
|
||||||
|
lastLineCursor.setPosition(lastLineCursor.position(), QTextCursor::MoveAnchor);
|
||||||
|
lastLineCursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor);
|
||||||
|
QString lastExistingLine = lastLineCursor.selectedText();
|
||||||
|
|
||||||
|
QString lastSuggestedLine = text.mid(text.lastIndexOf('\n') + 1);
|
||||||
|
qDebug() << lastExistingLine;
|
||||||
|
qDebug() << lastSuggestedLine;
|
||||||
|
|
||||||
|
QString tail = existingTailToKeep(lastSuggestedLine, lastExistingLine);
|
||||||
|
qDebug() << tail;
|
||||||
|
editCursor.insertText(text + tail);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
editCursor.removeSelectedText();
|
editCursor.removeSelectedText();
|
||||||
|
Loading…
Reference in New Issue
Block a user