Copilot: Allow applying suggestions over line breaks

Task-number: QTCREATORBUG-31418
Change-Id: I90b2b53ad57ee1dea5789d02159f4a93fd641c1f
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
David Schulz
2024-08-28 15:23:06 +02:00
parent d3ff09b4d6
commit 7dec58dbb9
4 changed files with 29 additions and 7 deletions

View File

@@ -30,7 +30,6 @@ CopilotSuggestion::CopilotSuggestion(const QList<Completion> &completions,
document()->setPlainText(text);
m_start = completion.position().toTextCursor(origin);
m_start.setKeepPositionOnInsert(true);
setCurrentPosition(m_start.position());
}
bool CopilotSuggestion::apply()
@@ -44,8 +43,9 @@ bool CopilotSuggestion::apply()
bool CopilotSuggestion::applyWord(TextEditorWidget *widget)
{
const Completion completion = m_completions.value(m_currentCompletion);
const QTextCursor cursor = completion.range().toSelection(m_start.document());
Completion completion = m_completions.value(m_currentCompletion);
const Range range = completion.range();
const QTextCursor cursor = range.toSelection(m_start.document());
QTextCursor currentCursor = widget->textCursor();
const QString text = completion.text();
const int startPos = currentCursor.positionInBlock() - cursor.positionInBlock()
@@ -55,13 +55,26 @@ bool CopilotSuggestion::applyWord(TextEditorWidget *widget)
if (next == -1)
return apply();
// TODO: Allow adding more than one line
QString subText = text.mid(startPos, next - startPos);
subText = subText.left(subText.indexOf('\n'));
if (subText.isEmpty())
return false;
currentCursor.insertText(subText);
if (const int seperatorPos = subText.lastIndexOf('\n'); seperatorPos >= 0) {
const QString newCompletionText = text.mid(startPos + seperatorPos + 1);
if (!newCompletionText.isEmpty()) {
completion.setText(newCompletionText);
const Position newStart(range.start().line() + subText.count('\n'), 0);
int nextSeperatorPos = newCompletionText.indexOf('\n');
if (nextSeperatorPos == -1)
nextSeperatorPos = newCompletionText.size();
const Position newEnd(newStart.line(), nextSeperatorPos);
completion.setRange(Range(newStart, newEnd));
completion.setPosition(newStart);
widget->insertSuggestion(std::make_unique<CopilotSuggestion>(
QList<Completion>{completion}, widget->document(), 0));
}
}
return false;
}

View File

@@ -22,10 +22,18 @@ public:
{
return typedValue<LanguageServerProtocol::Position>(LanguageServerProtocol::positionKey);
}
void setPosition(const LanguageServerProtocol::Position &position)
{
insert(LanguageServerProtocol::positionKey, position);
}
LanguageServerProtocol::Range range() const
{
return typedValue<LanguageServerProtocol::Range>(LanguageServerProtocol::rangeKey);
}
void setRange(const LanguageServerProtocol::Range &range)
{
insert(LanguageServerProtocol::rangeKey, range);
}
QString text() const { return typedValue<QString>(LanguageServerProtocol::textKey); }
void setText(const QString &text) { insert(LanguageServerProtocol::textKey, text); }
QString uuid() const { return typedValue<QString>(uuidKey); }

View File

@@ -613,9 +613,9 @@ bool TextDocumentLayout::updateSuggestion(const QTextBlock &block,
const FontSettings &fontSettings)
{
if (TextSuggestion *suggestion = TextDocumentLayout::suggestion(block)) {
auto positionInBlock = position - block.position();
if (position < suggestion->position())
if (position < suggestion->currentPosition())
return false;
const int positionInBlock = position - block.position();
const QString start = block.text().left(positionInBlock);
const QString end = block.text().mid(positionInBlock);
const QString replacement = suggestion->document()->firstBlock().text();

View File

@@ -1823,6 +1823,7 @@ void TextEditorWidgetPrivate::insertSuggestion(std::unique_ptr<TextSuggestion> &
return;
auto cursor = q->textCursor();
suggestion->setCurrentPosition(cursor.position());
cursor.setPosition(suggestion->position());
QTextOption option = suggestion->document()->defaultTextOption();
option.setTabStopDistance(charWidth() * m_document->tabSettings().m_tabSize);