CMake: add auto completion for cmake editor

Original Patch by tomdeblauwe <tdb@traficon.be>

Change-Id: I54aea31755dd5702e6998c8343114d34a8752f7b
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
tomdeblauwe
2012-09-06 22:38:25 +08:00
committed by Daniel Teske
parent 16f272e0f6
commit 76f69d0e2e
22 changed files with 1154 additions and 721 deletions

View File

@@ -0,0 +1,57 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cmakefilecompletionassist.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectmanager.h"
#include <texteditor/codeassist/keywordscompletionassist.h>
using namespace CMakeProjectManager::Internal;
using namespace TextEditor;
// -------------------------------
// CMakeFileCompletionAssistProvider
// -------------------------------
CMakeFileCompletionAssistProvider::CMakeFileCompletionAssistProvider(CMakeSettingsPage *settingsPage)
: m_settingsPage(settingsPage)
{}
CMakeFileCompletionAssistProvider::~CMakeFileCompletionAssistProvider()
{}
bool CMakeFileCompletionAssistProvider::supportsEditor(const Core::Id &editorId) const
{
return editorId == CMakeProjectManager::Constants::CMAKE_EDITOR_ID;
}
IAssistProcessor *CMakeFileCompletionAssistProvider::createProcessor() const
{
return new KeywordsCompletionAssistProcessor(m_settingsPage->keywords());
}

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CMAKEFILECOMPLETIONASSIST_H
#define CMAKEFILECOMPLETIONASSIST_H
#include <texteditor/codeassist/completionassistprovider.h>
namespace CMakeProjectManager {
namespace Internal {
class CMakeSettingsPage;
class CMakeFileCompletionAssistProvider : public TextEditor::CompletionAssistProvider
{
public:
CMakeFileCompletionAssistProvider(CMakeSettingsPage *settingsPage);
~CMakeFileCompletionAssistProvider();
bool supportsEditor(const Core::Id &editorId) const;
TextEditor::IAssistProcessor *createProcessor() const;
private:
CMakeSettingsPage *m_settingsPage;
};
} // Internal
} // CMakeProjectManager
#endif // CMAKEFILECOMPLETIONASSIST_H

View File

