tageditor/gui/javascripthighlighter.cpp

89 lines
3.9 KiB
C++

#include "./javascripthighlighter.h"
#include "../misc/utility.h"
namespace QtGui {
JavaScriptHighlighter::JavaScriptHighlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent)
{
HighlightingRule rule;
m_keywordFormat.setFontWeight(QFont::Bold);
static const QStringList keywordPatterns{ QStringLiteral("\\bvar\\b"), QStringLiteral("\\blet\\b"), QStringLiteral("\\bconst\\b"),
QStringLiteral("\\bArray\\b"), QStringLiteral("\\bfunction\\b"), QStringLiteral("\\breturn\\b"), QStringLiteral("\\barguments\\b"),
QStringLiteral("\\bif\\b"), QStringLiteral("\\belse\\b"), QStringLiteral("\\bfor\\b"), QStringLiteral("\\bswitch\\b"),
QStringLiteral("\\bcase\\b"), QStringLiteral("\\bbreak\\b"), QStringLiteral("\\bwhile\\b"), QStringLiteral("\\bundefined\\b"),
QStringLiteral("\\bnull\\b"), QStringLiteral("\\bcontinue\\b"), QStringLiteral("\\bfalse\\b"), QStringLiteral("\\btrue\\b") };
for (const auto &pattern : keywordPatterns) {
rule.pattern = QRegularExpression(pattern);
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
rule.format = m_keywordFormat;
m_highlightingRules.append(rule);
}
m_singleLineCommentFormat.setForeground(Qt::darkGray);
rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*"));
rule.format = m_singleLineCommentFormat;
m_highlightingRules.append(rule);
m_multiLineCommentFormat.setForeground(Qt::darkGray);
m_regexFormat.setForeground(Qt::darkMagenta);
rule.pattern = QRegularExpression(QStringLiteral("/.*/"));
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
rule.format = m_regexFormat;
m_highlightingRules.append(rule);
m_stringFormat.setForeground(Qt::darkGreen);
rule.pattern = QRegularExpression(QStringLiteral("\".*\""));
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
rule.format = m_stringFormat;
m_highlightingRules.append(rule);
m_functionFormat.setForeground(Qt::darkBlue);
rule.pattern = QRegularExpression(QStringLiteral("(?!if)\\b[A-Za-z0-9_]+(?=\\()"));
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
rule.format = m_functionFormat;
m_highlightingRules.append(rule);
m_commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
m_commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
}
void JavaScriptHighlighter::highlightBlock(const QString &text)
{
for (const auto &rule : m_highlightingRules) {
const auto &expression(rule.pattern);
auto match = expression.match(text);
while (match.hasMatch()) {
const auto index = Utility::containerSizeToInt(match.capturedStart());
const auto length = Utility::containerSizeToInt(match.capturedLength());
setFormat(index, length, rule.format);
match = expression.match(text, index + length);
}
}
setCurrentBlockState(0);
auto startIndex = 0;
if (previousBlockState() != 1) {
startIndex = Utility::containerSizeToInt(m_commentStartExpression.match(text).capturedStart());
}
while (startIndex >= 0) {
const auto endMatch = m_commentEndExpression.match(text, startIndex);
const auto endIndex = Utility::containerSizeToInt(endMatch.capturedStart());
const auto commentLength = [&] {
if (endIndex >= 0) {
return endIndex - startIndex + Utility::containerSizeToInt(endMatch.capturedLength());
}
setCurrentBlockState(1);
return Utility::containerSizeToInt(text.length()) - startIndex;
}();
setFormat(startIndex, commentLength, m_multiLineCommentFormat);
startIndex = Utility::containerSizeToInt(m_commentStartExpression.match(text, startIndex + commentLength).capturedStart());
}
}
} // namespace QtGui