- enhancement: highlighter for GLSL (OpenGL Shading Language)

This commit is contained in:
Roy Qu 2022-01-23 23:27:48 +08:00
parent 194dd3f3e4
commit 609f611e8f
20 changed files with 1969 additions and 54 deletions

View File

@ -14,6 +14,7 @@ Red Panda C++ Version 0.13.3
- fix: editor crash when no highlighter is assigned (the editing file is a not c/cpp source file);
- fix: ')' not correctly skip in the editor when no highlighter is assigned (the editing file is a not c/cpp source file);
- fix: Undo in the editor will lose line indents when no highlighter is assigned (the editing file is a not c/cpp source file);
- enhancement: highlighter for GLSL (OpenGL Shading Language)
Red Panda C++ Version 0.13.2
- fix: "delete and exit" button in the environtment / folder option page doesn't work correctly

View File

@ -19,6 +19,7 @@
#include <QObject>
#include "qsynedit/highlighter/cpp.h"
#include "qsynedit/highlighter/asm.h"
#include "qsynedit/highlighter/glsl.h"
#include "qsynedit/Constants.h"
#include "colorscheme.h"
@ -42,6 +43,8 @@ PSynHighlighter HighlighterManager::getHighlighter(const QString &filename)
|| suffix == "CPP" || suffix =="H" || suffix == "c++"
|| suffix == "h++") {
return getCppHighlighter();
} else if (suffix == "vs" || suffix == "fs") {
return getGLSLHighlighter();
}
}
return PSynHighlighter();
@ -100,6 +103,34 @@ PSynHighlighter HighlighterManager::getAsmHighlighter()
return pHighlighter;
}
PSynHighlighter HighlighterManager::getGLSLHighlighter()
{
SynEditGLSLHighlighter* highlighter = new SynEditGLSLHighlighter();
PSynHighlighter pHighlighter(highlighter);
highlighter->asmAttribute()->setForeground(Qt::blue);
highlighter->charAttribute()->setForeground(Qt::black);
highlighter->commentAttribute()->setForeground(0x8C8C8C);
highlighter->commentAttribute()->setStyles(SynFontStyle::fsItalic);
highlighter->classAttribute()->setForeground(0x008080);
highlighter->floatAttribute()->setForeground(Qt::darkMagenta);
highlighter->functionAttribute()->setForeground(0x00627A);
highlighter->globalVarAttribute()->setForeground(0x660E7A);
highlighter->hexAttribute()->setForeground(Qt::darkMagenta);
highlighter->identifierAttribute()->setForeground(0x080808);
highlighter->invalidAttribute()->setForeground(Qt::red);
highlighter->localVarAttribute()->setForeground(Qt::black);
highlighter->numberAttribute()->setForeground(0x1750EB);
highlighter->octAttribute()->setForeground(Qt::darkMagenta);
highlighter->preprocessorAttribute()->setForeground(0x1f542e);
highlighter->keywordAttribute()->setForeground(0x0033b3);
highlighter->whitespaceAttribute()->setForeground(Qt::lightGray);
highlighter->stringAttribute()->setForeground(0x007d17);
highlighter->stringEscapeSequenceAttribute()->setForeground(Qt::red);
highlighter->symbolAttribute()->setForeground(0xc10000);
highlighter->variableAttribute()->setForeground(0x400080);
return pHighlighter;
}
void HighlighterManager::applyColorScheme(PSynHighlighter highlighter, const QString &schemeName)
{
if (!highlighter)

View File

@ -27,6 +27,7 @@ public:
PSynHighlighter copyHighlighter(PSynHighlighter highlighter);
PSynHighlighter getCppHighlighter();
PSynHighlighter getAsmHighlighter();
PSynHighlighter getGLSLHighlighter();
void applyColorScheme(PSynHighlighter highlighter, const QString& schemeName);
};

View File