@@ -250,102 +250,26 @@ CMakeSettingsPage::CMakeSettingsPage()
ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_TR_CATEGORY));
setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON));
m_userCmake.process = 0;
m_pathCmake.process = 0;
m_userCmake.hasCodeBlocksMsvcGenerator = false;
m_pathCmake.hasCodeBlocksMsvcGenerator = false;
m_userCmake.hasCodeBlocksNinjaGenerator = false;
m_pathCmake.hasCodeBlocksNinjaGenerator = false;
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String("CMakeSettings"));
m_userCmake.executable = settings->value(QLatin1String("cmakeExecutable")).toString();
m_cmakeValidatorForUser.setCMakeExecutable(settings->value(QLatin1String("cmakeExecutable")).toString());
settings->endGroup();
updateInfo(&m_userCmake);
m_pathCmake.executable = findCmakeExecutable();
updateInfo(&m_pathCmake);
}
void CMakeSettingsPage::startProcess(CMakeValidator *cmakeValidator)
{
cmakeValidator->process = new QProcess();
if (cmakeValidator == &m_pathCmake) // ugly
connect(cmakeValidator->process, SIGNAL(finished(int)),
this, SLOT(userCmakeFinished()));
else
connect(cmakeValidator->process, SIGNAL(finished(int)),
this, SLOT(pathCmakeFinished()));
cmakeValidator->process->start(cmakeValidator->executable, QStringList(QLatin1String("--help")));
cmakeValidator->process->waitForStarted();
}
void CMakeSettingsPage::userCmakeFinished()
{
cmakeFinished(&m_userCmake);
}
void CMakeSettingsPage::pathCmakeFinished()
{
cmakeFinished(&m_pathCmake);
}
void CMakeSettingsPage::cmakeFinished(CMakeValidator *cmakeValidator) const
{
if (cmakeValidator->process) {
cmakeValidator->process->waitForFinished();
QString response = cmakeValidator->process->readAll();
QRegExp versionRegexp(QLatin1String("^cmake version ([\\d\\.]*)"));
versionRegexp.indexIn(response);
//m_supportsQtCreator = response.contains(QLatin1String("QtCreator"));
cmakeValidator->hasCodeBlocksNinjaGenerator = response.contains(QLatin1String("CodeBlocks - Ninja"));
cmakeValidator->hasCodeBlocksMsvcGenerator = response.contains(QLatin1String("CodeBlocks - NMake Makefiles"));
cmakeValidator->version = versionRegexp.cap(1);
if (!(versionRegexp.capturedTexts().size() > 3))
cmakeValidator->version += QLatin1Char('.') + versionRegexp.cap(3);
if (cmakeValidator->version.isEmpty())
cmakeValidator->state = CMakeValidator::INVALID;
else
cmakeValidator->state = CMakeValidator::VALID;
cmakeValidator->process->deleteLater();
cmakeValidator->process = 0;
}
m_cmakeValidatorForSystem.setCMakeExecutable(findCmakeExecutable());
}
bool CMakeSettingsPage::isCMakeExecutableValid() const
{
if (m_userCmake.state == CMakeValidator::RUNNING) {
disconnect(m_userCmake.process, SIGNAL(finished(int)),
this, SLOT(userCmakeFinished()));
m_userCmake.process->waitForFinished();
// Parse the output now
cmakeFinished(&m_userCmake);
}
if (m_userCmake.state == CMakeValidator::VALID)
if (m_cmakeValidatorForUser.isValid())
return true;
if (m_pathCmake.state == CMakeValidator::RUNNING) {
disconnect(m_userCmake.process, SIGNAL(finished(int)),
this, SLOT(pathCmakeFinished()));
m_pathCmake.process->waitForFinished();
// Parse the output now
cmakeFinished(&m_pathCmake);
}
return m_pathCmake.state == CMakeValidator::VALID;
return m_cmakeValidatorForSystem.isValid();
}
CMakeSettingsPage::~CMakeSettingsPage()
{
if (m_userCmake.process)
m_userCmake.process->waitForFinished();
delete m_userCmake.process;
if (m_pathCmake.process)
m_pathCmake.process->waitForFinished();
delete m_pathCmake.process;
m_cmakeValidatorForUser.cancel();
m_cmakeValidatorForSystem.cancel();
}
QString CMakeSettingsPage::findCmakeExecutable() const
@@ -363,28 +287,15 @@ QWidget *CMakeSettingsPage::createPage(QWidget *parent)
m_pathchooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
formLayout->addRow(tr("Executable:"), m_pathchooser);
formLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
m_pathchooser->setPath(m_userCmake.executable);
m_pathchooser->setPath(m_cmakeValidatorForUser.cmakeExecutable());
return outerWidget;
}
void CMakeSettingsPage::updateInfo(CMakeValidator *cmakeValidator)
{
QFileInfo fi(cmakeValidator->executable);
if (fi.exists() && fi.isExecutable()) {
// Run it to find out more
cmakeValidator->state = CMakeValidator::RUNNING;
startProcess(cmakeValidator);
} else {
cmakeValidator->state = CMakeValidator::INVALID;
}
saveSettings();
}
void CMakeSettingsPage::saveSettings() const
{
QSettings *settings = Core::ICore::settings();
settings->beginGroup(QLatin1String("CMakeSettings"));
settings->setValue(QLatin1String("cmakeExecutable"), m_userCmake.executable);
settings->setValue(QLatin1String("cmakeExecutable"), m_cmakeValidatorForUser.cmakeExecutable());
settings->endGroup();
}
@@ -392,10 +303,10 @@ void CMakeSettingsPage::apply()
{
if (!m_pathchooser) // page was never shown
return;
if (m_userCmake.executable == m_pathchooser->path())
if (m_cmakeValidatorForUser.cmakeExecutable() == m_pathchooser->path())
return;
m_userCmake.executable = m_pathchooser->path();
updateInfo(&m_userCmake);
m_cmakeValidatorForUser.setCMakeExecutable(m_pathchooser->path());
saveSettings();
}
void CMakeSettingsPage::finish()
@@ -407,36 +318,46 @@ QString CMakeSettingsPage::cmakeExecutable() const
{
if (!isCMakeExecutableValid())
return QString();
if (m_userCmake.state == CMakeValidator::VALID)
return m_userCmake.executable;
else
return m_pathCmake.executable;
if (m_cmakeValidatorForUser.isValid())
return m_cmakeValidatorForUser.cmakeExecutable();
if (m_cmakeValidatorForSystem.isValid())
return m_cmakeValidatorForSystem.cmakeExecutable();
return QString();
}
void CMakeSettingsPage::setCMakeExecutable(const QString &executable)
{
if (m_userCmake.executable == executable)
if (m_cmakeValidatorForUser.cmakeExecutable() == executable)
return;
m_userCmake.executable = executable;
updateInfo(&m_userCmake);
m_cmakeValidatorForUser.setCMakeExecutable(executable);
}
bool CMakeSettingsPage::hasCodeBlocksMsvcGenerator() const
{
if (!isCMakeExecutableValid())
return false;
if (m_userCmake.state == CMakeValidator::VALID)
return m_userCmake.hasCodeBlocksMsvcGenerator;
else
return m_pathCmake.hasCodeBlocksMsvcGenerator;
if (m_cmakeValidatorForUser.isValid())
return m_cmakeValidatorForUser.hasCodeBlocksMsvcGenerator();
if (m_cmakeValidatorForSystem.isValid())
return m_cmakeValidatorForSystem.hasCodeBlocksMsvcGenerator();
return false;
}
bool CMakeSettingsPage::hasCodeBlocksNinjaGenerator() const
{
if (!isCMakeExecutableValid())
return false;
if (m_userCmake.state == CMakeValidator::VALID)
return m_userCmake.hasCodeBlocksNinjaGenerator;
else
return m_pathCmake.hasCodeBlocksNinjaGenerator;
if (m_cmakeValidatorForUser.isValid())
return m_cmakeValidatorForUser.hasCodeBlocksNinjaGenerator();
if (m_cmakeValidatorForSystem.isValid())
return m_cmakeValidatorForSystem.hasCodeBlocksNinjaGenerator();
return false;
}
TextEditor::Keywords CMakeSettingsPage::keywords()
{
if (m_cmakeValidatorForUser.isValid())
return m_cmakeValidatorForUser.keywords();
if (m_cmakeValidatorForSystem.isValid())
return m_cmakeValidatorForSystem.keywords();
return TextEditor::Keywords(QStringList(), QStringList(), QMap<QString, QStringList>());
}

View File

@@ -35,6 +35,7 @@
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <coreplugin/icontext.h>
#include <texteditor/codeassist/keywordscompletionassist.h>
#include <utils/environment.h>
#include <utils/pathchooser.h>
@@ -42,9 +43,11 @@
#include <QFuture>
#include <QStringList>
#include <QDir>
#include <QVector>
#include <QAction>
QT_FORWARD_DECLARE_CLASS(QProcess)
#include "cmakevalidator.h"
QT_FORWARD_DECLARE_CLASS(QLabel)
namespace Utils {
@@ -95,17 +98,6 @@ private:
ProjectExplorer::Project *m_contextProject;
};
struct CMakeValidator
{
enum STATE { VALID, INVALID, RUNNING };
STATE state;
QProcess *process;
bool hasCodeBlocksMsvcGenerator;
bool hasCodeBlocksNinjaGenerator;
QString version;
QString executable;
};
class CMakeSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
@@ -124,20 +116,15 @@ public:
bool hasCodeBlocksMsvcGenerator() const;
bool hasCodeBlocksNinjaGenerator() const;
private slots:
void userCmakeFinished();
void pathCmakeFinished();
TextEditor::Keywords keywords();
private:
void cmakeFinished(CMakeValidator *cmakeValidator) const;
void saveSettings() const;
QString findCmakeExecutable() const;
void startProcess(CMakeValidator *cmakeValidator);
void updateInfo(CMakeValidator *cmakeValidator);
Utils::PathChooser *m_pathchooser;
mutable CMakeValidator m_userCmake;
mutable CMakeValidator m_pathCmake;
CMakeValidator m_cmakeValidatorForUser;
CMakeValidator m_cmakeValidatorForSystem;
};
} // namespace Internal

