Commit 9a6c4a42 authored by hjk's avatar hjk

completion: enable multiple completors for different use cases.

Introduce CompletionPolicy enum, use 'TextCompletion' for the new plain
text completion, and 'SemanticCompletion' or 'QuickFixCompletion' for
the existing cases.

Reviewed-by: Erik Verbruggen
parent 43c980e6
......@@ -178,13 +178,11 @@ void CppPlugin::initializeEditor(CPPEditor *editor)
TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
// auto completion
connect(editor, SIGNAL(requestAutoCompletion(TextEditor::ITextEditable*, bool)),
TextEditor::CompletionSupport::instance(), SLOT(autoComplete(TextEditor::ITextEditable*, bool)));
// quick fix
connect(editor, SIGNAL(requestQuickFix(TextEditor::ITextEditable*)),
this, SLOT(quickFix(TextEditor::ITextEditable*)));
// semantic auto completion and quick fix
connect(editor,
SIGNAL(requestCompletion(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)),
TextEditor::CompletionSupport::instance(),
SLOT(complete(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)));
// method combo box sorting
connect(this, SIGNAL(outlineSortingChanged(bool)),
......@@ -408,7 +406,8 @@ void CppPlugin::quickFixNow()
if (editor->isOutdated())
m_quickFixTimer->start(QUICKFIX_INTERVAL);
else
TextEditor::CompletionSupport::instance()->quickFix(m_currentTextEditable);
TextEditor::CompletionSupport::instance()->
complete(m_currentTextEditable, TextEditor::QuickFixCompletion, true);
}
}
}
......
......@@ -54,7 +54,7 @@ CppQuickFixCollector::~CppQuickFixCollector()
{
}
bool CppQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editor)
bool CppQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editor) const
{
return CPlusPlus::CppModelManagerInterface::instance()->isCppEditor(editor);
}
......
......@@ -54,7 +54,7 @@ public:
CppQuickFixCollector();
virtual ~CppQuickFixCollector();
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool supportsEditor(TextEditor::ITextEditable *editor) const;
virtual TextEditor::QuickFixState *initializeCompletion(TextEditor::BaseTextEditor *editor);
virtual QList<TextEditor::QuickFixFactory *> quickFixFactories() const;
......
......@@ -653,8 +653,15 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
return start;
}
bool CppCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
{ return m_manager->isCppEditor(editor); }
bool CppCodeCompletion::supportsPolicy(TextEditor::CompletionPolicy policy) const
{
return policy == TextEditor::SemanticCompletion;
}
bool CppCodeCompletion::supportsEditor(TextEditor::ITextEditable *editor) const
{
return m_manager->isCppEditor(editor);
}
TextEditor::ITextEditable *CppCodeCompletion::editor() const
{ return m_editor; }
......
......@@ -79,7 +79,8 @@ public:
int startPosition() const;
bool shouldRestartCompletion();
QList<TextEditor::CompletionItem> getCompletions();
bool supportsEditor(TextEditor::ITextEditable *editor);
bool supportsEditor(TextEditor::ITextEditable *editor) const;
bool supportsPolicy(TextEditor::CompletionPolicy policy) const;
bool triggersCompletion(TextEditor::ITextEditable *editor);
int startCompletion(TextEditor::ITextEditable *editor);
void completions(QList<TextEditor::CompletionItem> *completions);
......
......@@ -492,8 +492,6 @@ public:
m_editor = 0;
}
virtual ~WordCompletion() {}
virtual bool shouldRestartCompletion()
{
//qDebug() << "SHOULD RESTART COMPLETION?";
......@@ -506,9 +504,20 @@ public:
return m_editable;
}
virtual int startPosition() const { return m_startPosition; }
virtual int startPosition() const
{
return m_startPosition;
}
virtual bool supportsEditor(ITextEditable *) { return true; }
virtual bool supportsEditor(ITextEditable *) const
{
return true;
}
virtual bool supportsPolicy(CompletionPolicy policy) const
{
return policy == TextCompletion;
}
virtual bool triggersCompletion(ITextEditable *editable)
{
......@@ -539,7 +548,7 @@ public:
m_editable = m_editor->editableInterface();
m_startPosition = m_editor->textCursor().position() - needle.size();
CompletionSupport::instance()->autoComplete(m_editable, false);
CompletionSupport::instance()->complete(m_editable, TextCompletion, false);
}
void setInactive()
......@@ -1173,7 +1182,7 @@ void FakeVimPluginPrivate::triggerCompletions()
return;
if (BaseTextEditor *editor = qobject_cast<BaseTextEditor *>(handler->widget()))
CompletionSupport::instance()->
autoComplete(editor->editableInterface(), false);
complete(editor->editableInterface(), TextCompletion, false);
// editor->triggerCompletions();
}
......
......@@ -395,12 +395,14 @@ int CodeCompletion::startPosition() const
return m_startPosition;
}
bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor) const
{
if (qobject_cast<GLSLTextEditor *>(editor->widget()) != 0)
return true;
return qobject_cast<GLSLTextEditor *>(editor->widget()) != 0;
}
return false;
bool CodeCompletion::supportsPolicy(TextEditor::CompletionPolicy policy) const
{
return policy == TextEditor::SemanticCompletion;
}
bool CodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
......
......@@ -56,7 +56,12 @@ public:
/*
* Returns true if this completion collector can be used with the given editor.
*/
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool supportsEditor(TextEditor::ITextEditable *editor) const;
/*
* Returns true if this completion collector supports the given completion policy.
*/
virtual bool supportsPolicy(TextEditor::CompletionPolicy policy) const;
/* This method should return whether the cursor is at a position which could
* trigger an autocomplete. It will be called each time a character is typed in
......
......@@ -250,13 +250,11 @@ void GLSLEditorPlugin::initializeEditor(GLSLEditor::GLSLTextEditor *editor)
TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
// // auto completion
connect(editor, SIGNAL(requestAutoCompletion(TextEditor::ITextEditable*, bool)),
TextEditor::CompletionSupport::instance(), SLOT(autoComplete(TextEditor::ITextEditable*, bool)));
// // quick fix
// connect(editor, SIGNAL(requestQuickFix(TextEditor::ITextEditable*)),
// this, SLOT(quickFix(TextEditor::ITextEditable*)));
// auto completion and quick fix
connect(editor,
SIGNAL(requestCompletion(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)),
TextEditor::CompletionSupport::instance(),
SLOT(autoComplete(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)));
}
......
......@@ -510,7 +510,7 @@ int CodeCompletion::startPosition() const
bool CodeCompletion::shouldRestartCompletion()
{ return m_restartCompletion; }
bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor) const
{
if (qobject_cast<QmlJSTextEditor *>(editor->widget()))
return true;
......@@ -518,6 +518,11 @@ bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
return false;
}
bool CodeCompletion::supportsPolicy(TextEditor::CompletionPolicy policy) const
{
return policy == TextEditor::SemanticCompletion;
}
bool CodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
{
if (maybeTriggersCompletion(editor)) {
......
......@@ -69,7 +69,8 @@ public:
virtual TextEditor::ITextEditable *editor() const;
virtual int startPosition() const;
virtual bool shouldRestartCompletion();
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool supportsEditor(TextEditor::ITextEditable *editor) const;
virtual bool supportsPolicy(TextEditor::CompletionPolicy policy) const;
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
virtual int startCompletion(TextEditor::ITextEditable *editor);
virtual void completions(QList<TextEditor::CompletionItem> *completions);
......
......@@ -272,13 +272,11 @@ void QmlJSEditorPlugin::initializeEditor(QmlJSEditor::QmlJSTextEditor *editor)
TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
// auto completion
connect(editor, SIGNAL(requestAutoCompletion(TextEditor::ITextEditable*, bool)),
TextEditor::CompletionSupport::instance(), SLOT(autoComplete(TextEditor::ITextEditable*, bool)));
// quick fix
connect(editor, SIGNAL(requestQuickFix(TextEditor::ITextEditable*)),
this, SLOT(quickFix(TextEditor::ITextEditable*)));
// auto completion and quick fix
connect(editor,
SIGNAL(requestCompletion(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)),
TextEditor::CompletionSupport::instance(),
SLOT(autoComplete(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)));
}
void QmlJSEditorPlugin::followSymbolUnderCursor()
......@@ -340,7 +338,8 @@ void QmlJSEditorPlugin::quickFixNow()
// ### FIXME: m_quickFixTimer->start(QUICKFIX_INTERVAL);
m_quickFixTimer->stop();
} else {
TextEditor::CompletionSupport::instance()->quickFix(m_currentTextEditable);
TextEditor::CompletionSupport::instance()
->complete(m_currentTextEditable, TextEditor::QuickFixCompletion, true);
}
}
}
......
......@@ -141,11 +141,16 @@ QmlJSQuickFixCollector::~QmlJSQuickFixCollector()
{
}
bool QmlJSQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editable)
bool QmlJSQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editable) const
{
return qobject_cast<QmlJSTextEditor *>(editable->widget()) != 0;
}
bool QmlJSQuickFixCollector::supportsPolicy(TextEditor::CompletionPolicy policy) const
{
return policy == TextEditor::QuickFixCompletion;
}
TextEditor::QuickFixState *QmlJSQuickFixCollector::initializeCompletion(TextEditor::BaseTextEditor *editor)
{
if (QmlJSTextEditor *qmljsEditor = qobject_cast<QmlJSTextEditor *>(editor)) {
......
......@@ -152,7 +152,8 @@ public:
QmlJSQuickFixCollector();
virtual ~QmlJSQuickFixCollector();
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool supportsEditor(TextEditor::ITextEditable *editor) const;
virtual bool supportsPolicy(TextEditor::CompletionPolicy policy) const;
virtual TextEditor::QuickFixState *initializeCompletion(TextEditor::BaseTextEditor *editor);
virtual QList<TextEditor::QuickFixFactory *> quickFixFactories() const;
......
......@@ -78,11 +78,14 @@ int ProFileCompletion::startPosition() const
return m_startPosition;
}
bool ProFileCompletion::supportsEditor(TextEditor::ITextEditable *editor)
bool ProFileCompletion::supportsEditor(TextEditor::ITextEditable *editor) const
{
if (qobject_cast<ProFileEditorEditable *>(editor))
return true;
return false;
return qobject_cast<ProFileEditorEditable *>(editor) != 0;
}
bool ProFileCompletion::supportsPolicy(TextEditor::CompletionPolicy policy) const
{
return policy == TextEditor::SemanticCompletion;
}
bool ProFileCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
......
......@@ -54,7 +54,8 @@ public:
virtual TextEditor::ITextEditable *editor() const;
virtual int startPosition() const;
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool supportsEditor(TextEditor::ITextEditable *editor) const;
virtual bool supportsPolicy(TextEditor::CompletionPolicy policy) const;
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
virtual int startCompletion(TextEditor::ITextEditable *editor);
virtual void completions(QList<TextEditor::CompletionItem> *completions);
......
......@@ -92,8 +92,10 @@ Core::IEditor *ProFileEditorFactory::createEditor(QWidget *parent)
TextEditor::TextEditorSettings::instance()->initializeEditor(editor);
// auto completion
connect(editor, SIGNAL(requestAutoCompletion(TextEditor::ITextEditable*, bool)),
TextEditor::CompletionSupport::instance(), SLOT(autoComplete(TextEditor::ITextEditable*, bool)));
connect(editor,
SIGNAL(requestCompletion(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)),
TextEditor::CompletionSupport::instance(),
SLOT(autoComplete(TextEditor::ITextEditable*,TextEditor::CompletionPolicy,bool)));
return editor->editableInterface();
}
......
......@@ -540,12 +540,12 @@ void BaseTextEditor::selectEncoding()
void BaseTextEditor::triggerCompletions()
{
emit requestAutoCompletion(editableInterface(), true);
emit requestCompletion(editableInterface(), TextEditor::SemanticCompletion, true);
}
void BaseTextEditor::triggerQuickFix()
{
emit requestQuickFix(editableInterface());
emit requestCompletion(editableInterface(), TextEditor::QuickFixCompletion, true);
}
QString BaseTextEditor::msgTextTooLarge(quint64 size)
......@@ -1851,7 +1851,7 @@ void BaseTextEditor::maybeRequestAutoCompletion(const QChar &ch)
}
} else {
d->m_requestAutoCompletionTimer->stop();
emit requestAutoCompletion(editableInterface(), false);
emit requestCompletion(editableInterface(), TextEditor::SemanticCompletion, false);
}
}
......@@ -1864,7 +1864,7 @@ void BaseTextEditor::_q_requestAutoCompletion()
if (d->m_requestAutoCompletionRevision == document()->revision() &&
d->m_requestAutoCompletionPosition == position())
emit requestAutoCompletion(editableInterface(), false);
emit requestCompletion(editableInterface(), TextEditor::SemanticCompletion, false);
}
void BaseTextEditor::insertCodeSnippet(const QTextCursor &cursor_arg, const QString &snippet)
......
......@@ -35,6 +35,7 @@
#define BASETEXTEDITOR_H
#include "itexteditable.h"
#include "icompletioncollector.h"
#include <find/ifindsupport.h>
......@@ -483,8 +484,8 @@ signals:
void requestFontZoom(int zoom);
void requestZoomReset();
void requestBlockUpdate(const QTextBlock &);
void requestAutoCompletion(TextEditor::ITextEditable *editor, bool forced);
void requestQuickFix(TextEditor::ITextEditable *editor);
void requestCompletion(TextEditor::ITextEditable *editor,
TextEditor::CompletionPolicy, bool forced);
private:
void maybeRequestAutoCompletion(const QChar &ch);
......
......@@ -67,7 +67,7 @@ private slots:
public:
QList<CompletionItem> getCompletions() const;
void autoComplete_helper(ITextEditable *editor, bool forced, bool quickFix);
void complete(ITextEditable *editor, CompletionPolicy policy, bool forced);
CompletionSupport *m_support;
Internal::CompletionWidget *m_completionList;
......@@ -76,6 +76,7 @@ public:
ITextEditable *m_editor;
const QList<ICompletionCollector *> m_completionCollectors;
ICompletionCollector *m_completionCollector;
CompletionPolicy m_policy;
};
CompletionSupportPrivate::CompletionSupportPrivate(CompletionSupport *support) :
......@@ -86,7 +87,8 @@ CompletionSupportPrivate::CompletionSupportPrivate(CompletionSupport *support) :
m_editor(0),
m_completionCollectors(ExtensionSystem::PluginManager::instance()
->getObjects<ICompletionCollector>()),
m_completionCollector(0)
m_completionCollector(0),
m_policy(SemanticCompletion)
{
}
......@@ -131,7 +133,7 @@ void CompletionSupportPrivate::cleanupCompletions()
// Only check for completion trigger when some text was entered
if (m_editor->position() > m_startPosition)
autoComplete_helper(m_editor, false, /*quickFix = */ false);
complete(m_editor, m_policy, false);
}
}
......@@ -140,28 +142,25 @@ bool CompletionSupport::isActive() const
return d->m_completionList != 0;
}
void CompletionSupport::autoComplete(ITextEditable *editor, bool forced)
CompletionPolicy CompletionSupport::policy() const
{
d->autoComplete_helper(editor, forced, /*quickFix = */ false);
return d->m_policy;
}
void CompletionSupport::quickFix(ITextEditable *editor)
void CompletionSupport::complete(ITextEditable *editor, CompletionPolicy policy, bool forced)
{
d->autoComplete_helper(editor,
/*forced = */ true,
/*quickFix = */ true);
d->complete(editor, policy, forced);
}
void CompletionSupportPrivate::autoComplete_helper(ITextEditable *editor,
bool forced, bool quickFix)
void CompletionSupportPrivate::complete(ITextEditable *editor, CompletionPolicy policy, bool forced)
{
m_completionCollector = 0;
m_completionCollector = 0;
foreach (ICompletionCollector *collector, m_completionCollectors) {
if (quickFix)
collector = qobject_cast<IQuickFixCollector *>(collector);
if (collector && collector->supportsEditor(editor)) {
QTC_ASSERT(collector, continue);
if (collector->supportsEditor(editor)
&& collector->supportsPolicy(policy)) {
m_policy = policy;
m_completionCollector = collector;
break;
}
......@@ -195,7 +194,6 @@ void CompletionSupportPrivate::autoComplete_helper(ITextEditable *editor,
}
m_completionList = new Internal::CompletionWidget(m_support, editor);
m_completionList->setQuickFix(quickFix);
connect(m_completionList, SIGNAL(itemSelected(TextEditor::CompletionItem)),
this, SLOT(performCompletion(TextEditor::CompletionItem)));
......
......@@ -35,6 +35,7 @@
#define COMPLETIONSUPPORT_H
#include <texteditor/texteditor_global.h>
#include <texteditor/icompletioncollector.h>
#include <QtCore/QObject>
......@@ -56,10 +57,11 @@ public:
static CompletionSupport *instance();
bool isActive() const;
CompletionPolicy policy() const;
public slots:
void autoComplete(TextEditor::ITextEditable *editor, bool forced);
void quickFix(TextEditor::ITextEditable *editor);
void complete(TextEditor::ITextEditable *editor,
TextEditor::CompletionPolicy policy, bool forced);
private:
CompletionSupport();
......
......@@ -179,11 +179,6 @@ CompletionWidget::~CompletionWidget()
{
}
void CompletionWidget::setQuickFix(bool quickFix)
{
m_completionListView->setQuickFix(quickFix);
}
void CompletionWidget::setCompletionItems(const QList<TextEditor::CompletionItem> &completionitems)
{
m_completionListView->setCompletionItems(completionitems);
......@@ -271,7 +266,6 @@ void CompletionWidget::updatePositionAndSize(int startPos)
CompletionListView::CompletionListView(CompletionSupport *support, ITextEditable *editor, CompletionWidget *completionWidget)
: QListView(completionWidget),
m_blockFocusOut(false),
m_quickFix(false),
m_editor(editor),
m_editorWidget(editor->widget()),
m_completionWidget(completionWidget),
......@@ -455,7 +449,8 @@ bool CompletionListView::event(QEvent *e)
break;
}
if (forwardKeys && ! m_quickFix) {
const CompletionPolicy policy = m_support->policy();
if (forwardKeys && policy != QuickFixCompletion) {
if (ke->text().length() == 1 && currentIndex().isValid() && qApp->focusWidget() == this) {
QChar typedChar = ke->text().at(0);
const CompletionItem &item = m_model->itemAt(currentIndex());
......@@ -471,7 +466,7 @@ bool CompletionListView::event(QEvent *e)
m_blockFocusOut = false;
// Have the completion support update the list of items
m_support->autoComplete(m_editor, false);
m_support->complete(m_editor, policy, false);
return true;
}
......@@ -484,11 +479,6 @@ void CompletionListView::keyboardSearch(const QString &search)
Q_UNUSED(search)
}
void CompletionListView::setQuickFix(bool quickFix)
{
m_quickFix = quickFix;
}
void CompletionListView::setCompletionItems(const QList<TextEditor::CompletionItem> &completionItems)
{
m_model->setItems(completionItems);
......
......@@ -61,7 +61,6 @@ public:
CompletionWidget(CompletionSupport *support, ITextEditable *editor);
~CompletionWidget();
void setQuickFix(bool quickFix);
void setCompletionItems(const QList<TextEditor::CompletionItem> &completionitems);
void showCompletions(int startPos);
......@@ -111,16 +110,15 @@ private:
CompletionListView(CompletionSupport *support, ITextEditable *editor, CompletionWidget *completionWidget);
void setQuickFix(bool quickFix);
void setCompletionItems(const QList<TextEditor::CompletionItem> &completionitems);
void keyboardSearch(const QString &search);
void closeList(const QModelIndex &index);
private slots:
void maybeShowInfoTip();
private:
private:
bool m_blockFocusOut;
bool m_quickFix;
ITextEditable *m_editor;
QWidget *m_editorWidget;
CompletionWidget *m_completionWidget;
......
......@@ -50,6 +50,13 @@ class ICompletionCollector;
class ITextEditable;
class CompletionSettings;
enum CompletionPolicy
{
QuickFixCompletion, // Used for "Quick Fix" operation.
TextCompletion, // Plain word completion.
SemanticCompletion // Completion using code models.
};
class CompletionItem
{
public:
......@@ -99,7 +106,12 @@ public:
/*
* Returns true if this completion collector can be used with the given editor.
*/
virtual bool supportsEditor(ITextEditable *editor) = 0;
virtual bool supportsEditor(ITextEditable *editor) const = 0;
/*
* Returns true if this completion collector supports the given completion policy.
*/
virtual bool supportsPolicy(CompletionPolicy policy) const = 0;
/* This method should return whether the cursor is at a position which could
* trigger an autocomplete. It will be called each time a character is typed in
......
......@@ -161,6 +161,9 @@ public:
virtual int startCompletion(TextEditor::ITextEditable *editor);
virtual void completions(QList<TextEditor::CompletionItem> *completions);
virtual bool supportsPolicy(TextEditor::CompletionPolicy policy) const
{ return policy == TextEditor::QuickFixCompletion; }
/// See IQuickFixCollector::fix
virtual void fix(const TextEditor::CompletionItem &item);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment