Commit c0a0c610 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Initial work on the code completion for GLSL files.

parent 2fe83082
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "glslcodecompletion.h"
#include "glsleditor.h"
#include <QtCore/QDebug>
using namespace GLSLEditor;
static const char *glsl_keywords[] =
{ // ### TODO: get the keywords from the lexer
"attribute",
"bool",
"break",
"bvec2",
"bvec3",
"bvec4",
"case",
"centroid",
"const",
"continue",
"default",
"discard",
"dmat2",
"dmat2x2",
"dmat2x3",
"dmat2x4",
"dmat3",
"dmat3x2",
"dmat3x3",
"dmat3x4",
"dmat4",
"dmat4x2",
"dmat4x3",
"dmat4x4",
"do",
"double",
"dvec2",
"dvec3",
"dvec4",
"else",
"false",
"flat",
"float",
"for",
"highp",
"if",
"in",
"inout",
"int",
"invariant",
"isampler1D",
"isampler1DArray",
"isampler2D",
"isampler2DArray",
"isampler2DMS",
"isampler2DMSArray",
"isampler2DRect",
"isampler3D",
"isamplerBuffer",
"isamplerCube",
"isamplerCubeArray",
"ivec2",
"ivec3",
"ivec4",
"layout",
"lowp",
"mat2",
"mat2x2",
"mat2x3",
"mat2x4",
"mat3",
"mat3x2",
"mat3x3",
"mat3x4",
"mat4",
"mat4x2",
"mat4x3",
"mat4x4",
"mediump",
"noperspective",
"out",
"patch",
"precision",
"return",
"sample",
"sampler1D",
"sampler1DArray",
"sampler1DArrayShadow",
"sampler1DShadow",
"sampler2D",
"sampler2DArray",
"sampler2DArrayShadow",
"sampler2DMS",
"sampler2DMSArray",
"sampler2DRect",
"sampler2DRectShadow",
"sampler2DShadow",
"sampler3D",
"samplerBuffer",
"samplerCube",
"samplerCubeArray",
"samplerCubeArrayShadow",
"samplerCubeShadow",
"smooth",
"struct",
"subroutine",
"switch",
"true",
"uint",
"uniform",
"usampler1D",
"usampler1DArray",
"usampler2D",
"usampler2DArray",
"usampler2DMS",
"usampler2DMSarray",
"usampler2DRect",
"usampler3D",
"usamplerBuffer",
"usamplerCube",
"usamplerCubeArray",
"uvec2",
"uvec3",
"uvec4",
"varying",
"vec2",
"vec3",
"vec4",
"void",
"while",
0
};
CodeCompletion::CodeCompletion(QObject *parent)
: ICompletionCollector(parent),
m_editor(0),
m_startPosition(-1),
m_restartCompletion(false)
{
for (const char **it = glsl_keywords; *it; ++it) {
TextEditor::CompletionItem item(this);
item.text = QString::fromLatin1(*it);
m_keywordCompletions.append(item);
}
}
CodeCompletion::~CodeCompletion()
{
}
TextEditor::ITextEditable *CodeCompletion::editor() const
{
return m_editor;
}
int CodeCompletion::startPosition() const
{
return m_startPosition;
}
bool CodeCompletion::supportsEditor(TextEditor::ITextEditable *editor)
{
if (qobject_cast<GLSLTextEditor *>(editor->widget()) != 0)
return true;
return false;
}
bool CodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
{
Q_UNUSED(editor);
return false;
}
int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
{
m_editor = editor;
int pos = editor->position() - 1;
QChar ch = editor->characterAt(pos);
while (ch.isLetterOrNumber())
ch = editor->characterAt(--pos);
m_completions += m_keywordCompletions;
m_startPosition = pos + 1;
return m_startPosition;
}
void CodeCompletion::completions(QList<TextEditor::CompletionItem> *completions)
{
const int length = m_editor->position() - m_startPosition;
if (length == 0)
*completions = m_completions;
else if (length > 0) {
const QString key = m_editor->textAt(m_startPosition, length);
filter(m_completions, completions, key);
if (completions->size() == 1) {
if (key == completions->first().text)
completions->clear();
}
}
}
bool CodeCompletion::typedCharCompletes(const TextEditor::CompletionItem &item, QChar typedChar)
{
Q_UNUSED(item);
Q_UNUSED(typedChar);
return false;
}
void CodeCompletion::complete(const TextEditor::CompletionItem &item, QChar typedChar)
{
Q_UNUSED(typedChar);
QString toInsert = item.text;
const int length = m_editor->position() - m_startPosition;
m_editor->setCurPos(m_startPosition);
m_editor->replace(length, toInsert);
if (toInsert.endsWith(QLatin1Char('.')) || toInsert.endsWith(QLatin1Char('(')))
m_restartCompletion = true;
}
bool CodeCompletion::partiallyComplete(const QList<TextEditor::CompletionItem> &completionItems)
{
return ICompletionCollector::partiallyComplete(completionItems);
}
void CodeCompletion::cleanup()
{
m_editor = 0;
m_completions.clear();
m_restartCompletion = false;
m_startPosition = -1;
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef GLSLCODECOMPLETION_H
#define GLSLCODECOMPLETION_H
#include <texteditor/icompletioncollector.h>
namespace GLSLEditor {
class CodeCompletion: public TextEditor::ICompletionCollector
{
Q_OBJECT
public:
CodeCompletion(QObject *parent = 0);
virtual ~CodeCompletion();
/* Returns the current active ITextEditable */
virtual TextEditor::ITextEditable *editor() const;
virtual int startPosition() const;
/*
* Returns true if this completion collector can be used with the given editor.
*/
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
/* 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
* the text editor.
*/
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
// returns starting position
virtual int startCompletion(TextEditor::ITextEditable *editor);
/* This method should add all the completions it wants to show into the list,
* based on the given cursor position.
*/
virtual void completions(QList<TextEditor::CompletionItem> *completions);
/**
* This method should return true when the given typed character should cause
* the selected completion item to be completed.
*/
virtual bool typedCharCompletes(const TextEditor::CompletionItem &item, QChar typedChar);
/**
* This method should complete the given completion item.
*
* \param typedChar Non-null when completion was triggered by typing a
* character. Possible values depend on typedCharCompletes()
*/
virtual void complete(const TextEditor::CompletionItem &item, QChar typedChar);
/* This method gives the completion collector a chance to partially complete
* based on a set of items. The general use case is to complete the common
* prefix shared by all possible completion items.
*
* Returns whether the completion popup should be closed.
*/
virtual bool partiallyComplete(const QList<TextEditor::CompletionItem> &completionItems);
/* Called when it's safe to clean up the completion items.
*/
virtual void cleanup();
private:
QList<TextEditor::CompletionItem> m_completions;
QList<TextEditor::CompletionItem> m_keywordCompletions;
TextEditor::ITextEditable *m_editor;
int m_startPosition;
bool m_restartCompletion;
};
} // namespace GLSLEditor
#endif // GLSLCODECOMPLETION_H
......@@ -15,7 +15,8 @@ glsleditorconstants.h \
glsleditoreditable.h \
glsleditorfactory.h \
glsleditorplugin.h \
glslhighlighter.h
glslhighlighter.h \
glslcodecompletion.h
SOURCES += \
glsleditor.cpp \
......@@ -23,7 +24,8 @@ glsleditoractionhandler.cpp \
glsleditoreditable.cpp \
glsleditorfactory.cpp \
glsleditorplugin.cpp \
glslhighlighter.cpp
glslhighlighter.cpp \
glslcodecompletion.cpp
OTHER_FILES += GLSLEditor.mimetypes.xml
RESOURCES += glsleditor.qrc
......@@ -31,6 +31,7 @@
#include "glsleditor.h"
#include "glsleditorconstants.h"
#include "glsleditorfactory.h"
#include "glslcodecompletion.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
......@@ -107,6 +108,9 @@ bool GLSLEditorPlugin::initialize(const QStringList & /*arguments*/, QString *er
m_editor = new GLSLEditorFactory(this);
addObject(m_editor);
CodeCompletion *completion = new CodeCompletion(this);
addAutoReleasedObject(completion);
m_actionHandler = new TextEditor::TextEditorActionHandler(GLSLEditor::Constants::C_GLSLEDITOR_ID,
TextEditor::TextEditorActionHandler::Format
| TextEditor::TextEditorActionHandler::UnCommentSelection
......@@ -122,7 +126,7 @@ bool GLSLEditorPlugin::initialize(const QStringList & /*arguments*/, QString *er
menu->setTitle(tr("GLSL"));
am->actionContainer(Core::Constants::M_TOOLS)->addMenu(glslToolsMenu);
Core::Command *cmd;
Core::Command *cmd = 0;
// Insert marker for "Refactoring" menu:
Core::Context globalContext(Core::Constants::C_GLOBAL);
......@@ -137,10 +141,10 @@ bool GLSLEditorPlugin::initialize(const QStringList & /*arguments*/, QString *er
contextMenu->addAction(cmd);
// Set completion settings and keep them up to date
// TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance();
// completion->setCompletionSettings(textEditorSettings->completionSettings());
// connect(textEditorSettings, SIGNAL(completionSettingsChanged(TextEditor::CompletionSettings)),
// completion, SLOT(setCompletionSettings(TextEditor::CompletionSettings)));
TextEditor::TextEditorSettings *textEditorSettings = TextEditor::TextEditorSettings::instance();
completion->setCompletionSettings(textEditorSettings->completionSettings());
connect(textEditorSettings, SIGNAL(completionSettingsChanged(TextEditor::CompletionSettings)),
completion, SLOT(setCompletionSettings(TextEditor::CompletionSettings)));
error_message->clear();
......@@ -170,8 +174,8 @@ 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)));
connect(editor, SIGNAL(requestAutoCompletion(TextEditor::ITextEditable*, bool)),
TextEditor::CompletionSupport::instance(), SLOT(autoComplete(TextEditor::ITextEditable*, bool)));
// // quick fix
// connect(editor, SIGNAL(requestQuickFix(TextEditor::ITextEditable*)),
......
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