- enhancement: Highlighter for makefiles
This commit is contained in:
parent
650e3b407c
commit
8af963579a
4
NEWS.md
4
NEWS.md
|
@ -1,3 +1,7 @@
|
||||||
|
Red Panda C++ Version 2.6
|
||||||
|
|
||||||
|
- enhancement: Highlighter for makefiles
|
||||||
|
|
||||||
Red Panda C++ Version 2.5
|
Red Panda C++ Version 2.5
|
||||||
|
|
||||||
- enhancement: New color scheme Monokai (contributed by 小龙Dev(XiaoLoong@github))
|
- enhancement: New color scheme Monokai (contributed by 小龙Dev(XiaoLoong@github))
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "qsynedit/highlighter/cpp.h"
|
#include "qsynedit/highlighter/cpp.h"
|
||||||
#include "qsynedit/highlighter/asm.h"
|
#include "qsynedit/highlighter/asm.h"
|
||||||
#include "qsynedit/highlighter/glsl.h"
|
#include "qsynedit/highlighter/glsl.h"
|
||||||
|
#include "qsynedit/highlighter/makefilehighlighter.h"
|
||||||
|
|
||||||
#include "qsynedit/Constants.h"
|
#include "qsynedit/Constants.h"
|
||||||
#include "colorscheme.h"
|
#include "colorscheme.h"
|
||||||
|
|
||||||
|
@ -38,6 +40,8 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(QSynedit::HighlighterL
|
||||||
return getCppHighlighter();
|
return getCppHighlighter();
|
||||||
case QSynedit::HighlighterLanguage::Asssembly:
|
case QSynedit::HighlighterLanguage::Asssembly:
|
||||||
return getAsmHighlighter();
|
return getAsmHighlighter();
|
||||||
|
case QSynedit::HighlighterLanguage::Makefile:
|
||||||
|
return getMakefileHighlighter();
|
||||||
case QSynedit::HighlighterLanguage::GLSL:
|
case QSynedit::HighlighterLanguage::GLSL:
|
||||||
return getGLSLHighlighter();
|
return getGLSLHighlighter();
|
||||||
default:
|
default:
|
||||||
|
@ -49,6 +53,7 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(const QString &filenam
|
||||||
{
|
{
|
||||||
QFileInfo info(filename);
|
QFileInfo info(filename);
|
||||||
QString suffix = info.suffix();
|
QString suffix = info.suffix();
|
||||||
|
QString basename = info.baseName();
|
||||||
if (suffix.isEmpty() || suffix == "c" || suffix == "cpp" || suffix == "cxx"
|
if (suffix.isEmpty() || suffix == "c" || suffix == "cpp" || suffix == "cxx"
|
||||||
|| suffix == "cc" || suffix == "h" || suffix == "hpp"
|
|| suffix == "cc" || suffix == "h" || suffix == "hpp"
|
||||||
|| suffix == "hxx" || suffix == "hh" || suffix == "C"
|
|| suffix == "hxx" || suffix == "hh" || suffix == "C"
|
||||||
|
@ -59,7 +64,8 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(const QString &filenam
|
||||||
return getGLSLHighlighter();
|
return getGLSLHighlighter();
|
||||||
} else if (suffix == "s" || suffix == "asm") {
|
} else if (suffix == "s" || suffix == "asm") {
|
||||||
return getAsmHighlighter();
|
return getAsmHighlighter();
|
||||||
}
|
} else if (basename.compare("makefile", Qt::CaseInsensitive)==0)
|
||||||
|
return getMakefileHighlighter();
|
||||||
return QSynedit::PHighlighter();
|
return QSynedit::PHighlighter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,14 +73,7 @@ QSynedit::PHighlighter HighlighterManager::copyHighlighter(QSynedit::PHighlighte
|
||||||
{
|
{
|
||||||
if (!highlighter)
|
if (!highlighter)
|
||||||
return QSynedit::PHighlighter();
|
return QSynedit::PHighlighter();
|
||||||
if (highlighter->language() == QSynedit::HighlighterLanguage::Cpp)
|
return getHighlighter(highlighter->language());
|
||||||
return getCppHighlighter();
|
|
||||||
else if (highlighter->language() == QSynedit::HighlighterLanguage::Asssembly)
|
|
||||||
return getAsmHighlighter();
|
|
||||||
else if (highlighter->language() == QSynedit::HighlighterLanguage::GLSL)
|
|
||||||
return getGLSLHighlighter();
|
|
||||||
//todo
|
|
||||||
return QSynedit::PHighlighter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSynedit::PHighlighter HighlighterManager::getCppHighlighter()
|
QSynedit::PHighlighter HighlighterManager::getCppHighlighter()
|
||||||
|
@ -95,26 +94,29 @@ QSynedit::PHighlighter HighlighterManager::getGLSLHighlighter()
|
||||||
return highlighter;
|
return highlighter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QSynedit::PHighlighter HighlighterManager::getMakefileHighlighter()
|
||||||
|
{
|
||||||
|
std::shared_ptr<QSynedit::MakefileHighlighter> highlighter=std::make_shared<QSynedit::MakefileHighlighter>();
|
||||||
|
return highlighter;
|
||||||
|
}
|
||||||
|
|
||||||
void HighlighterManager::applyColorScheme(QSynedit::PHighlighter highlighter, const QString &schemeName)
|
void HighlighterManager::applyColorScheme(QSynedit::PHighlighter highlighter, const QString &schemeName)
|
||||||
{
|
{
|
||||||
if (!highlighter)
|
if (!highlighter)
|
||||||
return;
|
return;
|
||||||
if ( (highlighter->language() == QSynedit::HighlighterLanguage::Cpp)
|
|
||||||
|| (highlighter->language() == QSynedit::HighlighterLanguage::Asssembly)
|
for (QString name: highlighter->attributes().keys()) {
|
||||||
) {
|
PColorSchemeItem item = pColorManager->getItem(schemeName,name);
|
||||||
for (QString name: highlighter->attributes().keys()) {
|
if (item) {
|
||||||
PColorSchemeItem item = pColorManager->getItem(schemeName,name);
|
QSynedit::PHighlighterAttribute attr = highlighter->attributes()[name];
|
||||||
if (item) {
|
attr->setBackground(item->background());
|
||||||
QSynedit::PHighlighterAttribute attr = highlighter->attributes()[name];
|
attr->setForeground(item->foreground());
|
||||||
attr->setBackground(item->background());
|
QSynedit::FontStyles styles = QSynedit::FontStyle::fsNone;
|
||||||
attr->setForeground(item->foreground());
|
styles.setFlag(QSynedit::FontStyle::fsBold, item->bold());
|
||||||
QSynedit::FontStyles styles = QSynedit::FontStyle::fsNone;
|
styles.setFlag(QSynedit::FontStyle::fsItalic, item->italic());
|
||||||
styles.setFlag(QSynedit::FontStyle::fsBold, item->bold());
|
styles.setFlag(QSynedit::FontStyle::fsUnderline, item->underlined());
|
||||||
styles.setFlag(QSynedit::FontStyle::fsItalic, item->italic());
|
styles.setFlag(QSynedit::FontStyle::fsStrikeOut, item->strikeout());
|
||||||
styles.setFlag(QSynedit::FontStyle::fsUnderline, item->underlined());
|
attr->setStyles(styles);
|
||||||
styles.setFlag(QSynedit::FontStyle::fsStrikeOut, item->strikeout());
|
|
||||||
attr->setStyles(styles);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
QSynedit::PHighlighter getCppHighlighter();
|
QSynedit::PHighlighter getCppHighlighter();
|
||||||
QSynedit::PHighlighter getAsmHighlighter();
|
QSynedit::PHighlighter getAsmHighlighter();
|
||||||
QSynedit::PHighlighter getGLSLHighlighter();
|
QSynedit::PHighlighter getGLSLHighlighter();
|
||||||
|
QSynedit::PHighlighter getMakefileHighlighter();
|
||||||
void applyColorScheme(QSynedit::PHighlighter highlighter, const QString& schemeName);
|
void applyColorScheme(QSynedit::PHighlighter highlighter, const QString& schemeName);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -467,7 +467,7 @@ RESOURCES += \
|
||||||
|
|
||||||
RC_ICONS = images/devcpp.ico images/associations/c.ico images/associations/cpp.ico images/associations/dev.ico images/associations/c.ico images/associations/cpp.ico images/associations/h.ico images/associations/hpp.ico
|
RC_ICONS = images/devcpp.ico images/associations/c.ico images/associations/cpp.ico images/associations/dev.ico images/associations/c.ico images/associations/cpp.ico images/associations/h.ico images/associations/hpp.ico
|
||||||
|
|
||||||
## fixed lrelease.prf
|
# fixed lrelease.prf
|
||||||
qtPrepareTool(QMAKE_LRELEASE, lrelease)
|
qtPrepareTool(QMAKE_LRELEASE, lrelease)
|
||||||
|
|
||||||
isEmpty(LRELEASE_DIR): LRELEASE_DIR = .qm
|
isEmpty(LRELEASE_DIR): LRELEASE_DIR = .qm
|
||||||
|
|
|
@ -52,8 +52,6 @@
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include <qt_utils/charsetinfo.h>
|
#include <qt_utils/charsetinfo.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
SaveException::SaveException(const QString& reason) {
|
SaveException::SaveException(const QString& reason) {
|
||||||
mReason = reason;
|
mReason = reason;
|
||||||
mReasonBuffer = mReason.toLocal8Bit();
|
mReasonBuffer = mReason.toLocal8Bit();
|
||||||
|
@ -912,7 +910,7 @@ void Editor::onGetEditingAreas(int Line, QSynedit::EditingAreaList &areaList)
|
||||||
{
|
{
|
||||||
areaList.clear();
|
areaList.clear();
|
||||||
if (mTabStopBegin>=0 && mTabStopY == Line) {
|
if (mTabStopBegin>=0 && mTabStopY == Line) {
|
||||||
QSynedit::PEditingArea p = make_shared<QSynedit::EditingArea>();
|
QSynedit::PEditingArea p = std::make_shared<QSynedit::EditingArea>();
|
||||||
p->type = QSynedit::EditingAreaType::eatRectangleBorder;
|
p->type = QSynedit::EditingAreaType::eatRectangleBorder;
|
||||||
// int spaceCount = leftSpaces(mLineBeforeTabStop);
|
// int spaceCount = leftSpaces(mLineBeforeTabStop);
|
||||||
// int spaceBefore = mLineBeforeTabStop.length()-TrimLeft(mLineBeforeTabStop).length();
|
// int spaceBefore = mLineBeforeTabStop.length()-TrimLeft(mLineBeforeTabStop).length();
|
||||||
|
|
|
@ -1331,8 +1331,8 @@ void MainWindow::setProjectCurrentFile(const QString &filename)
|
||||||
if (!unit)
|
if (!unit)
|
||||||
return;
|
return;
|
||||||
QModelIndex index = mProject->model()->getNodeIndex(unit->node().get());
|
QModelIndex index = mProject->model()->getNodeIndex(unit->node().get());
|
||||||
index = mProjectProxyModel->mapFromSource(index);
|
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
|
index = mProjectProxyModel->mapFromSource(index);
|
||||||
ui->projectView->expand(index);
|
ui->projectView->expand(index);
|
||||||
ui->projectView->setCurrentIndex(index);
|
ui->projectView->setCurrentIndex(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ SOURCES += qsynedit/CodeFolding.cpp \
|
||||||
qsynedit/Search.cpp \
|
qsynedit/Search.cpp \
|
||||||
qsynedit/SearchBase.cpp \
|
qsynedit/SearchBase.cpp \
|
||||||
qsynedit/SearchRegex.cpp \
|
qsynedit/SearchRegex.cpp \
|
||||||
qsynedit/Types.cpp
|
qsynedit/Types.cpp \
|
||||||
|
qsynedit/highlighter/makefilehighlighter.cpp
|
||||||
|
|
||||||
HEADERS += qsynedit/Search.h \
|
HEADERS += qsynedit/Search.h \
|
||||||
qsynedit/SearchBase.h \
|
qsynedit/SearchBase.h \
|
||||||
|
@ -62,5 +63,6 @@ HEADERS += qsynedit/Search.h \
|
||||||
qsynedit/highlighter/cpp.h \
|
qsynedit/highlighter/cpp.h \
|
||||||
qsynedit/highlighter/customhighlighterv1.h \
|
qsynedit/highlighter/customhighlighterv1.h \
|
||||||
qsynedit/highlighter/glsl.h \
|
qsynedit/highlighter/glsl.h \
|
||||||
|
qsynedit/highlighter/makefilehighlighter.h
|
||||||
|
|
||||||
INCLUDEPATH += ../redpanda_qt_utils
|
INCLUDEPATH += ../redpanda_qt_utils
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum class HighlighterLanguage {
|
||||||
Asssembly,
|
Asssembly,
|
||||||
Cpp,
|
Cpp,
|
||||||
GLSL,
|
GLSL,
|
||||||
|
Makefile,
|
||||||
Custom
|
Custom
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,641 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
#include "makefilehighlighter.h"
|
||||||
|
#include "../Constants.h"
|
||||||
|
//#include <QDebug>
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
const QSet<QString> MakefileHighlighter::Directives {
|
||||||
|
"abspath",
|
||||||
|
"addprefix",
|
||||||
|
"addsuffix",
|
||||||
|
"and",
|
||||||
|
"AR",
|
||||||
|
"ARFLAGS",
|
||||||
|
"AS",
|
||||||
|
"ASFLAGS",
|
||||||
|
"basename",
|
||||||
|
"bindir",
|
||||||
|
|
||||||
|
"call",
|
||||||
|
"CC",
|
||||||
|
"CFLAGS",
|
||||||
|
"CO",
|
||||||
|
"COFLAGS",
|
||||||
|
"COMSPEC",
|
||||||
|
"CPP",
|
||||||
|
"CPPFLAGS",
|
||||||
|
"CTANGLE",
|
||||||
|
"CURDIR",
|
||||||
|
"CWEAVE",
|
||||||
|
"CXX",
|
||||||
|
"CXXFLAGS",
|
||||||
|
|
||||||
|
"define",
|
||||||
|
"DESTDIR",
|
||||||
|
"dir",
|
||||||
|
|
||||||
|
"else",
|
||||||
|
"endef",
|
||||||
|
"endif",
|
||||||
|
"error",
|
||||||
|
"eval",
|
||||||
|
"exec_prefix",
|
||||||
|
"export",
|
||||||
|
|
||||||
|
"FC",
|
||||||
|
"FFLAGS",
|
||||||
|
"file",
|
||||||
|
"filter",
|
||||||
|
"filter-out",
|
||||||
|
"findstring",
|
||||||
|
"firstword",
|
||||||
|
"flavor",
|
||||||
|
"foreach",
|
||||||
|
|
||||||
|
"GET",
|
||||||
|
"GFLAGS",
|
||||||
|
"gmk-eval",
|
||||||
|
"gmk-expand",
|
||||||
|
"gmk_add_function",
|
||||||
|
"gmk_alloc",
|
||||||
|
"gmk_eval",
|
||||||
|
"gmk_expand",
|
||||||
|
"gmk_free",
|
||||||
|
"gmk_func_ptr",
|
||||||
|
"GNUmakefile",
|
||||||
|
"GPATH",
|
||||||
|
"guile",
|
||||||
|
|
||||||
|
"if",
|
||||||
|
"if",
|
||||||
|
"ifdef",
|
||||||
|
"ifeq",
|
||||||
|
"ifndef",
|
||||||
|
"ifneq",
|
||||||
|
"include",
|
||||||
|
"info",
|
||||||
|
"intcmp",
|
||||||
|
|
||||||
|
"join",
|
||||||
|
|
||||||
|
"lastword",
|
||||||
|
"LDFLAGS",
|
||||||
|
"LDLIBS",
|
||||||
|
"let",
|
||||||
|
"LEX",
|
||||||
|
"LFLAGS",
|
||||||
|
"libexecdir",
|
||||||
|
"LINT",
|
||||||
|
"LINTFLAGS",
|
||||||
|
"load",
|
||||||
|
"LOADLIBES",
|
||||||
|
|
||||||
|
"M2C",
|
||||||
|
"MAKE",
|
||||||
|
"MAKE",
|
||||||
|
"MAKECMDGOALS",
|
||||||
|
"Makefile",
|
||||||
|
"makefile",
|
||||||
|
"MAKEFILES",
|
||||||
|
"MAKEFILES",
|
||||||
|
"MAKEFILE_LIST",
|
||||||
|
"MAKEFLAGS",
|
||||||
|
"MAKEINFO",
|
||||||
|
"MAKELEVEL",
|
||||||
|
"MAKELEVEL",
|
||||||
|
"MAKEOVERRIDES",
|
||||||
|
"MAKESHELL"
|
||||||
|
"MAKE_HOST",
|
||||||
|
"MAKE_RESTARTS"
|
||||||
|
"MAKE_TERMERR"
|
||||||
|
"MAKE_TERMOUT"
|
||||||
|
"MAKE_VERSION",
|
||||||
|
"MFLAGS",
|
||||||
|
|
||||||
|
"notdir",
|
||||||
|
|
||||||
|
"or",
|
||||||
|
"origin",
|
||||||
|
"OUTPUT_OPTION",
|
||||||
|
"override",
|
||||||
|
|
||||||
|
"patsubst",
|
||||||
|
"patsubst",
|
||||||
|
"PC",
|
||||||
|
"PFLAGS",
|
||||||
|
"prefix",
|
||||||
|
"private",
|
||||||
|
|
||||||
|
"realpath",
|
||||||
|
"RFLAGS",
|
||||||
|
"RM",
|
||||||
|
|
||||||
|
"sbindir",
|
||||||
|
"SHELL",
|
||||||
|
"shell",
|
||||||
|
"sort",
|
||||||
|
"strip",
|
||||||
|
"subst",
|
||||||
|
"subst",
|
||||||
|
"suffix",
|
||||||
|
"SUFFIXES",
|
||||||
|
|
||||||
|
"TANGLE",
|
||||||
|
"TEX",
|
||||||
|
"TEXI2DVI",
|
||||||
|
|
||||||
|
"undefine",
|
||||||
|
"unexport",
|
||||||
|
|
||||||
|
"value",
|
||||||
|
"VPATH",
|
||||||
|
"VPATH",
|
||||||
|
"vpath",
|
||||||
|
"vpath",
|
||||||
|
|
||||||
|
"warning",
|
||||||
|
"WEAVE",
|
||||||
|
"wildcard",
|
||||||
|
"wildcard",
|
||||||
|
"word",
|
||||||
|
"wordlist",
|
||||||
|
"words",
|
||||||
|
|
||||||
|
"YACC",
|
||||||
|
"YFLAGS",
|
||||||
|
};
|
||||||
|
|
||||||
|
MakefileHighlighter::MakefileHighlighter()
|
||||||
|
{
|
||||||
|
mTargetAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrClass, TokenType::Identifier);
|
||||||
|
addAttribute(mTargetAttribute);
|
||||||
|
mCommandAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrGlobalVariable, TokenType::Identifier);
|
||||||
|
addAttribute(mCommandAttribute);
|
||||||
|
mCommandParamAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrPreprocessor, TokenType::Identifier);
|
||||||
|
addAttribute(mCommandParamAttribute);
|
||||||
|
mNumberAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrNumber, TokenType::Number);
|
||||||
|
addAttribute(mNumberAttribute);
|
||||||
|
mVariableAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrLocalVariable, TokenType::Identifier);
|
||||||
|
addAttribute(mVariableAttribute);
|
||||||
|
mExpressionAttribute = std::make_shared<HighlighterAttribute>(SYNS_AttrFunction, TokenType::Identifier);
|
||||||
|
addAttribute(mExpressionAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procSpace()
|
||||||
|
{
|
||||||
|
mTokenID = TokenId::Space;
|
||||||
|
while (mLine[mRun]!=0 && mLine[mRun]<=32)
|
||||||
|
mRun++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procNumber()
|
||||||
|
{
|
||||||
|
while (isNumberChar(mLine[mRun]))
|
||||||
|
mRun++;
|
||||||
|
mTokenID = TokenId::Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procNull()
|
||||||
|
{
|
||||||
|
mTokenID = TokenId::Null;
|
||||||
|
mState = RangeState::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procString(bool inExpression )
|
||||||
|
{
|
||||||
|
mState = RangeState::String;
|
||||||
|
mTokenID = TokenId::String;
|
||||||
|
while (mLine[mRun] != 0) {
|
||||||
|
if (mLine[mRun] == '\"') {
|
||||||
|
mRun++;
|
||||||
|
popState();
|
||||||
|
break;
|
||||||
|
} else if (!inExpression && mLine[mRun] == '$') {
|
||||||
|
break;
|
||||||
|
} else if (isSpaceChar(mLine[mRun])) {
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
mRun++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procStringStart()
|
||||||
|
{
|
||||||
|
mRun++;
|
||||||
|
pushState();
|
||||||
|
procString(mState!=RangeState::BraceExpression
|
||||||
|
&& mState!=RangeState::ParenthesisExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procExpressionStart(ExpressionStartType type)
|
||||||
|
{
|
||||||
|
mRun+=2; //skip '$(' or '${'
|
||||||
|
pushState();
|
||||||
|
switch(type) {
|
||||||
|
case ExpressionStartType::Brace:
|
||||||
|
mState = RangeState::BraceExpression;
|
||||||
|
break;
|
||||||
|
case ExpressionStartType::Parenthesis:
|
||||||
|
mState = RangeState::ParenthesisExpression;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mTokenID = TokenId::Expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procExpressionEnd()
|
||||||
|
{
|
||||||
|
mTokenID = TokenId::Expression;
|
||||||
|
mRun+=1;
|
||||||
|
popState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procSymbol()
|
||||||
|
{
|
||||||
|
mTokenID = TokenId::Symbol;
|
||||||
|
mRun+=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procVariableExpression()
|
||||||
|
{
|
||||||
|
mRun+=1; //skip $
|
||||||
|
while (isIdentStartChar(mLine[mRun]))
|
||||||
|
mRun++;
|
||||||
|
mTokenID = TokenId::Variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procAutoVariable()
|
||||||
|
{
|
||||||
|
mRun+=1; //skip $
|
||||||
|
switch(mLine[mRun].unicode()) {
|
||||||
|
case '@':
|
||||||
|
case '%':
|
||||||
|
case '<':
|
||||||
|
case '?':
|
||||||
|
case '^':
|
||||||
|
case '+':
|
||||||
|
case '|':
|
||||||
|
case '*':
|
||||||
|
case '$':
|
||||||
|
mRun+=1;
|
||||||
|
mTokenID=TokenId::Expression;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mTokenID=TokenId::Symbol;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procAssignment()
|
||||||
|
{
|
||||||
|
mTokenID = TokenId::Symbol;
|
||||||
|
mRun++;
|
||||||
|
mState = RangeState::Assignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procDollar()
|
||||||
|
{
|
||||||
|
if (mLine[mRun+1]=='(') {
|
||||||
|
procExpressionStart(ExpressionStartType::Parenthesis);
|
||||||
|
} else if (mLine[mRun+1]=='{') {
|
||||||
|
procExpressionStart(ExpressionStartType::Brace);
|
||||||
|
} else if (isIdentStartChar(mLine[mRun+1])) {
|
||||||
|
procVariableExpression();
|
||||||
|
} else {
|
||||||
|
procAutoVariable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procComment()
|
||||||
|
{
|
||||||
|
mRun++; //skip #
|
||||||
|
mRun = mLineString.length();
|
||||||
|
mTokenID = TokenId::Comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::procIdentifier()
|
||||||
|
{
|
||||||
|
int start = mRun;
|
||||||
|
while (isIdentChar(mLine[mRun])) {
|
||||||
|
mRun++;
|
||||||
|
}
|
||||||
|
QString s = mLineString.mid(start,mRun-start).toLower();
|
||||||
|
if (Directives.contains(s)) {
|
||||||
|
mTokenID = TokenId::Directive;
|
||||||
|
} else {
|
||||||
|
switch(mState) {
|
||||||
|
case RangeState::Assignment:
|
||||||
|
case RangeState::BraceExpression:
|
||||||
|
case RangeState::ParenthesisExpression:
|
||||||
|
mTokenID = TokenId::Variable;
|
||||||
|
break;
|
||||||
|
case RangeState::CommandParameters:
|
||||||
|
mTokenID = TokenId::CommandParam;
|
||||||
|
break;
|
||||||
|
case RangeState::Command:
|
||||||
|
mTokenID = TokenId::Command;
|
||||||
|
mState = RangeState::CommandParameters;
|
||||||
|
break;
|
||||||
|
case RangeState::Prequisitions:
|
||||||
|
case RangeState::Unknown:
|
||||||
|
mTokenID = TokenId::Target;
|
||||||
|
break;
|
||||||
|
case RangeState::String:
|
||||||
|
mTokenID = TokenId::String;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MakefileHighlighter::pushState()
|
||||||
|
{
|
||||||
|
mStates.push_back(mState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::popState()
|
||||||
|
{
|
||||||
|
if (!mStates.empty()) {
|
||||||
|
mState = mStates.back();
|
||||||
|
mStates.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakefileHighlighter::isIdentChar(const QChar &ch) const
|
||||||
|
{
|
||||||
|
if (ch == '_' || ch =='-') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((ch>='0') && (ch <= '9')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((ch>='a') && (ch <= 'z')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((ch>='A') && (ch <= 'Z')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakefileHighlighter::eol() const
|
||||||
|
{
|
||||||
|
return mTokenID == TokenId::Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MakefileHighlighter::languageName()
|
||||||
|
{
|
||||||
|
return "makefile";
|
||||||
|
}
|
||||||
|
|
||||||
|
HighlighterLanguage MakefileHighlighter::language()
|
||||||
|
{
|
||||||
|
return HighlighterLanguage::Makefile;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MakefileHighlighter::getToken() const
|
||||||
|
{
|
||||||
|
return mLineString.mid(mTokenPos,mRun-mTokenPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PHighlighterAttribute &MakefileHighlighter::getTokenAttribute() const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Directive,
|
||||||
|
Unknown
|
||||||
|
*/
|
||||||
|
switch(mTokenID) {
|
||||||
|
case TokenId::Comment:
|
||||||
|
return mCommentAttribute;
|
||||||
|
case TokenId::Target:
|
||||||
|
return mTargetAttribute;
|
||||||
|
case TokenId::Command:
|
||||||
|
return mCommandAttribute;
|
||||||
|
case TokenId::CommandParam:
|
||||||
|
return mCommandParamAttribute;
|
||||||
|
case TokenId::Number:
|
||||||
|
return mNumberAttribute;
|
||||||
|
case TokenId::Space:
|
||||||
|
return mWhitespaceAttribute;
|
||||||
|
case TokenId::String:
|
||||||
|
return mStringAttribute;
|
||||||
|
case TokenId::Identifier:
|
||||||
|
return mIdentifierAttribute;
|
||||||
|
case TokenId::Variable:
|
||||||
|
return mVariableAttribute;
|
||||||
|
case TokenId::Expression:
|
||||||
|
return mExpressionAttribute;
|
||||||
|
case TokenId::Symbol:
|
||||||
|
return mSymbolAttribute;
|
||||||
|
case TokenId::Directive:
|
||||||
|
return mKeywordAttribute;
|
||||||
|
default:
|
||||||
|
return mSymbolAttribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MakefileHighlighter::getTokenPos()
|
||||||
|
{
|
||||||
|
return mTokenPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::next()
|
||||||
|
{
|
||||||
|
mTokenPos = mRun;
|
||||||
|
if (mLine[mRun].unicode()==0) {
|
||||||
|
procNull();
|
||||||
|
return;
|
||||||
|
} else if (mRun==0 && mLine[mRun]=='\t') {
|
||||||
|
mState = RangeState::Command;
|
||||||
|
procSpace();
|
||||||
|
return;
|
||||||
|
} else if (isSpaceChar(mLine[mRun].unicode())) {
|
||||||
|
procSpace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(mState) {
|
||||||
|
case RangeState::String:
|
||||||
|
if (mLine[mRun] == '$')
|
||||||
|
procDollar();
|
||||||
|
else
|
||||||
|
procString(false);
|
||||||
|
break;
|
||||||
|
case RangeState::Command:
|
||||||
|
case RangeState::CommandParameters:
|
||||||
|
case RangeState::Prequisitions:
|
||||||
|
case RangeState::Assignment:
|
||||||
|
switch(mLine[mRun].unicode()) {
|
||||||
|
case '$':
|
||||||
|
procDollar();
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
procStringStart();
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
procComment();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mLine[mRun]>='0' && mLine[mRun]<='9') {
|
||||||
|
procNumber();
|
||||||
|
} else if (isIdentStartChar(mLine[mRun])) {
|
||||||
|
procIdentifier();
|
||||||
|
} else {
|
||||||
|
procSymbol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RangeState::ParenthesisExpression:
|
||||||
|
case RangeState::BraceExpression:
|
||||||
|
switch(mLine[mRun].unicode()) {
|
||||||
|
case '$':
|
||||||
|
procDollar();
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
if (mState == RangeState::ParenthesisExpression)
|
||||||
|
procExpressionEnd();
|
||||||
|
else
|
||||||
|
procSymbol();
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
if (mState == RangeState::BraceExpression)
|
||||||
|
procExpressionEnd();
|
||||||
|
else
|
||||||
|
procSymbol();
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
procComment();
|
||||||
|
break;
|
||||||
|
case '@':
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
case '%':
|
||||||
|
case '^':
|
||||||
|
case '<':
|
||||||
|
case '?':
|
||||||
|
if (mLine[mRun]=='D' || mLine[mRun]=='F') {
|
||||||
|
//auto variable
|
||||||
|
mRun+=2;
|
||||||
|
mTokenID = TokenId::Variable;
|
||||||
|
} else
|
||||||
|
procSymbol();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mLine[mRun]>='0' && mLine[mRun]<='9') {
|
||||||
|
procNumber();
|
||||||
|
} else if (isIdentStartChar(mLine[mRun])) {
|
||||||
|
procIdentifier();
|
||||||
|
} else {
|
||||||
|
procSymbol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RangeState::Unknown:
|
||||||
|
switch(mLine[mRun].unicode()) {
|
||||||
|
case '$':
|
||||||
|
procDollar();
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
procComment();
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
procStringStart();
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
case '+':
|
||||||
|
if (mLine[mRun+1]=='=') {
|
||||||
|
mRun++;
|
||||||
|
procAssignment();
|
||||||
|
} else {
|
||||||
|
procSymbol();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
if (mLine[mRun+1]=='=') {
|
||||||
|
mRun++;
|
||||||
|
procAssignment();
|
||||||
|
} else {
|
||||||
|
mRun++;
|
||||||
|
mTokenID = TokenId::Target;
|
||||||
|
mState = RangeState::Prequisitions;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
procAssignment();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (mLine[mRun]>='0' && mLine[mRun]<='9') {
|
||||||
|
procNumber();
|
||||||
|
} else if (isIdentStartChar(mLine[mRun])) {
|
||||||
|
procIdentifier();
|
||||||
|
} else {
|
||||||
|
procSymbol();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::setLine(const QString &newLine, int lineNumber)
|
||||||
|
{
|
||||||
|
mLineString = newLine;
|
||||||
|
mLine = mLineString.data();
|
||||||
|
mLineNumber = lineNumber;
|
||||||
|
mRun = 0;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakefileHighlighter::getTokenFinished() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakefileHighlighter::isLastLineCommentNotFinished(int /*state*/) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakefileHighlighter::isLastLineStringNotFinished(int /*state*/) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HighlighterState MakefileHighlighter::getState() const
|
||||||
|
{
|
||||||
|
HighlighterState state;
|
||||||
|
state.state = (int)mState;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::setState(const HighlighterState & rangeState)
|
||||||
|
{
|
||||||
|
mState = (RangeState)rangeState.state;
|
||||||
|
mStates.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakefileHighlighter::resetState()
|
||||||
|
{
|
||||||
|
mState = RangeState::Unknown;
|
||||||
|
mStates.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QString> MakefileHighlighter::keywords() const
|
||||||
|
{
|
||||||
|
return Directives;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* 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 MAKEFILEHIGHLIGHTER_H
|
||||||
|
#define MAKEFILEHIGHLIGHTER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base.h"
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
|
||||||
|
class MakefileHighlighter : public Highlighter
|
||||||
|
{
|
||||||
|
enum class TokenId {
|
||||||
|
Null,
|
||||||
|
Comment,
|
||||||
|
Target,
|
||||||
|
Command,
|
||||||
|
CommandParam,
|
||||||
|
Number,
|
||||||
|
Space,
|
||||||
|
String,
|
||||||
|
Identifier,
|
||||||
|
Variable,
|
||||||
|
Expression,
|
||||||
|
Symbol,
|
||||||
|
Directive
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RangeState {
|
||||||
|
Unknown, String,
|
||||||
|
/* Targets, */
|
||||||
|
Prequisitions,
|
||||||
|
Command,
|
||||||
|
CommandParameters,
|
||||||
|
ParenthesisExpression,
|
||||||
|
BraceExpression,
|
||||||
|
Assignment,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExpressionStartType {
|
||||||
|
Parenthesis,
|
||||||
|
Brace
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MakefileHighlighter();
|
||||||
|
|
||||||
|
static const QSet<QString> Directives;
|
||||||
|
private:
|
||||||
|
QChar* mLine;
|
||||||
|
QString mLineString;
|
||||||
|
int mLineNumber;
|
||||||
|
int mRun;
|
||||||
|
int mStringLen;
|
||||||
|
int mTokenPos;
|
||||||
|
QVector<RangeState> mStates;
|
||||||
|
RangeState mState;
|
||||||
|
TokenId mTokenID;
|
||||||
|
|
||||||
|
PHighlighterAttribute mTargetAttribute;
|
||||||
|
PHighlighterAttribute mCommandAttribute;
|
||||||
|
PHighlighterAttribute mCommandParamAttribute;
|
||||||
|
PHighlighterAttribute mNumberAttribute;
|
||||||
|
PHighlighterAttribute mVariableAttribute;
|
||||||
|
PHighlighterAttribute mExpressionAttribute;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void procSpace();
|
||||||
|
void procNumber();
|
||||||
|
void procNull();
|
||||||
|
void procString(bool inExpression );
|
||||||
|
void procStringStart();
|
||||||
|
void procExpressionStart(ExpressionStartType type);
|
||||||
|
void procExpressionEnd();
|
||||||
|
void procSymbol();
|
||||||
|
void procVariableExpression();
|
||||||
|
void procAutoVariable();
|
||||||
|
void procAssignment();
|
||||||
|
void procDollar();
|
||||||
|
void procComment();
|
||||||
|
void procIdentifier();
|
||||||
|
|
||||||
|
void pushState();
|
||||||
|
void popState();
|
||||||
|
bool isIdentStartChar(const QChar& ch) {
|
||||||
|
if (ch == '_') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((ch>='a') && (ch <= 'z')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((ch>='A') && (ch <= 'Z')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNumberChar(const QChar& ch) {
|
||||||
|
return (ch>='0') && (ch<='9');
|
||||||
|
}
|
||||||
|
|
||||||
|
// SynHighlighter interface
|
||||||
|
public:
|
||||||
|
bool eol() const override;
|
||||||
|
|
||||||
|
QString languageName() override;
|
||||||
|
HighlighterLanguage language() override;
|
||||||
|
QString getToken() const override;
|
||||||
|
const PHighlighterAttribute &getTokenAttribute() const override;
|
||||||
|
int getTokenPos() override;
|
||||||
|
void next() override;
|
||||||
|
void setLine(const QString &newLine, int lineNumber) override;
|
||||||
|
|
||||||
|
// SynHighlighter interface
|
||||||
|
public:
|
||||||
|
bool getTokenFinished() const override;
|
||||||
|
bool isLastLineCommentNotFinished(int state) const override;
|
||||||
|
bool isLastLineStringNotFinished(int state) const override;
|
||||||
|
HighlighterState getState() const override;
|
||||||
|
void setState(const HighlighterState& rangeState) override;
|
||||||
|
void resetState() override;
|
||||||
|
|
||||||
|
bool isIdentChar(const QChar& ch) const override;
|
||||||
|
public:
|
||||||
|
QSet<QString> keywords() const override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // MAKEFILEHIGHLIGHTER_H
|
Loading…
Reference in New Issue