TextEditor: add text cursor to assist interface

This will allow us to request assistance for a specific selection
instead of just the position.

Change-Id: Ib8e5b32d4a8f2936e5a6f1b7ac968d7f1d8d9de6
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-05-13 10:05:45 +02:00
parent 1402b16451
commit 59a77a4965
18 changed files with 44 additions and 60 deletions

View File

@@ -616,18 +616,13 @@ void addFixItsActionsToMenu(QMenu *menu, const TextEditor::QuickFixOperations &f
}
}
static int lineToPosition(const QTextDocument *textDocument, int lineNumber)
{
QTC_ASSERT(textDocument, return 0);
const QTextBlock textBlock = textDocument->findBlockByLineNumber(lineNumber);
return textBlock.isValid() ? textBlock.position() - 1 : 0;
}
static TextEditor::AssistInterface createAssistInterface(TextEditor::TextEditorWidget *widget,
int lineNumber)
{
return TextEditor::AssistInterface(widget->document(),
lineToPosition(widget->document(), lineNumber),
QTextCursor cursor(widget->document()->findBlockByLineNumber(lineNumber));
if (!cursor.atStart())
cursor.movePosition(QTextCursor::PreviousCharacter);
return TextEditor::AssistInterface(cursor,
widget->textDocument()->filePath(),
TextEditor::IdleEditor);
}

View File

@@ -105,9 +105,12 @@ public:
QStringList completions;
LanguageFeatures languageFeatures = LanguageFeatures::defaultFeatures();
languageFeatures.objCEnabled = false;
QTextCursor textCursor = m_editorWidget->textCursor();
textCursor.setPosition(m_position);
m_editorWidget->setTextCursor(textCursor);
CppCompletionAssistInterface *ai
= new CppCompletionAssistInterface(m_editorWidget->textDocument()->filePath(),
m_textDocument, m_position,
m_editorWidget,
ExplicitlyInvoked, m_snapshot,
ProjectExplorer::HeaderPaths(),
languageFeatures);

View File

@@ -426,7 +426,6 @@ AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
const Utils::FilePath &filePath,
const TextEditorWidget *textEditorWidget,
const LanguageFeatures &languageFeatures,
int position,
AssistReason reason) const
{
QTC_ASSERT(textEditorWidget, return nullptr);
@@ -435,7 +434,6 @@ AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
textEditorWidget,
BuiltinEditorDocumentParser::get(filePath.toString()),
languageFeatures,
position,
reason,
CppModelManager::instance()->workingCopy());
}

View File

@@ -87,7 +87,6 @@ public:
const Utils::FilePath &filePath,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason) const override;
};
@@ -168,10 +167,9 @@ public:
const TextEditor::TextEditorWidget *textEditorWidget,
BuiltinEditorDocumentParser::Ptr parser,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason,
const WorkingCopy &workingCopy)
: TextEditor::AssistInterface(textEditorWidget->document(), position, filePath, reason)
: TextEditor::AssistInterface(textEditorWidget->textCursor(), filePath, reason)
, m_parser(parser)
, m_gotCppSpecifics(false)
, m_workingCopy(workingCopy)
@@ -179,13 +177,12 @@ public:
{}
CppCompletionAssistInterface(const Utils::FilePath &filePath,
QTextDocument *textDocument,
int position,
const TextEditor::TextEditorWidget *textEditorWidget,
TextEditor::AssistReason reason,
const CPlusPlus::Snapshot &snapshot,
const ProjectExplorer::HeaderPaths &headerPaths,
const CPlusPlus::LanguageFeatures &features)
: TextEditor::AssistInterface(textDocument, position, filePath, reason)
: TextEditor::AssistInterface(textEditorWidget->textCursor(), filePath, reason)
, m_gotCppSpecifics(true)
, m_snapshot(snapshot)
, m_headerPaths(headerPaths)

View File

@@ -59,7 +59,6 @@ public:
const Utils::FilePath &filePath,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason) const = 0;
static int activationSequenceChar(const QChar &ch, const QChar &ch2,

View File

@@ -1312,7 +1312,6 @@ AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistR
return cap->createAssistInterface(textDocument()->filePath(),
this,
features,
position(),
reason);
} else {
return TextEditorWidget::createAssistInterface(kind, reason);

View File

@@ -74,10 +74,8 @@ IAssistProcessor *CppQuickFixAssistProvider::createProcessor(const AssistInterfa
// --------------------------
// CppQuickFixAssistInterface
// --------------------------
CppQuickFixInterface::CppQuickFixInterface(CppEditorWidget *editor,
AssistReason reason)
: AssistInterface(editor->document(), editor->position(),
editor->textDocument()->filePath(), reason)
CppQuickFixInterface::CppQuickFixInterface(CppEditorWidget *editor, AssistReason reason)
: AssistInterface(editor->textCursor(), editor->textDocument()->filePath(), reason)
, m_editor(editor)
, m_semanticInfo(editor->semanticInfo())
, m_snapshot(CppModelManager::instance()->snapshot())

View File

@@ -545,13 +545,12 @@ bool GlslCompletionAssistProcessor::acceptsIdleEditor() const
// -----------------------------
// GlslCompletionAssistInterface
// -----------------------------
GlslCompletionAssistInterface::GlslCompletionAssistInterface(QTextDocument *textDocument,
int position,
GlslCompletionAssistInterface::GlslCompletionAssistInterface(const QTextCursor &cursor,
const Utils::FilePath &fileName,
AssistReason reason,
const QString &mimeType,
const Document::Ptr &glslDoc)
: AssistInterface(textDocument, position, fileName, reason)
: AssistInterface(cursor, fileName, reason)
, m_mimeType(mimeType)
, m_glslDoc(glslDoc)
{

View File

@@ -107,8 +107,7 @@ private:
class GlslCompletionAssistInterface : public TextEditor::AssistInterface
{
public:
GlslCompletionAssistInterface(QTextDocument *textDocument,
int position, const Utils::FilePath &fileName,
GlslCompletionAssistInterface(const QTextCursor &cursor, const Utils::FilePath &fileName,
TextEditor::AssistReason reason,
const QString &mimeType,
const Document::Ptr &glslDoc);

View File

@@ -369,8 +369,7 @@ AssistInterface *GlslEditorWidget::createAssistInterface(
AssistKind kind, AssistReason reason) const
{
if (kind == Completion)
return new GlslCompletionAssistInterface(document(),
position(),
return new GlslCompletionAssistInterface(textCursor(),
textDocument()->filePath(),
reason,
textDocument()->mimeType(),

View File

@@ -103,7 +103,7 @@ TextEditor::AssistInterface *BindingEditorWidget::createAssistInterface(
{
Q_UNUSED(assistKind)
return new QmlJSEditor::QmlJSCompletionAssistInterface(
document(), position(), Utils::FilePath(),
textCursor(), Utils::FilePath(),
assistReason, qmljsdocument->semanticInfo());
}

View File

@@ -334,10 +334,11 @@ QStringList qmlJSAutoComplete(QTextDocument *textDocument,
{
QStringList list;
QmlJSCompletionAssistProcessor processor;
QTextCursor cursor(textDocument);
cursor.setPosition(position);
QScopedPointer<IAssistProposal> proposal(processor.perform( /* The processor takes ownership. */
new QmlJSCompletionAssistInterface(
textDocument,
position,
cursor,
fileName,
reason,
info)));
@@ -978,12 +979,11 @@ bool QmlJSCompletionAssistProcessor::completeUrl(const QString &relativeBasePath
// ------------------------------
// QmlJSCompletionAssistInterface
// ------------------------------
QmlJSCompletionAssistInterface::QmlJSCompletionAssistInterface(QTextDocument *textDocument,
int position,
QmlJSCompletionAssistInterface::QmlJSCompletionAssistInterface(const QTextCursor &cursor,
const Utils::FilePath &fileName,
AssistReason reason,
const SemanticInfo &info)
: AssistInterface(textDocument, position, fileName, reason)
: AssistInterface(cursor, fileName, reason)
, m_semanticInfo(info)
{}

View File

@@ -105,8 +105,7 @@ private:
class QMLJSEDITOR_EXPORT QmlJSCompletionAssistInterface : public TextEditor::AssistInterface
{
public:
QmlJSCompletionAssistInterface(QTextDocument *textDocument,
int position,
QmlJSCompletionAssistInterface(const QTextCursor &cursor,
const Utils::FilePath &fileName,
TextEditor::AssistReason reason,
const QmlJSTools::SemanticInfo &info);

View File

@@ -1021,11 +1021,8 @@ AssistInterface *QmlJSEditorWidget::createAssistInterface(
AssistReason reason) const
{
if (assistKind == Completion) {
return new QmlJSCompletionAssistInterface(document(),
position(),
textDocument()->filePath(),
reason,
m_qmlJsEditorDocument->semanticInfo());
return new QmlJSCompletionAssistInterface(textCursor(), textDocument()->filePath(),
reason, m_qmlJsEditorDocument->semanticInfo());
} else if (assistKind == QuickFix) {
return new Internal::QmlJSQuickFixAssistInterface(const_cast<QmlJSEditorWidget *>(this), reason);
}

View File

@@ -48,8 +48,7 @@ using namespace Internal;
// -----------------------
QmlJSQuickFixAssistInterface::QmlJSQuickFixAssistInterface(QmlJSEditorWidget *editor,
AssistReason reason)
: AssistInterface(editor->document(), editor->position(),
editor->textDocument()->filePath(), reason)
: AssistInterface(editor->textCursor(), editor->textDocument()->filePath(), reason)
, m_semanticInfo(editor->qmlJsEditorDocument()->semanticInfo())
, m_currentFile(QmlJSRefactoringChanges::file(editor, m_semanticInfo.document))
{}

View File

@@ -101,13 +101,14 @@ using namespace TextEditor;
namespace TextEditor {
AssistInterface::AssistInterface(QTextDocument *textDocument,
int position,
const Utils::FilePath &filePath,
AssistReason reason)
: m_textDocument(textDocument)
AssistInterface::AssistInterface(const QTextCursor &cursor,
const Utils::FilePath &filePath,
AssistReason reason)
: m_textDocument(cursor.document())
, m_cursor(cursor)
, m_isAsync(false)
, m_position(position)
, m_position(cursor.position())
, m_anchor(cursor.anchor())
, m_filePath(filePath)
, m_reason(reason)
{}
@@ -141,6 +142,9 @@ void AssistInterface::prepareForAsyncUse()
void AssistInterface::recreateTextDocument()
{
m_textDocument = new QTextDocument(m_text);
m_cursor = QTextCursor(m_textDocument);
m_cursor.setPosition(m_anchor);
m_cursor.setPosition(m_position, QTextCursor::KeepAnchor);
m_text.clear();
QTC_CHECK(m_textDocument->blockCount() == m_userStates.count());

View File

@@ -30,21 +30,17 @@
#include <texteditor/texteditor_global.h>
#include <QString>
#include <QTextCursor>
#include <QVector>
#include <utils/fileutils.h>
QT_BEGIN_NAMESPACE
class QTextDocument;
QT_END_NAMESPACE
namespace TextEditor {
class TEXTEDITOR_EXPORT AssistInterface
{
public:
AssistInterface(QTextDocument *textDocument,
int position,
AssistInterface(const QTextCursor &cursor,
const Utils::FilePath &filePath,
AssistReason reason);
virtual ~AssistInterface();
@@ -52,6 +48,7 @@ public:
virtual int position() const { return m_position; }
virtual QChar characterAt(int position) const;
virtual QString textAt(int position, int length) const;
QTextCursor cursor() const { return m_cursor; }
virtual Utils::FilePath filePath() const { return m_filePath; }
virtual QTextDocument *textDocument() const { return m_textDocument; }
virtual void prepareForAsyncUse();
@@ -60,8 +57,10 @@ public:
private:
QTextDocument *m_textDocument;
QTextCursor m_cursor;
bool m_isAsync;
int m_position;
int m_anchor;
Utils::FilePath m_filePath;
AssistReason m_reason;
QString m_text;

View File

@@ -8169,10 +8169,10 @@ void TextEditorWidget::invokeAssist(AssistKind kind, IAssistProvider *provider)
}
AssistInterface *TextEditorWidget::createAssistInterface(AssistKind kind,
AssistReason reason) const
AssistReason reason) const
{
Q_UNUSED(kind)
return new AssistInterface(document(), position(), d->m_document->filePath(), reason);
return new AssistInterface(textCursor(), d->m_document->filePath(), reason);
}
QString TextEditorWidget::foldReplacementText(const QTextBlock &) const