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); document()->setPlainText(text);
m_start = completion.position().toTextCursor(origin); m_start = completion.position().toTextCursor(origin);
m_start.setKeepPositionOnInsert(true); m_start.setKeepPositionOnInsert(true);
setCurrentPosition(m_start.position());
} }
bool CopilotSuggestion::apply() bool CopilotSuggestion::apply()
@@ -44,8 +43,9 @@ bool CopilotSuggestion::apply()
bool CopilotSuggestion::applyWord(TextEditorWidget *widget) bool CopilotSuggestion::applyWord(TextEditorWidget *widget)
{ {
const Completion completion = m_completions.value(m_currentCompletion); Completion completion = m_completions.value(m_currentCompletion);
const QTextCursor cursor = completion.range().toSelection(m_start.document()); const Range range = completion.range();
const QTextCursor cursor = range.toSelection(m_start.document());
QTextCursor currentCursor = widget->textCursor(); QTextCursor currentCursor = widget->textCursor();
const QString text = completion.text(); const QString text = completion.text();
const int startPos = currentCursor.positionInBlock() - cursor.positionInBlock() const int startPos = currentCursor.positionInBlock() - cursor.positionInBlock()
@@ -55,13 +55,26 @@ bool CopilotSuggestion::applyWord(TextEditorWidget *widget)
if (next == -1) if (next == -1)
return apply(); return apply();
// TODO: Allow adding more than one line
QString subText = text.mid(startPos, next - startPos); QString subText = text.mid(startPos, next - startPos);
subText = subText.left(subText.indexOf('\n'));
if (subText.isEmpty()) if (subText.isEmpty())
return false; return false;
currentCursor.insertText(subText); 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; return false;
} }

View File

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

View File

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

View File

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