View File

@@ -17,7 +17,9 @@ HEADERS = cmakeproject.h \
cmakeeditor.h \
cmakehighlighter.h \
cmakeuicodemodelsupport.h \
cmakelocatorfilter.h
cmakelocatorfilter.h \
cmakefilecompletionassist.h \
cmakevalidator.h
SOURCES = cmakeproject.cpp \
cmakeprojectplugin.cpp \
@@ -31,7 +33,9 @@ SOURCES = cmakeproject.cpp \
cmakeeditor.cpp \
cmakehighlighter.cpp \
cmakeuicodemodelsupport.cpp \
cmakelocatorfilter.cpp
cmakelocatorfilter.cpp \
cmakefilecompletionassist.cpp \
cmakevalidator.cpp
RESOURCES += cmakeproject.qrc

View File

@@ -22,6 +22,8 @@ QtcPlugin {
"cmakeeditor.h",
"cmakeeditorfactory.cpp",
"cmakeeditorfactory.h",
"cmakefilecompletionassist.cpp",
"cmakefilecompletionassist.h",
"cmakehighlighter.cpp",
"cmakehighlighter.h",
"cmakelocatorfilter.cpp",
@@ -42,6 +44,8 @@ QtcPlugin {
"cmakerunconfiguration.h",
"cmakeuicodemodelsupport.cpp",
"cmakeuicodemodelsupport.h",
"cmakevalidator.cpp",
"cmakevalidator.h",
"makestep.cpp",
"makestep.h",
]

View File

@@ -35,6 +35,7 @@
#include "makestep.h"
#include "cmakeprojectconstants.h"
#include "cmakelocatorfilter.h"
#include "cmakefilecompletionassist.h"
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
@@ -68,7 +69,7 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
addAutoReleasedObject(new CMakeEditorFactory(manager));
addAutoReleasedObject(new CMakeLocatorFilter);
addAutoReleasedObject(new CMakeFileCompletionAssistProvider(cmp));
return true;
}

View File

