mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2025-05-27 10:50:28 -04:00
refactor: Improve textsuggestion working
This commit is contained in:
parent
3e9506ca92
commit
2fe6850a06
@ -327,7 +327,9 @@ void LLMClientInterface::sendCompletionToClient(
|
|||||||
completionItem[LanguageServerProtocol::textKey] = processedCompletion;
|
completionItem[LanguageServerProtocol::textKey] = processedCompletion;
|
||||||
QJsonObject range;
|
QJsonObject range;
|
||||||
range["start"] = position;
|
range["start"] = position;
|
||||||
range["end"] = position;
|
QJsonObject end = position;
|
||||||
|
end["character"] = position["character"].toInt() + processedCompletion.length();
|
||||||
|
range["end"] = end;
|
||||||
completionItem[LanguageServerProtocol::rangeKey] = range;
|
completionItem[LanguageServerProtocol::rangeKey] = range;
|
||||||
completionItem[LanguageServerProtocol::positionKey] = position;
|
completionItem[LanguageServerProtocol::positionKey] = position;
|
||||||
completions.append(completionItem);
|
completions.append(completionItem);
|
||||||
|
@ -29,6 +29,36 @@
|
|||||||
|
|
||||||
namespace QodeAssist {
|
namespace QodeAssist {
|
||||||
|
|
||||||
|
QString mergeWithRightText(const QString &suggestion, const QString &rightText)
|
||||||
|
{
|
||||||
|
if (suggestion.isEmpty() || rightText.isEmpty()) {
|
||||||
|
return suggestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
QString processed = rightText;
|
||||||
|
QSet<int> matchedPositions;
|
||||||
|
|
||||||
|
for (int i = 0; i < suggestion.length() && j < processed.length(); ++i) {
|
||||||
|
if (suggestion[i] == processed[j]) {
|
||||||
|
matchedPositions.insert(j);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedPositions.isEmpty()) {
|
||||||
|
return suggestion + rightText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> positions = matchedPositions.values();
|
||||||
|
std::sort(positions.begin(), positions.end(), std::greater<int>());
|
||||||
|
for (int pos : positions) {
|
||||||
|
processed.remove(pos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return suggestion;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -43,16 +73,23 @@ LLMSuggestion::LLMSuggestion(
|
|||||||
|
|
||||||
QTextCursor cursor(sourceDocument);
|
QTextCursor cursor(sourceDocument);
|
||||||
cursor.setPosition(startPos);
|
cursor.setPosition(startPos);
|
||||||
cursor.setPosition(endPos, QTextCursor::KeepAnchor);
|
|
||||||
|
|
||||||
QTextBlock block = cursor.block();
|
QTextBlock block = cursor.block();
|
||||||
QString blockText = block.text();
|
QString blockText = block.text();
|
||||||
|
|
||||||
int startPosInBlock = startPos - block.position();
|
int cursorPositionInBlock = cursor.positionInBlock();
|
||||||
int endPosInBlock = endPos - block.position();
|
|
||||||
|
|
||||||
blockText.replace(startPosInBlock, endPosInBlock - startPosInBlock, data.text);
|
QString rightText = blockText.mid(cursorPositionInBlock);
|
||||||
replacementDocument()->setPlainText(blockText);
|
|
||||||
|
if (!data.text.contains('\n')) {
|
||||||
|
QString processedRightText = mergeWithRightText(data.text, rightText);
|
||||||
|
processedRightText = processedRightText.mid(data.text.length());
|
||||||
|
QString displayText = blockText.left(cursorPositionInBlock) + data.text
|
||||||
|
+ processedRightText;
|
||||||
|
replacementDocument()->setPlainText(displayText);
|
||||||
|
} else {
|
||||||
|
QString displayText = blockText.left(cursorPositionInBlock) + data.text;
|
||||||
|
replacementDocument()->setPlainText(displayText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLMSuggestion::applyWord(TextEditor::TextEditorWidget *widget)
|
bool LLMSuggestion::applyWord(TextEditor::TextEditorWidget *widget)
|
||||||
@ -77,31 +114,82 @@ bool LLMSuggestion::applyPart(Part part, TextEditor::TextEditorWidget *widget)
|
|||||||
|
|
||||||
int next = part == Word ? Utils::endOfNextWord(text, startPos) : text.indexOf('\n', startPos);
|
int next = part == Word ? Utils::endOfNextWord(text, startPos) : text.indexOf('\n', startPos);
|
||||||
|
|
||||||
if (next == -1)
|
if (next == -1) {
|
||||||
return apply();
|
if (part == Line) {
|
||||||
|
next = text.length();
|
||||||
|
} else {
|
||||||
|
return apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (part == Line)
|
if (part == Line)
|
||||||
++next;
|
++next;
|
||||||
|
|
||||||
QString subText = text.mid(startPos, next - startPos);
|
QString subText = text.mid(startPos, next - startPos);
|
||||||
if (subText.isEmpty())
|
|
||||||
|
if (subText.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
currentCursor.insertText(subText);
|
QTextBlock currentBlock = currentCursor.block();
|
||||||
|
QString textAfterCursor = currentBlock.text().mid(currentCursor.positionInBlock());
|
||||||
|
|
||||||
if (const int seperatorPos = subText.lastIndexOf('\n'); seperatorPos >= 0) {
|
if (!subText.contains('\n')) {
|
||||||
const QString newCompletionText = text.mid(startPos + seperatorPos + 1);
|
QTextCursor deleteCursor = currentCursor;
|
||||||
if (!newCompletionText.isEmpty()) {
|
deleteCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
const Utils::Text::Position newStart{int(range.begin.line + subText.count('\n')), 0};
|
deleteCursor.removeSelectedText();
|
||||||
const Utils::Text::Position
|
|
||||||
newEnd{newStart.line, int(subText.length() - seperatorPos - 1)};
|
QString mergedText = mergeWithRightText(subText, textAfterCursor);
|
||||||
const Utils::Text::Range newRange{newStart, newEnd};
|
currentCursor.insertText(mergedText);
|
||||||
const QList<Data> newSuggestion{{newRange, newEnd, newCompletionText}};
|
} else {
|
||||||
widget->insertSuggestion(
|
currentCursor.insertText(subText);
|
||||||
std::make_unique<LLMSuggestion>(newSuggestion, widget->document(), 0));
|
|
||||||
|
if (const int seperatorPos = subText.lastIndexOf('\n'); seperatorPos >= 0) {
|
||||||
|
const QString newCompletionText = text.mid(startPos + seperatorPos + 1);
|
||||||
|
if (!newCompletionText.isEmpty()) {
|
||||||
|
const Utils::Text::Position newStart{int(range.begin.line + subText.count('\n')), 0};
|
||||||
|
const Utils::Text::Position newEnd{newStart.line, int(newCompletionText.length())};
|
||||||
|
const Utils::Text::Range newRange{newStart, newEnd};
|
||||||
|
const QList<Data> newSuggestion{{newRange, newEnd, newCompletionText}};
|
||||||
|
widget->insertSuggestion(
|
||||||
|
std::make_unique<LLMSuggestion>(newSuggestion, widget->document(), 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLMSuggestion::apply()
|
||||||
|
{
|
||||||
|
const Utils::Text::Range range = suggestions()[currentSuggestion()].range;
|
||||||
|
const QTextCursor cursor = range.begin.toTextCursor(sourceDocument());
|
||||||
|
const QString text = suggestions()[currentSuggestion()].text;
|
||||||
|
|
||||||
|
QTextBlock currentBlock = cursor.block();
|
||||||
|
QString textAfterCursor = currentBlock.text().mid(cursor.positionInBlock());
|
||||||
|
|
||||||
|
QTextCursor editCursor = cursor;
|
||||||
|
|
||||||
|
int firstLineEnd = text.indexOf('\n');
|
||||||
|
if (firstLineEnd != -1) {
|
||||||
|
QString firstLine = text.left(firstLineEnd);
|
||||||
|
QString restOfText = text.mid(firstLineEnd);
|
||||||
|
|
||||||
|
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
|
editCursor.removeSelectedText();
|
||||||
|
|
||||||
|
QString mergedFirstLine = mergeWithRightText(firstLine, textAfterCursor);
|
||||||
|
editCursor.insertText(mergedFirstLine + restOfText);
|
||||||
|
} else {
|
||||||
|
editCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||||
|
editCursor.removeSelectedText();
|
||||||
|
|
||||||
|
QString mergedText = mergeWithRightText(text, textAfterCursor);
|
||||||
|
editCursor.insertText(mergedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QodeAssist
|
} // namespace QodeAssist
|
||||||
|
@ -40,5 +40,6 @@ public:
|
|||||||
bool applyWord(TextEditor::TextEditorWidget *widget) override;
|
bool applyWord(TextEditor::TextEditorWidget *widget) override;
|
||||||
bool applyLine(TextEditor::TextEditorWidget *widget) override;
|
bool applyLine(TextEditor::TextEditorWidget *widget) override;
|
||||||
bool applyPart(Part part, TextEditor::TextEditorWidget *widget);
|
bool applyPart(Part part, TextEditor::TextEditorWidget *widget);
|
||||||
|
bool apply() override;
|
||||||
};
|
};
|
||||||
} // namespace QodeAssist
|
} // namespace QodeAssist
|
||||||
|
Loading…
Reference in New Issue
Block a user