Commit d55ae4a3 authored by Denis Steckelmacher's avatar Denis Steckelmacher

Provide completion items for import statements

All the available modules (and their versions) are listed when the user types
"import".
parent e77544cc
......@@ -5,6 +5,7 @@ include_directories(
set(completion_SRCS
completionitem.cpp
modulecompletionitem.cpp
context.cpp
model.cpp
worker.cpp
......
......@@ -22,6 +22,7 @@
#include "context.h"
#include "completionitem.h"
#include "modulecompletionitem.h"
#include <language/codecompletion/codecompletionitem.h>
#include <language/codecompletion/normaldeclarationcompletionitem.h>
......@@ -30,12 +31,15 @@
#include <language/duchain/classdeclaration.h>
#include <language/duchain/namespacealiasdeclaration.h>
#include <language/duchain/codemodel.h>
#include <kstandarddirs.h>
#include <qmljs/qmljsdocument.h>
#include <qmljs/parser/qmljslexer_p.h>
#include <duchain/expressionvisitor.h>
#include <duchain/helper.h>
#include <QtCore/QDir>
using namespace KDevelop;
typedef QPair<Declaration*, int> DeclarationDepthPair;
......@@ -47,6 +51,11 @@ CodeCompletionContext::CodeCompletionContext(const DUContextPointer& context, co
: KDevelop::CodeCompletionContext(context, extractLastLine(text), position, depth),
m_completionKind(NormalCompletion)
{
// Detect "import ..." and provide import completions
if (m_text.startsWith("import ")) {
m_completionKind = ImportCompletion;
}
// Detect whether the cursor is in a comment
bool isLastLine = true;
......@@ -77,15 +86,23 @@ QList<CompletionTreeItemPointer> CodeCompletionContext::completionItems(bool& ab
{
Q_UNUSED (fullCompletion);
// Compute the completion items, based on the surrounding text and the
// type of completion to offer in the constructor
QList<CompletionTreeItemPointer> items;
if (abort) {
return QList<CompletionTreeItemPointer>();
}
if (abort || m_completionKind == CommentCompletion) {
return items;
switch (m_completionKind) {
case NormalCompletion:
return normalCompletion();
case CommentCompletion:
return commentCompletion();
case ImportCompletion:
return importCompletion();
}
}
QList<KDevelop::CompletionTreeItemPointer> CodeCompletionContext::normalCompletion()
{
QList<CompletionTreeItemPointer> items;
QChar lastChar = m_text.size() > 0 ? m_text.at(m_text.size() - 1) : QLatin1Char('\0');
if (lastChar == QLatin1Char('.') || lastChar == QLatin1Char('[')) {
......@@ -123,6 +140,29 @@ QList<CompletionTreeItemPointer> CodeCompletionContext::completionItems(bool& ab
return items;
}
QList<CompletionTreeItemPointer> CodeCompletionContext::commentCompletion()
{
return QList<CompletionTreeItemPointer>();
}
QList<CompletionTreeItemPointer> CodeCompletionContext::importCompletion()
{
QList<CompletionTreeItemPointer> items;
// List $KDEDATA/kdevqmljssupport/qmlplugins/ and add one completion item
// per file found there
QString dataDir = KGlobal::dirs()->findDirs("data",
QLatin1String("kdevqmljssupport/qmlplugins")
).at(0);
QDir dir(dataDir);
for (const QString &entry : dir.entryList(QDir::Files, QDir::Name)) {
items.append(CompletionTreeItemPointer(new ModuleCompletionItem(entry)));
}
return items;
}
QList<CompletionTreeItemPointer> CodeCompletionContext::completionsInContext(const DUContextPointer& context,
CompletionInContextFlags flags,
CompletionItem::Decoration decoration)
......
......@@ -45,6 +45,10 @@ public:
Q_DECLARE_FLAGS(CompletionInContextFlags, CompletionInContextFlag)
private:
QList<KDevelop::CompletionTreeItemPointer> normalCompletion();
QList<KDevelop::CompletionTreeItemPointer> commentCompletion();
QList<KDevelop::CompletionTreeItemPointer> importCompletion();
QList<KDevelop::CompletionTreeItemPointer> completionsInContext(const KDevelop::DUContextPointer& context,
CompletionInContextFlags flags,
CompletionItem::Decoration decoration);
......@@ -57,6 +61,7 @@ private:
enum CompletionKind {
NormalCompletion, /*!< @brief Completion in a code context */
CommentCompletion, /*!< @brief Completion in comments */
ImportCompletion, /*!< @brief Completion for import statements */
};
CompletionKind m_completionKind;
......
/*
* This file is part of qmljs, the QML/JS language support plugin for KDevelop
* Copyright (c) 2014 Denis Steckelmacher <steckdenis@yahoo.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "modulecompletionitem.h"
#include <language/codecompletion/codecompletionmodel.h>
#include <language/duchain/duchainutils.h>
#include <ktexteditor/document.h>
#include <QIcon>
using namespace KDevelop;
QmlJS::ModuleCompletionItem::ModuleCompletionItem(const QString& name)
{
QStringList nameAndVersion = name
.section(QLatin1Char('.'), 0, -2)
.split(QLatin1Char('_'));
m_name = nameAndVersion.at(0);
m_version = (nameAndVersion.count() > 1 ? nameAndVersion.at(1) : QLatin1String("1.0"));
}
int QmlJS::ModuleCompletionItem::argumentHintDepth() const
{
return 0;
}
int QmlJS::ModuleCompletionItem::inheritanceDepth() const
{
return m_name.count(QLatin1Char('.'));
}
CodeCompletionModel::CompletionProperties QmlJS::ModuleCompletionItem::completionProperties() const
{
return CodeCompletionModel::Namespace;
}
QVariant QmlJS::ModuleCompletionItem::data(const QModelIndex& index, int role, const KDevelop::CodeCompletionModel* model) const
{
Q_UNUSED(model)
switch (role) {
case CodeCompletionModel::IsExpandable:
return QVariant(false);
case Qt::DisplayRole:
switch (index.column()) {
case CodeCompletionModel::Prefix:
return QLatin1String("module");
case CodeCompletionModel::Name:
return m_name;
case CodeCompletionModel::Postfix:
return m_version;
}
break;
case CodeCompletionModel::CompletionRole:
return (int)completionProperties();
case Qt::DecorationRole:
if(index.column() == CodeCompletionModel::Icon) {
CodeCompletionModel::CompletionProperties p = completionProperties();
return DUChainUtils::iconForProperties(p);
}
break;
}
return QVariant();
}
void QmlJS::ModuleCompletionItem::execute(KTextEditor::Document* document, const KTextEditor::Range& word)
{
// Replace the whole line with an import statement
document->replaceText(
KTextEditor::Range(word.start().line(), 0, word.start().line(), INT_MAX),
QString("import %1 %2").arg(m_name, m_version)
);
}
/*
* This file is part of qmljs, the QML/JS language support plugin for KDevelop
* Copyright (c) 2014 Denis Steckelmacher <steckdenis@yahoo.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __MODULECOMPLETIONITEM_H__
#define __MODULECOMPLETIONITEM_H__
#include <language/codecompletion/codecompletionitem.h>
namespace QmlJS {
class ModuleCompletionItem : public KDevelop::CompletionTreeItem
{
public:
ModuleCompletionItem(const QString &name);
virtual QVariant data(const QModelIndex& index, int role, const KDevelop::CodeCompletionModel* model) const;
virtual int inheritanceDepth() const;
virtual int argumentHintDepth() const;
virtual KTextEditor::CodeCompletionModel::CompletionProperties completionProperties() const;
virtual void execute(KTextEditor::Document* document, const KTextEditor::Range& word);
private:
QString m_name;
QString m_version;
};
}
#endif
\ No newline at end of file
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