@@ -0,0 +1,262 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "cmakevalidator.h"
#include <QProcess>
#include <QFileInfo>
#include <QTextDocument>
using namespace CMakeProjectManager::Internal;
///////////////////////////
// CMakeValidator
///////////////////////////
CMakeValidator::CMakeValidator()
: m_state(Invalid), m_process(0), m_hasCodeBlocksMsvcGenerator(false), m_hasCodeBlocksNinjaGenerator(false)
{
}
CMakeValidator::~CMakeValidator()
{
cancel();
}
void CMakeValidator::cancel()
{
if (m_process) {
disconnect(m_process, SIGNAL(finished(int)));
m_process->waitForFinished();
delete m_process;
m_process = 0;
}
}
void CMakeValidator::setCMakeExecutable(const QString &executable)
{
cancel();
m_process = new QProcess();
connect(m_process, SIGNAL(finished(int)),
this, SLOT(finished(int)));
m_executable = executable;
QFileInfo fi(m_executable);
if (fi.exists() && fi.isExecutable()) {
// Run it to find out more
m_state = CMakeValidator::RunningBasic;
if (!startProcess(QStringList(QLatin1String("--help"))))
m_state = CMakeValidator::Invalid;
} else {
m_state = CMakeValidator::Invalid;
}
}
void CMakeValidator::finished(int exitCode)
{
if (exitCode) {
m_state = CMakeValidator::Invalid;
return;
}
if (m_state == CMakeValidator::RunningBasic) {
QString response = m_process->readAll();
QRegExp versionRegexp(QLatin1String("^cmake version ([\\d\\.]*)"));
versionRegexp.indexIn(response);
//m_supportsQtCreator = response.contains(QLatin1String("QtCreator"));
m_hasCodeBlocksMsvcGenerator = response.contains(QLatin1String("CodeBlocks - NMake Makefiles"));
m_hasCodeBlocksNinjaGenerator = response.contains(QLatin1String("CodeBlocks - Ninja"));
m_version = versionRegexp.cap(1);
if (!(versionRegexp.capturedTexts().size() > 3))
m_version += QLatin1Char('.') + versionRegexp.cap(3);
if (m_version.isEmpty()) {
m_state = CMakeValidator::Invalid;
} else {
m_state = CMakeValidator::RunningFunctionList;
if (!startProcess(QStringList(QLatin1String("--help-command-list"))))
finished(0); // shoud never happen, just continue
}
} else if (m_state == CMakeValidator::RunningFunctionList) {
parseFunctionOutput(m_process->readAll());
m_state = CMakeValidator::RunningFunctionDetails;
if (!startProcess(QStringList(QLatin1String("--help-commands"))))
finished(0); // shoud never happen, just continue
} else if (m_state == CMakeValidator::RunningFunctionDetails) {
parseFunctionDetailsOutput(m_process->readAll());
m_state = CMakeValidator::ValidFunctionDetails;
}
}
bool CMakeValidator::isValid() const
{
if (m_state == CMakeValidator::Invalid)
return false;
if (m_state == CMakeValidator::RunningBasic)
m_process->waitForFinished();
return (m_state != CMakeValidator::Invalid);
}
bool CMakeValidator::startProcess(const QStringList &args)
{
m_process->start(m_executable, args);
return m_process->waitForStarted(2000);
}
QString CMakeValidator::cmakeExecutable() const
{
return m_executable;
}
bool CMakeValidator::hasCodeBlocksMsvcGenerator() const
{
if (!isValid())
return false;
return m_hasCodeBlocksMsvcGenerator;
}
bool CMakeValidator::hasCodeBlocksNinjaGenerator() const
{
if (!isValid())
return false;
return m_hasCodeBlocksNinjaGenerator;
}
TextEditor::Keywords CMakeValidator::keywords()
{
while (m_state != ValidFunctionDetails && m_state != CMakeValidator::Invalid) {
m_process->waitForFinished();
}
if (m_state == CMakeValidator::Invalid)
return TextEditor::Keywords(QStringList(), QStringList(), QMap<QString, QStringList>());
return TextEditor::Keywords(m_variables, m_functions, m_functionArgs);
}
static void extractKeywords(const QByteArray &input, QStringList *destination)
{
if (!destination)
return;
QString keyword;
int ignoreZone = 0;
for (int i = 0; i < input.count(); ++i) {
const QChar chr = input.at(i);
if (chr == QLatin1Char('{'))
++ignoreZone;
if (chr == QLatin1Char('}'))
--ignoreZone;
if (ignoreZone == 0) {
if ((chr.isLetterOrNumber() && chr.isUpper())
|| chr == QLatin1Char('_')) {
keyword += chr;
} else {
if (!keyword.isEmpty()) {
if (keyword.size() > 1) {
*destination << keyword;
}
keyword.clear();
}
}
}
}
if (keyword.size() > 1) {
*destination << keyword;
}
}
void CMakeValidator::parseFunctionOutput(const QByteArray &output)
{
QList<QByteArray> cmakeFunctionsList = output.split('\n');
m_functions.clear();
if (!cmakeFunctionsList.isEmpty()) {
cmakeFunctionsList.removeFirst(); //remove version string
foreach (const QByteArray &function, cmakeFunctionsList)
m_functions << QString(function).trimmed();
}
}
QString CMakeValidator::formatFunctionDetails(const QString &command, const QByteArray &args)
{
return QLatin1String("<table><tr><td><b>") + Qt::escape(command)
+ QLatin1String("</b></td><td>")
+ Qt::escape(args)
+ QLatin1String("</td></tr>");
}
void CMakeValidator::parseFunctionDetailsOutput(const QByteArray &output)
{
QStringList cmakeFunctionsList = m_functions;
QList<QByteArray> cmakeCommandsHelp = output.split('\n');
for (int i = 0; i < cmakeCommandsHelp.count(); ++i) {
QByteArray lineTrimmed = cmakeCommandsHelp.at(i).trimmed();
if (cmakeFunctionsList.first().toLatin1() == lineTrimmed) {
QStringList commandSyntaxes;
QString currentCommandSyntax;
QString currentCommand = cmakeFunctionsList.takeFirst();
++i;
for (; i < cmakeCommandsHelp.count(); ++i) {
lineTrimmed = cmakeCommandsHelp.at(i).trimmed();
if (cmakeFunctionsList.first().toLatin1() == lineTrimmed) {
//start of next function in output
if (!currentCommandSyntax.isEmpty())
commandSyntaxes << currentCommandSyntax.append("</table>");
--i;
break;
}
if (lineTrimmed.startsWith(currentCommand.toLatin1() + "(")) {
if (!currentCommandSyntax.isEmpty())
commandSyntaxes << currentCommandSyntax.append("</table>");
QByteArray argLine = lineTrimmed.mid(currentCommand.length());
extractKeywords(argLine, &m_variables);
currentCommandSyntax = formatFunctionDetails(currentCommand, argLine);
} else {
if (!currentCommandSyntax.isEmpty()) {
if (lineTrimmed.isEmpty()) {
commandSyntaxes << currentCommandSyntax.append("</table>");
currentCommandSyntax.clear();
} else {
extractKeywords(lineTrimmed, &m_variables);
currentCommandSyntax += "<tr><td>&nbsp;</td><td>" + Qt::escape(lineTrimmed) + "</td></tr>";
}
}
}
}
m_functionArgs[currentCommand] = commandSyntaxes;
}
}
m_functions = m_functionArgs.keys();
m_variables.sort();
m_variables.removeDuplicates();
}

