- 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
|
||||
|
||||
- enhancement: New color scheme Monokai (contributed by 小龙Dev(XiaoLoong@github))
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include "qsynedit/highlighter/cpp.h"
|
||||
#include "qsynedit/highlighter/asm.h"
|
||||
#include "qsynedit/highlighter/glsl.h"
|
||||
#include "qsynedit/highlighter/makefilehighlighter.h"
|
||||
|
||||
#include "qsynedit/Constants.h"
|
||||
#include "colorscheme.h"
|
||||
|
||||
|
@ -38,6 +40,8 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(QSynedit::HighlighterL
|
|||
return getCppHighlighter();
|
||||
case QSynedit::HighlighterLanguage::Asssembly:
|
||||
return getAsmHighlighter();
|
||||
case QSynedit::HighlighterLanguage::Makefile:
|
||||
return getMakefileHighlighter();
|
||||
case QSynedit::HighlighterLanguage::GLSL:
|
||||
return getGLSLHighlighter();
|
||||
default:
|
||||
|
@ -49,6 +53,7 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(const QString &filenam
|
|||
{
|
||||
QFileInfo info(filename);
|
||||
QString suffix = info.suffix();
|
||||
QString basename = info.baseName();
|
||||
if (suffix.isEmpty() || suffix == "c" || suffix == "cpp" || suffix == "cxx"
|
||||
|| suffix == "cc" || suffix == "h" || suffix == "hpp"
|
||||
|| suffix == "hxx" || suffix == "hh" || suffix == "C"
|
||||
|
@ -59,7 +64,8 @@ QSynedit::PHighlighter HighlighterManager::getHighlighter(const QString &filenam
|
|||
return getGLSLHighlighter();
|
||||
} else if (suffix == "s" || suffix == "asm") {
|
||||
return getAsmHighlighter();
|
||||
}
|
||||
} else if (basename.compare("makefile", Qt::CaseInsensitive)==0)
|
||||
return getMakefileHighlighter();
|
||||
return QSynedit::PHighlighter();
|
||||
}
|
||||
|
||||
|
@ -67,14 +73,7 @@ QSynedit::PHighlighter HighlighterManager::copyHighlighter(QSynedit::PHighlighte
|
|||
{
|
||||
if (!highlighter)
|
||||
return QSynedit::PHighlighter();
|
||||
if (highlighter->language() == QSynedit::HighlighterLanguage::Cpp)
|
||||
return getCppHighlighter();
|
||||
else if (highlighter->language() == QSynedit::HighlighterLanguage::Asssembly)
|
||||
return getAsmHighlighter();
|
||||
else if (highlighter->language() == QSynedit::HighlighterLanguage::GLSL)
|
||||
return getGLSLHighlighter();
|
||||
//todo
|
||||
return QSynedit::PHighlighter();
|
||||
return getHighlighter(highlighter->language());
|
||||
}
|
||||
|
||||
QSynedit::PHighlighter HighlighterManager::getCppHighlighter()
|
||||
|
@ -95,26 +94,29 @@ QSynedit::PHighlighter HighlighterManager::getGLSLHighlighter()
|
|||
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)
|
||||
{
|
||||
if (!highlighter)
|
||||
return;
|
||||
if ( (highlighter->language() == QSynedit::HighlighterLanguage::Cpp)
|
||||
|| (highlighter->language() == QSynedit::HighlighterLanguage::Asssembly)
|
||||
) {
|
||||
for (QString name: highlighter->attributes().keys()) {
|
||||
PColorSchemeItem item = pColorManager->getItem(schemeName,name);
|
||||
if (item) {
|
||||
QSynedit::PHighlighterAttribute attr = highlighter->attributes()[name];
|
||||
attr->setBackground(item->background());
|
||||
attr->setForeground(item->foreground());
|
||||
QSynedit::FontStyles styles = QSynedit::FontStyle::fsNone;
|
||||
styles.setFlag(QSynedit::FontStyle::fsBold, item->bold());
|
||||
styles.setFlag(QSynedit::FontStyle::fsItalic, item->italic());
|
||||
styles.setFlag(QSynedit::FontStyle::fsUnderline, item->underlined());
|
||||
styles.setFlag(QSynedit::FontStyle::fsStrikeOut, item->strikeout());
|
||||
attr->setStyles(styles);
|
||||
}
|
||||
|
||||
for (QString name: highlighter->attributes().keys()) {
|
||||
PColorSchemeItem item = pColorManager->getItem(schemeName,name);
|
||||
if (item) {
|
||||
QSynedit::PHighlighterAttribute attr = highlighter->attributes()[name];
|
||||
attr->setBackground(item->background());
|
||||
attr->setForeground(item->foreground());
|
||||
QSynedit::FontStyles styles = QSynedit::FontStyle::fsNone;
|
||||
styles.setFlag(QSynedit::FontStyle::fsBold, item->bold());
|
||||
styles.setFlag(QSynedit::FontStyle::fsItalic, item->italic());
|
||||
styles.setFlag(QSynedit::FontStyle::fsUnderline, item->underlined());
|
||||
styles.setFlag(QSynedit::FontStyle::fsStrikeOut, item->strikeout());
|
||||
attr->setStyles(styles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
QSynedit::PHighlighter getCppHighlighter();
|
||||
QSynedit::PHighlighter getAsmHighlighter();
|
||||
QSynedit::PHighlighter getGLSLHighlighter();
|
||||
QSynedit::PHighlighter getMakefileHighlighter();
|
||||
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
|
||||
|
||||
## fixed lrelease.prf
|
||||
# fixed lrelease.prf
|
||||
qtPrepareTool(QMAKE_LRELEASE, lrelease)
|
||||
|
||||
isEmpty(LRELEASE_DIR): LRELEASE_DIR = .qm
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
#include "project.h"
|
||||
#include <qt_utils/charsetinfo.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
SaveException::SaveException(const QString& reason) {
|
||||
mReason = reason;
|
||||
mReasonBuffer = mReason.toLocal8Bit();
|
||||
|
@ -912,7 +910,7 @@ void Editor::onGetEditingAreas(int Line, QSynedit::EditingAreaList &areaList)
|
|||
{
|
||||
areaList.clear();
|
||||
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;
|
||||
// int spaceCount = leftSpaces(mLineBeforeTabStop);
|
||||
// int spaceBefore = mLineBeforeTabStop.length()-TrimLeft(mLineBeforeTabStop).length();
|
||||
|
|
|
@ -1331,8 +1331,8 @@ void MainWindow::setProjectCurrentFile(const QString &filename)
|
|||
if (!unit)
|
||||
return;
|
||||
QModelIndex index = mProject->model()->getNodeIndex(unit->node().get());
|
||||
index = mProjectProxyModel->mapFromSource(index);
|
||||
if (index.isValid()) {
|
||||
index = mProjectProxyModel->mapFromSource(index);
|
||||
ui->projectView->expand(index);
|
||||
ui->projectView->setCurrentIndex(index);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ SOURCES += qsynedit/CodeFolding.cpp \
|
|||
qsynedit/Search.cpp \
|
||||
qsynedit/SearchBase.cpp \
|
||||
qsynedit/SearchRegex.cpp \
|
||||
qsynedit/Types.cpp
|
||||
qsynedit/Types.cpp \
|
||||
qsynedit/highlighter/makefilehighlighter.cpp
|
||||
|
||||
HEADERS += qsynedit/Search.h \
|
||||
qsynedit/SearchBase.h \
|
||||
|
@ -62,5 +63,6 @@ HEADERS += qsynedit/Search.h \
|
|||
qsynedit/highlighter/cpp.h \
|
||||
qsynedit/highlighter/customhighlighterv1.h \
|
||||
qsynedit/highlighter/glsl.h \
|
||||
qsynedit/highlighter/makefilehighlighter.h
|
||||
|
||||
INCLUDEPATH += ../redpanda_qt_utils
|
||||
|
|
|
@ -80,6 +80,7 @@ enum class HighlighterLanguage {
|
|||
Asssembly,
|
||||
Cpp,
|
||||
GLSL,
|
||||
Makefile,
|
||||
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