@ -116,6 +116,7 @@ SOURCES += \
qsynedit/highlighter/base.cpp \
qsynedit/highlighter/composition.cpp \
qsynedit/highlighter/cpp.cpp \
qsynedit/highlighter/glsl.cpp \
settingsdialog/compilersetdirectorieswidget.cpp \
settingsdialog/compilersetoptionwidget.cpp \
settings.cpp \
@ -238,6 +239,7 @@ HEADERS += \
qsynedit/highlighter/base.h \
qsynedit/highlighter/composition.h \
qsynedit/highlighter/cpp.h \
qsynedit/highlighter/glsl.h \
settingsdialog/compilersetdirectorieswidget.h \
settingsdialog/compilersetoptionwidget.h \
settings.h \

View File

@ -131,7 +131,7 @@ Editor::Editor(QWidget *parent, const QString& filename,
}
if (pSettings->editor().readOnlySytemHeader()
&& (mParser->isSystemHeaderFile(mFilename) || mParser->isProjectHeaderFile(mFilename))) {
&& mParser && (mParser->isSystemHeaderFile(mFilename) || mParser->isProjectHeaderFile(mFilename))) {
this->setModified(false);
setReadOnly(true);
updateCaption();
@ -710,7 +710,7 @@ void Editor::keyPressEvent(QKeyEvent *event)
return;
} else if (mLastIdCharPressed==pSettings->codeCompletion().minCharRequired()){
QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY());
if (!lastWord.isEmpty()) {
if (mParser && !lastWord.isEmpty()) {
if (CppTypeKeywords.contains(lastWord)) {
if (lastWord == "long" ||
lastWord == "short" ||
@ -750,7 +750,7 @@ void Editor::keyPressEvent(QKeyEvent *event)
}
} else {
//preprocessor ?
if ((mLastIdCharPressed=0) && (ch=='#') && lineText().isEmpty()) {
if (mParser && (mLastIdCharPressed=0) && (ch=='#') && lineText().isEmpty()) {
if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
mLastIdCharPressed++;
@ -761,7 +761,7 @@ void Editor::keyPressEvent(QKeyEvent *event)
}
}
//javadoc directive?
if ((mLastIdCharPressed=0) && (ch=='#') &&
if (mParser && (mLastIdCharPressed=0) && (ch=='#') &&
lineText().trimmed().startsWith('*')) {
if (pSettings->codeCompletion().enabled()
&& pSettings->codeCompletion().showCompletionWhileInput() ) {
@ -2223,34 +2223,37 @@ bool Editor::handleCodeCompletion(QChar key)
{
if (!mCompletionPopup->isEnabled())
return false;
switch(key.unicode()) {
case '.':
setSelText(key);
showCompletion("",false);
return true;
case '>':
setSelText(key);
if ((caretX() > 2) && (lineText().length() >= 2) &&
(lineText()[caretX() - 3] == '-'))
if (mParser) {
switch(key.unicode()) {
case '.':
setSelText(key);
showCompletion("",false);
return true;
case ':':
ExecuteCommand(SynEditorCommand::ecChar,':',nullptr);
//setSelText(key);
if ((caretX() > 2) && (lineText().length() >= 2) &&
(lineText()[caretX() - 3] == ':'))
showCompletion("",false);
return true;
case '/':
case '\\':
setSelText(key);
if (mParser->isIncludeLine(lineText())) {
showHeaderCompletion(false);
return true;
case '>':
setSelText(key);
if ((caretX() > 2) && (lineText().length() >= 2) &&
(lineText()[caretX() - 3] == '-'))
showCompletion("",false);
return true;
case ':':
ExecuteCommand(SynEditorCommand::ecChar,':',nullptr);
//setSelText(key);
if ((caretX() > 2) && (lineText().length() >= 2) &&
(lineText()[caretX() - 3] == ':'))
showCompletion("",false);
return true;
case '/':
case '\\':
setSelText(key);
if (mParser->isIncludeLine(lineText())) {
showHeaderCompletion(false);
}
return true;
default:
return false;
}
return true;
default:
return false;
}
return false;
}
void Editor::initParser()
@ -2387,11 +2390,18 @@ Editor::QuoteStatus Editor::getQuoteStatus()
void Editor::reparse()
{
if (!highlighter())
return;
if (highlighter()->language() != SynHighlighterLanguage::Cpp
&& highlighter()->language() != SynHighlighterLanguage::GLSL)
return;
parseFile(mParser,mFilename,mInProject);
}
void Editor::reparseTodo()
{
if (!highlighter())
return;
pMainWindow->todoParser()->parseFile(mFilename);
}
@ -2590,7 +2600,10 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete)
}
if (!pSettings->codeCompletion().enabled())
return;
if (!mParser->enabled())
if (!mParser || !mParser->enabled())
return;
if (!highlighter())
return;
if (mCompletionPopup->isVisible()) // already in search, don't do it again
@ -2662,6 +2675,19 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete)
mParser->findAndScanBlockAt(mFilename, caretY())
);
QSet<QString> keywords;
if (highlighter()) {
if (highlighter()->language() != SynHighlighterLanguage::Cpp ) {
keywords = highlighter()->keywords();
} else if (mUseCppSyntax) {
foreach (const QString& keyword, CppKeywords.keys()) {
keywords.insert(keyword);
}
} else {
keywords = CKeywords;
}
}
if (word.isEmpty()) {
//word=getWordAtPosition(this,caretXY(),pBeginPos,pEndPos, WordPurpose::wpCompletion);
QString memberOperator;
@ -2680,14 +2706,15 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete)
memberOperator,
memberExpression,
mFilename,
caretY());
caretY(),
keywords);
} else {
QStringList memberExpression;
memberExpression.append(word);
mCompletionPopup->prepareSearch(preWord,
QStringList(),
"",
memberExpression, mFilename, caretY());
memberExpression, mFilename, caretY(),keywords);
}
// Filter the whole statement list
@ -3901,6 +3928,10 @@ void Editor::checkSyntaxInBack()
{
if (readOnly())
return;
if (!highlighter())
return;
if (highlighter()->language()!=SynHighlighterLanguage::Cpp)
return;
if(pSettings->editor().syntaxCheck())
pMainWindow->checkSyntaxInBack(this);
}