View File

@@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef CMAKEVALIDATOR_H
#define CMAKEVALIDATOR_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <texteditor/codeassist/keywordscompletionassist.h>
QT_FORWARD_DECLARE_CLASS(QProcess)
namespace CMakeProjectManager {
namespace Internal {
class CMakeValidator : public QObject
{
Q_OBJECT
public:
CMakeValidator();
~CMakeValidator();
enum State { Invalid, RunningBasic, RunningFunctionList, RunningFunctionDetails, ValidFunctionDetails };
void cancel();
bool isValid() const;
void setCMakeExecutable(const QString &executable);
QString cmakeExecutable() const;
bool hasCodeBlocksMsvcGenerator() const;
bool hasCodeBlocksNinjaGenerator() const;
TextEditor::Keywords keywords();
private slots:
void finished(int exitCode);
private:
void finishStep();
void startNextStep();
bool startProcess(const QStringList &args);
void parseFunctionOutput(const QByteArray &output);
void parseFunctionDetailsOutput(const QByteArray &output);
QString formatFunctionDetails(const QString &command, const QByteArray &args);
State m_state;
QProcess *m_process;
bool m_hasCodeBlocksMsvcGenerator;
bool m_hasCodeBlocksNinjaGenerator;
QString m_version;
QString m_executable;
QMap<QString, QStringList> m_functionArgs;
QStringList m_variables;
QStringList m_functions;
};
} // namespace Internal
} // namespace CMakeProjectManager
#endif // CMAKEVALIDATOR_H