Add C Syntax highlighter
The C syntax highlighter is heavily based on the Qt built-in
syntax highlighting example
ADD
src/editor/csyntaxhighlighter.cpp
+#include "csyntaxhighlighter.h"
+
+#include "defines.h"
+
+namespace Ripes {
+
+CSyntaxHighlighter::CSyntaxHighlighter(QTextDocument* parent) : SyntaxHighlighter(parent) {
+ HighlightingRule rule;
+
+ keywordFormat.setForeground(Qt::darkBlue);
+ keywordFormat.setFontWeight(QFont::Bold);
+ const QString keywordPatterns[] = {
+ QStringLiteral("\\bconst\\b"), QStringLiteral("\\benum\\b"), QStringLiteral("\\binline\\b"),
+ QStringLiteral("\\bshort\\b"), QStringLiteral("\\bstatic\\b"), QStringLiteral("\\bstruct\\b"),
+ QStringLiteral("\\btypedef\\b"), QStringLiteral("\\btypename\\b"), QStringLiteral("\\bunion\\b"),
+ QStringLiteral("\\bvolatile\\b"), QStringLiteral("\\bbreak\\b"), QStringLiteral("\\bcase\\b"),
+ QStringLiteral("\\bif\\b"), QStringLiteral("\\belse\\b"), QStringLiteral("\\bdo\\b"),
+ QStringLiteral("\\bwhile\\b"), QStringLiteral("\\bcontinue\\b"), QStringLiteral("\\bfor\\b"),
+ QStringLiteral("\\bextern\\b"), QStringLiteral("\\bgoto\\b"), QStringLiteral("\\bswitch\\b"),
+ QStringLiteral("\\bregister\\b"), QStringLiteral("\\breturn\\b"), QStringLiteral("\\bsizeof\\b"),
+ QStringLiteral("\\b__asm__\\b"), QStringLiteral("\\basm\\b")};
+
+ for (const QString& pattern : keywordPatterns) {
+ rule.pattern = QRegularExpression(pattern);
+ rule.format = keywordFormat;
+ highlightingRules.append(rule);
+ }
+
+ typeFormat.setForeground(Qt::darkBlue);
+ typeFormat.setFontWeight(QFont::Bold);
+ const QString typePatterns[] = {QStringLiteral("\\bchar\\b"), QStringLiteral("\\bfloat\\b"),
+ QStringLiteral("\\bdouble\\b"), QStringLiteral("\\bint\\b"),
+ QStringLiteral("\\blong\\b"), QStringLiteral("\\bshort\\b"),
+ QStringLiteral("\\bsigned\\b"), QStringLiteral("\\bunsigned\\b"),
+ QStringLiteral("\\bvoid\\b"), QStringLiteral("\\bbool\\b")};
+ for (const QString& pattern : typePatterns) {
+ rule.pattern = QRegularExpression(pattern);
+ rule.format = typeFormat;
+ highlightingRules.append(rule);
+ }
+
+ singleLineCommentFormat.setForeground(QColor(Colors::Medalist));
+ rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*"));
+ rule.format = singleLineCommentFormat;
+ highlightingRules.append(rule);
+
+ multiLineCommentFormat.setForeground(QColor(Colors::Medalist));
+
+ quotationFormat.setForeground(QColor(0x800000));
+ rule.pattern = QRegularExpression(QStringLiteral("\".*\""));
+ rule.format = quotationFormat;
+ highlightingRules.append(rule);
+
+ functionFormat.setForeground(QColor(Colors::BerkeleyBlue));
+ rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z0-9_]+(?=\\()"));
+ rule.format = functionFormat;
+ highlightingRules.append(rule);
+
+ commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
+ commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
+} // namespace Ripes
+
+void CSyntaxHighlighter::reset() {
+ SyntaxHighlighter::reset();
+}
+bool CSyntaxHighlighter::acceptsSyntax() const {
+ return true;
+}
+
+void CSyntaxHighlighter::clearAndRehighlight() {
+ rehighlight();
+}
+
+void CSyntaxHighlighter::highlightBlock(const QString& text) {
+ for (const HighlightingRule& rule : qAsConst(highlightingRules)) {
+ QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
+ while (matchIterator.hasNext()) {
+ QRegularExpressionMatch match = matchIterator.next();
+ setFormat(match.capturedStart(), match.capturedLength(), rule.format);
+ }
+ }
+
+ setCurrentBlockState(0);
+
+ int startIndex = 0;
+ if (previousBlockState() != 1)
+ startIndex = text.indexOf(commentStartExpression);
+
+ while (startIndex >= 0) {
+ QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
+ int endIndex = match.capturedStart();
+ int commentLength = 0;
+ if (endIndex == -1) {
+ setCurrentBlockState(1);
+ commentLength = text.length() - startIndex;
+ } else {
+ commentLength = endIndex - startIndex + match.capturedLength();
+ }
+ setFormat(startIndex, commentLength, multiLineCommentFormat);
+ startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
+ }
+}
+
+} // namespace Ripes

ADD
src/editor/csyntaxhighlighter.h
+#pragma once
+
+#include <QRegularExpression>
+
+#include "syntaxhighlighter.h"
+
+/** Heavily based on QT's rich text syntax highlighter example.
+ http://doc.qt.io/qt-5/qtwidgets-richtext-syntaxhighlighter-example.html
+ */
+
+namespace Ripes {
+
+class CSyntaxHighlighter : public SyntaxHighlighter {
+public:
+ CSyntaxHighlighter(QTextDocument* parent = nullptr);
+
+ void reset() override;
+ bool acceptsSyntax() const override;
+ void highlightBlock(const QString& text) override;
+
+public slots:
+ void clearAndRehighlight() override;
+
+private:
+ struct HighlightingRule {
+ QRegularExpression pattern;
+ QTextCharFormat format;
+ };
+ QVector<HighlightingRule> highlightingRules;
+
+ QRegularExpression commentStartExpression;
+ QRegularExpression commentEndExpression;
+
+ QTextCharFormat keywordFormat;
+ QTextCharFormat typeFormat;
+ QTextCharFormat singleLineCommentFormat;
+ QTextCharFormat multiLineCommentFormat;
+ QTextCharFormat quotationFormat;
+ QTextCharFormat functionFormat;
+};
+
+} // namespace Ripes

MODIFY
src/editor/rvassemblyhighlighter.h
src/editor/rvassemblyhighlighter.h
#pragma once
+#include <QRegularExpression>
+
#include "syntaxhighlighter.h"
namespace Ripes {
@@ -34,10 +36,10 @@ public:
void highlightBlock(const QString& text) override;
void reset() override;
- QString checkSyntax(const QString& line) override;
bool acceptsSyntax() const override;
private:
+ QString checkSyntax(const QString& line);
struct HighlightingRule {
QRegularExpression pattern;
QTextCharFormat format;

MODIFY
src/editor/syntaxhighlighter.cpp
src/editor/syntaxhighlighter.cpp
namespace Ripes {
SyntaxHighlighter::SyntaxHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) {
- connect(this->document(), &QTextDocument::blockCountChanged, [=] {
+ connect(this->document(), &QTextDocument::blockCountChanged, this, &SyntaxHighlighter::handleBlockCountChanged);
+}
+
+void SyntaxHighlighter::handleBlockCountChanged() {
clearAndRehighlight();
const auto tooltipsCopy = m_tooltipForLine; // deep copy
// Remove any tooltip for lines which have been deleted
@@ -13,7 +16,6 @@ SyntaxHighlighter::SyntaxHighlighter(QTextDocument* parent) : QSyntaxHighlighter
m_tooltipForLine.erase(tooltip.first);
}
}
- });
}
QString SyntaxHighlighter::getTooltipForLine(int index) const {

MODIFY
src/editor/syntaxhighlighter.h
src/editor/syntaxhighlighter.h
#pragma once
-#include <QRegularExpression>
#include <QSyntaxHighlighter>
namespace Ripes {
@@ -15,8 +14,6 @@ public:
virtual void highlightBlock(const QString& text) = 0;
virtual void reset();
- virtual QString checkSyntax(const QString& line) = 0;
-
virtual bool acceptsSyntax() const = 0;
signals:
@@ -26,6 +23,8 @@ public slots:
virtual void clearAndRehighlight() = 0;
protected:
+ void handleBlockCountChanged();
+
void setTooltip(int line, QString tooltip);
void clearTooltip(int line);
/**

Add C Syntax highlighter

The C syntax highlighter is heavily based on the Qt built-in
syntax highlighting example