View File

@ -765,7 +765,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
}
//we only parse CFile in the second parse
foreach (const QString& file,files) {
if (isCfile(file)) {
if (!isHfile(file)) {
mFilesScannedCount++;
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
if (!mPreprocessor.scannedFiles().contains(file)) {
@ -3196,8 +3196,8 @@ void CppParser::internalParse(const QString &fileName)
// Perform some validation before we start
if (!mEnabled)
return;
if (!isCfile(fileName) && !isHfile(fileName)) // support only known C/C++ files
return;
// if (!isCfile(fileName) && !isHfile(fileName)) // support only known C/C++ files
// return;
QStringList buffer;
if (mOnGetFileStream) {

View File

@ -401,3 +401,8 @@ void SynEditASMHighlighter::resetState()
{
}
QSet<QString> SynEditASMHighlighter::keywords() const
{
return Keywords;
}

View File

@ -93,6 +93,10 @@ public:
SynRangeState getRangeState() const override;
void setState(const SynRangeState& rangeState) override;
void resetState() override;
// SynHighlighter interface
public:
QSet<QString> keywords() const override;
};
#endif // SYNEDITASMHIGHLIGHTER_H

View File

@ -80,6 +80,11 @@ void SynHighlighter::nextToEol()
next();
}
QSet<QString> SynHighlighter::keywords() const
{
return QSet<QString>();
}
bool SynHighlighter::isSpaceChar(const QChar &ch)
{
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';

View File

@ -61,12 +61,14 @@ enum class SynHighlighterTokenType {
enum class SynHighlighterClass {
Composition,
CppHighlighter,
AsmHighlighter
AsmHighlighter,
GLSLHighlighter
};
enum class SynHighlighterLanguage {
Asssembly,
Cpp,
GLSL
};
class SynHighlighterAttribute {
@ -104,7 +106,6 @@ public:
const QSet<QChar>& wordBreakChars() const;
PSynHighlighterAttribute commentAttribute() const;
PSynHighlighterAttribute identifierAttribute() const;
@ -138,6 +139,7 @@ public:
virtual void setState(const SynRangeState& rangeState) = 0;
virtual void setLine(const QString& newLine, int lineNumber) = 0;
virtual void resetState() = 0;
virtual QSet<QString> keywords() const;
virtual QString languageName() = 0;
virtual SynHighlighterLanguage language() = 0;

View File

@ -19,13 +19,14 @@
#include <QFont>
static const QSet<QString> StatementKeyWords {
static const QSet<QString> CppStatementKeyWords {
"if",
"for",
"try",
"catch",
"else",
"while"
"while",
"do"
};
@ -547,7 +548,7 @@ void SynEditCppHighlighter::identProc()
mRun=wordEnd;
if (isKeyword(word)) {
mTokenId = TokenKind::Key;
if (StatementKeyWords.contains(word)) {
if (CppStatementKeyWords.contains(word)) {
pushIndents(sitStatement);
}
} else {
@ -1633,3 +1634,8 @@ bool SynEditCppHighlighter::isIdentChar(const QChar &ch) const
{
return ch=='_' || ch.isDigit() || ch.isLetter();
}
QSet<QString> SynEditCppHighlighter::keywords() const
{
return Keywords;
}

View File

@ -206,6 +206,10 @@ public:
// SynHighlighter interface
public:
bool isIdentChar(const QChar &ch) const override;
// SynHighlighter interface
public:
QSet<QString> keywords() const override;
};
#endif // SYNEDITCPPHIGHLIGHTER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,215 @@
/*
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef SYNEDITGLSLHIGHLIGHTER_H
#define SYNEDITGLSLHIGHLIGHTER_H
#include "base.h"
#include <QSet>
class SynEditGLSLHighlighter: public SynHighlighter
{
enum TokenKind {
Asm = 1,
Comment,
Directive,
Identifier,
Key,
Null,
Number,
Space,
String,
StringEscapeSeq,
Symbol,
Unknown,
Char,
Float,
Hex,
HexFloat,
Octal,
RawString
};
enum class ExtTokenKind {
Add, AddAssign, And, AndAssign, Arrow, Assign,
BitComplement, BraceClose, BraceOpen, Colon, Comma,
Decrement, Divide, DivideAssign, Ellipse, GreaterThan,
GreaterThanEqual, IncOr, IncOrAssign, Increment, LessThan,
LessThanEqual, LogAnd, LogComplement, LogEqual, LogOr,
Mod, ModAssign, MultiplyAssign, NotEqual, Point, PointerToMemberOfObject,
PointerToMemberOfPointer,Question,
RoundClose, RoundOpen, ScopeResolution, SemiColon, ShiftLeft,
ShiftLeftAssign, ShiftRight, ShiftRightAssign, SquareClose,
SquareOpen, Star, Subtract, SubtractAssign, Xor,
XorAssign
};
enum RangeState {
rsUnknown, rsAnsiC, rsAnsiCAsm, rsAnsiCAsmBlock, rsAsm,
rsAsmBlock, rsDirective, rsDirectiveComment, rsString,
rsMultiLineString, rsMultiLineDirective, rsCppComment,
rsStringEscapeSeq, rsMultiLineStringEscapeSeq,
rsRawString, rsSpace,rsRawStringEscaping,rsRawStringNotEscaping,rsChar,
rsCppCommentEnded
};
public:
explicit SynEditGLSLHighlighter();
PSynHighlighterAttribute asmAttribute() const;
PSynHighlighterAttribute preprocessorAttribute() const;
PSynHighlighterAttribute invalidAttribute() const;
PSynHighlighterAttribute numberAttribute() const;
PSynHighlighterAttribute floatAttribute() const;
PSynHighlighterAttribute hexAttribute() const;
PSynHighlighterAttribute octAttribute() const;
PSynHighlighterAttribute stringEscapeSequenceAttribute() const;
PSynHighlighterAttribute charAttribute() const;
PSynHighlighterAttribute variableAttribute() const;
PSynHighlighterAttribute functionAttribute() const;
PSynHighlighterAttribute classAttribute() const;
PSynHighlighterAttribute globalVarAttribute() const;
PSynHighlighterAttribute localVarAttribute() const;
static const QSet<QString> Keywords;
ExtTokenKind getExtTokenId();
SynTokenKind getTokenId();
private:
void andSymbolProc();
void ansiCppProc();
void ansiCProc();
void asciiCharProc();
void atSymbolProc();
void braceCloseProc();
void braceOpenProc();
void colonProc();
void commaProc();
void directiveProc();
void directiveEndProc();
void equalProc();
void greaterProc();
void identProc();
void lowerProc();
void minusProc();
void modSymbolProc();
void notSymbolProc();
void nullProc();
void numberProc();
void orSymbolProc();
void plusProc();
void pointProc();
void questionProc();
void rawStringProc();
void roundCloseProc();
void roundOpenProc();
void semiColonProc();
void slashProc();
void spaceProc();
void squareCloseProc();
void squareOpenProc();
void starProc();
void stringEndProc();
void stringEscapeSeqProc();
void stringProc();
void stringStartProc();
void tildeProc();
void unknownProc();
void xorSymbolProc();
void processChar();
void popIndents(int indentType);
void pushIndents(int indentType);
private:
bool mAsmStart;
SynRangeState mRange;
// SynRangeState mSpaceRange;
QString mLineString;
QChar* mLine;
int mLineSize;
int mRun;
int mStringLen;
int mToIdent;
int mTokenPos;
int mTokenId;
ExtTokenKind mExtTokenId;
int mLineNumber;
int mLeftBraces;
int mRightBraces;
PSynHighlighterAttribute mAsmAttribute;
PSynHighlighterAttribute mPreprocessorAttribute;
PSynHighlighterAttribute mInvalidAttribute;
PSynHighlighterAttribute mNumberAttribute;
PSynHighlighterAttribute mFloatAttribute;
PSynHighlighterAttribute mHexAttribute;
PSynHighlighterAttribute mOctAttribute;
PSynHighlighterAttribute mStringEscapeSequenceAttribute;
PSynHighlighterAttribute mCharAttribute;
PSynHighlighterAttribute mVariableAttribute;
PSynHighlighterAttribute mFunctionAttribute;
PSynHighlighterAttribute mClassAttribute;
PSynHighlighterAttribute mGlobalVarAttribute;
PSynHighlighterAttribute mLocalVarAttribute;
// SynHighligterBase interface
public:
bool getTokenFinished() const override;
bool isLastLineCommentNotFinished(int state) const override;
bool isLastLineStringNotFinished(int state) const override;
bool eol() const override;
QString getToken() const override;
PSynHighlighterAttribute getTokenAttribute() const override;
SynTokenKind getTokenKind() override;
int getTokenPos() override;
void next() override;
void setLine(const QString &newLine, int lineNumber) override;
bool isKeyword(const QString &word) override;
SynHighlighterTokenType getTokenType() override;
void setState(const SynRangeState& rangeState) override;
void resetState() override;
SynHighlighterClass getClass() const override;
QString getName() const override;
QString languageName() override;
SynHighlighterLanguage language() override;
// SynHighlighter interface
public:
SynRangeState getRangeState() const override;
// SynHighlighter interface
public:
bool isIdentChar(const QChar &ch) const override;
// SynHighlighter interface
public:
QSet<QString> keywords() const override;
};
#endif // SYNEDITGLSLHIGHLIGHTER_H

View File

@ -81,7 +81,8 @@ void CodeCompletionPopup::prepareSearch(
const QString& memberOperator,
const QStringList& memberExpression,
const QString &filename,
int line)
int line,
const QSet<QString>& customKeywords)
{
QMutexLocker locker(&mMutex);
if (!isEnabled())
@ -94,7 +95,7 @@ void CodeCompletionPopup::prepareSearch(
mMemberOperator = memberOperator;
if (preWord.isEmpty()) {
mIncludedFiles = mParser->getFileIncludes(filename);
getCompletionFor(ownerExpression,memberOperator,memberExpression, filename,line);
getCompletionFor(ownerExpression,memberOperator,memberExpression, filename,line, customKeywords);
} else {
getCompletionListForPreWord(preWord);
}
@ -458,10 +459,28 @@ void CodeCompletionPopup::getCompletionFor(
const QString& memberOperator,
const QStringList& memberExpression,
const QString &fileName,
int line)
int line,
const QSet<QString>& customKeywords)
{
if(!mParser)
if(!mParser) {
if (mShowKeywords) {
//add keywords
if (!customKeywords.isEmpty()) {
foreach (const QString& keyword,customKeywords) {
addKeyword(keyword);
}
} else if (mUseCppKeyword) {
foreach (const QString& keyword,CppKeywords.keys()) {
addKeyword(keyword);
}
} else {
foreach (const QString& keyword,CKeywords) {
addKeyword(keyword);
}
}
}
return;
}
if (!mParser->enabled())
return;
if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty())
@ -514,7 +533,11 @@ void CodeCompletionPopup::getCompletionFor(
if (mShowKeywords) {
//add keywords
if (mUseCppKeyword) {
if (!customKeywords.isEmpty()) {
foreach (const QString& keyword,customKeywords) {
addKeyword(keyword);
}
} else if (mUseCppKeyword) {
foreach (const QString& keyword,CppKeywords.keys()) {
addKeyword(keyword);
}

View File

@ -52,7 +52,8 @@ public:
const QString& memberOperator,
const QStringList& memberExpression,
const QString& filename,
int line);
int line,
const QSet<QString>& customKeywords);
bool search(const QString& memberPhrase, bool autoHideOnSingleResult);
PStatement selectedStatement();
@ -101,7 +102,8 @@ private:
const QString& memberOperator,
const QStringList& memberExpression,
const QString& fileName,
int line);
int line,
const QSet<QString>& customKeywords);
void getCompletionListForPreWord(const QString& preWord);
void addKeyword(const QString& keyword);
bool isIncluded(const QString& fileName);

View File

@ -22,7 +22,7 @@ Target=explosion.png
[Project]
UnitCount=3
Type=0
Type=1
IsCpp=0
linker=-lraylib -lopengl32 -lgdi32 -lwinmm_@@__@@_

View File

@ -14,7 +14,7 @@ C=raylib_3d_c.txt
[Project]
UnitCount=1
Type=0
Type=1
IsCpp=0
linker=-lraylib -lopengl32 -lgdi32 -lwinmm_@@__@@_

View File

@ -9,8 +9,8 @@ Category=3D
Category[zh_CN]=3D
[Unit0]
CPPName=main.cpp
C=raylib_3d_shader_cpp.txt
CPPName=main.c
C=raylib_3d_shader_c.txt
[Unit1]
Source=raylib_base.vs
@ -22,7 +22,7 @@ Target=fragment_shader.fs
[Project]
UnitCount=3
Type=0
IsCpp=1
Type=1
IsCpp=0
linker=-lraylib -lopengl32 -lgdi32 -lwinmm_@@__@@_

View File

@ -22,7 +22,7 @@ int main(void)
// Load plane model from a generated mesh
Model model = LoadModelFromMesh(GenMeshCube(10.0f, 10.0f, 3.3));
Shader shader = LoadShader("vertices_shader.vs","raylib_base.fs");
Shader shader = LoadShader("vertices_shader.vs","fragment_shader.fs");
// Assign out lighting shader to model
model.materials[0].shader = shader;