Improve JavaScriptHighlighter
* Fix greediness for string highlighting * Adjust colors * Port to QRegularExpression
This commit is contained in:
parent
db2f178542
commit
a32db9e33d
|
@ -7,69 +7,78 @@ JavaScriptHighlighter::JavaScriptHighlighter(QTextDocument *parent)
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
HighlightingRule rule;
|
||||||
|
|
||||||
m_keywordFormat.setForeground(Qt::darkBlue);
|
|
||||||
m_keywordFormat.setFontWeight(QFont::Bold);
|
m_keywordFormat.setFontWeight(QFont::Bold);
|
||||||
static const QStringList keywordPatterns{ QStringLiteral("\\bvar\\b"), QStringLiteral("\\bArray\\b"), QStringLiteral("\\bfunction\\b"),
|
static const QStringList keywordPatterns{ QStringLiteral("\\bvar\\b"), QStringLiteral("\\bArray\\b"), QStringLiteral("\\bfunction\\b"),
|
||||||
QStringLiteral("\\breturn\\b"), QStringLiteral("\\barguments\\b"), QStringLiteral("\\bif\\b"), QStringLiteral("\\belse\\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("\\bfor\\b"), QStringLiteral("\\bswitch\\b"), QStringLiteral("\\bcase\\b"), QStringLiteral("\\bbreak\\b"),
|
||||||
QStringLiteral("\\bwhile\\b"), QStringLiteral("\\bundefined\\b"), QStringLiteral("\\continue\\b") };
|
QStringLiteral("\\bwhile\\b"), QStringLiteral("\\bundefined\\b"), QStringLiteral("\\continue\\b") };
|
||||||
for (const QString &pattern : keywordPatterns) {
|
for (const auto &pattern : keywordPatterns) {
|
||||||
rule.pattern = QRegExp(pattern);
|
rule.pattern = QRegularExpression(pattern);
|
||||||
|
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
|
||||||
rule.format = m_keywordFormat;
|
rule.format = m_keywordFormat;
|
||||||
m_highlightingRules.append(rule);
|
m_highlightingRules.append(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_singleLineCommentFormat.setForeground(Qt::red);
|
m_singleLineCommentFormat.setForeground(Qt::darkGray);
|
||||||
rule.pattern = QRegExp(QStringLiteral("//[^\n]*"));
|
rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*"));
|
||||||
rule.format = m_singleLineCommentFormat;
|
rule.format = m_singleLineCommentFormat;
|
||||||
m_highlightingRules.append(rule);
|
m_highlightingRules.append(rule);
|
||||||
|
|
||||||
m_multiLineCommentFormat.setForeground(Qt::red);
|
m_multiLineCommentFormat.setForeground(Qt::darkGray);
|
||||||
|
|
||||||
m_quotationFormat.setForeground(Qt::darkGreen);
|
m_regexFormat.setForeground(Qt::darkMagenta);
|
||||||
rule.pattern = QRegExp(QStringLiteral("\".*\""));
|
rule.pattern = QRegularExpression(QStringLiteral("/.*/"));
|
||||||
rule.format = m_quotationFormat;
|
rule.pattern.setPatternOptions(QRegularExpression::InvertedGreedinessOption);
|
||||||
|
rule.format = m_regexFormat;
|
||||||
m_highlightingRules.append(rule);
|
m_highlightingRules.append(rule);
|
||||||
|
|
||||||
m_functionFormat.setFontItalic(true);
|
m_stringFormat.setForeground(Qt::darkGreen);
|
||||||
m_functionFormat.setForeground(Qt::blue);
|
rule.pattern = QRegularExpression(QStringLiteral("\".*\""));
|
||||||
rule.pattern = QRegExp(QStringLiteral("(?!if)\\b[A-Za-z0-9_]+(?=\\()"));
|
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;
|
rule.format = m_functionFormat;
|
||||||
m_highlightingRules.append(rule);
|
m_highlightingRules.append(rule);
|
||||||
|
|
||||||
m_commentStartExpression = QRegExp(QStringLiteral("/\\*"));
|
m_commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
|
||||||
m_commentEndExpression = QRegExp(QStringLiteral("\\*/"));
|
m_commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaScriptHighlighter::highlightBlock(const QString &text)
|
void JavaScriptHighlighter::highlightBlock(const QString &text)
|
||||||
{
|
{
|
||||||
for (const HighlightingRule &rule : m_highlightingRules) {
|
for (const auto &rule : m_highlightingRules) {
|
||||||
QRegExp expression(rule.pattern);
|
const auto &expression(rule.pattern);
|
||||||
int index = expression.indexIn(text);
|
auto match = expression.match(text);
|
||||||
while (index >= 0) {
|
while (match.hasMatch()) {
|
||||||
int length = expression.matchedLength();
|
const auto index = match.capturedStart();
|
||||||
|
const auto length = match.capturedLength();
|
||||||
setFormat(index, length, rule.format);
|
setFormat(index, length, rule.format);
|
||||||
index = expression.indexIn(text, index + length);
|
match = expression.match(text, index + length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrentBlockState(0);
|
setCurrentBlockState(0);
|
||||||
|
|
||||||
int startIndex = 0;
|
auto startIndex = 0;
|
||||||
if (previousBlockState() != 1) {
|
if (previousBlockState() != 1) {
|
||||||
startIndex = m_commentStartExpression.indexIn(text);
|
startIndex = m_commentStartExpression.match(text).capturedStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (startIndex >= 0) {
|
while (startIndex >= 0) {
|
||||||
int endIndex = m_commentEndExpression.indexIn(text, startIndex);
|
const auto endMatch = m_commentEndExpression.match(text, startIndex);
|
||||||
int commentLength;
|
const auto endIndex = endMatch.capturedStart();
|
||||||
if (endIndex == -1) {
|
const auto commentLength = [&] {
|
||||||
|
if (endIndex >= 0) {
|
||||||
|
return endIndex - startIndex + endMatch.capturedLength();
|
||||||
|
}
|
||||||
setCurrentBlockState(1);
|
setCurrentBlockState(1);
|
||||||
commentLength = text.length() - startIndex;
|
return text.length() - startIndex;
|
||||||
} else {
|
}();
|
||||||
commentLength = endIndex - startIndex + m_commentEndExpression.matchedLength();
|
|
||||||
}
|
|
||||||
setFormat(startIndex, commentLength, m_multiLineCommentFormat);
|
setFormat(startIndex, commentLength, m_multiLineCommentFormat);
|
||||||
startIndex = m_commentStartExpression.indexIn(text, startIndex + commentLength);
|
startIndex = m_commentStartExpression.match(text, startIndex + commentLength).capturedStart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef JAVASCRIPTHIGHLIGHTER_H
|
#ifndef JAVASCRIPTHIGHLIGHTER_H
|
||||||
#define JAVASCRIPTHIGHLIGHTER_H
|
#define JAVASCRIPTHIGHLIGHTER_H
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
|
|
||||||
namespace QtGui {
|
namespace QtGui {
|
||||||
|
@ -12,23 +13,24 @@ public:
|
||||||
JavaScriptHighlighter(QTextDocument *parent = nullptr);
|
JavaScriptHighlighter(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text);
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct HighlightingRule {
|
struct HighlightingRule {
|
||||||
QRegExp pattern;
|
QRegularExpression pattern;
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
};
|
};
|
||||||
QVector<HighlightingRule> m_highlightingRules;
|
QVector<HighlightingRule> m_highlightingRules;
|
||||||
|
|
||||||
QRegExp m_commentStartExpression;
|
QRegularExpression m_commentStartExpression;
|
||||||
QRegExp m_commentEndExpression;
|
QRegularExpression m_commentEndExpression;
|
||||||
|
|
||||||
QTextCharFormat m_keywordFormat;
|
QTextCharFormat m_keywordFormat;
|
||||||
QTextCharFormat m_classFormat;
|
QTextCharFormat m_classFormat;
|
||||||
QTextCharFormat m_singleLineCommentFormat;
|
QTextCharFormat m_singleLineCommentFormat;
|
||||||
QTextCharFormat m_multiLineCommentFormat;
|
QTextCharFormat m_multiLineCommentFormat;
|
||||||
QTextCharFormat m_quotationFormat;
|
QTextCharFormat m_stringFormat;
|
||||||
|
QTextCharFormat m_regexFormat;
|
||||||
QTextCharFormat m_functionFormat;
|
QTextCharFormat m_functionFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue