diff --git a/CMakeLists.txt b/CMakeLists.txt index 49c46d0..b7d7024 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,8 +54,10 @@ add_executable(${TARGET_NAME} src/main.cpp src/MainWindow.cpp src/CodeEditor.cpp + src/Syntax.cpp include/MainWindow.h include/CodeEditor.h + include/Syntax.h ) qt_add_resources(APP_RESOURCES resources.qrc) diff --git a/include/MainWindow.h b/include/MainWindow.h index a4a7099..4960d60 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -2,6 +2,7 @@ #define MAINWINDOW_H #include "CodeEditor.h" +#include "Syntax.h" #include #include #include @@ -34,6 +35,7 @@ private slots: void (MainWindow::*slot)()); CodeEditor *editor; QString currentFileName; + Syntax *syntax; }; #endif // MAINWINDOW_H diff --git a/include/Syntax.h b/include/Syntax.h new file mode 100644 index 0000000..4b40f5a --- /dev/null +++ b/include/Syntax.h @@ -0,0 +1,37 @@ +#ifndef SYNTAX_H +#define SYNTAX_H + +#include +#include +#include +#include + +class Syntax : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + Syntax(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct SyntaxRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + QList syntaxRules; + + QTextCharFormat keywordFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat quotationMark; + QTextCharFormat functionFormat; + QTextCharFormat parenthesisFormat; + QTextCharFormat charFormat; + + void addPattern(const QString &pattern, const QTextCharFormat &format); +}; + +#endif // SYNTAX_H \ No newline at end of file diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index ae44543..c454126 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1,4 +1,5 @@ #include "MainWindow.h" +#include "Syntax.h" #include #include @@ -15,8 +16,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) resize(800, 600); editor = new CodeEditor(this); - setCentralWidget(editor); + syntax = new Syntax(editor->document()); + setCentralWidget(editor); createMenuBar(); } diff --git a/src/Syntax.cpp b/src/Syntax.cpp new file mode 100644 index 0000000..553c927 --- /dev/null +++ b/src/Syntax.cpp @@ -0,0 +1,66 @@ +#include "Syntax.h" + +Syntax::Syntax(QTextDocument *parent) : QSyntaxHighlighter(parent) +{ + keywordFormat.setForeground(Qt::blue); + keywordFormat.setFontWeight(QFont::Bold); + QStringList keywordPatterns; + keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b" + << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b" + << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b" + << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b" + << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b" + << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b" + << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b" + << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b" + << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b" + << "\\bvoid\\b" << "\\bvolatile\\b" << "\\bforeach\\b"; + foreach (const QString &pattern, keywordPatterns) + { + addPattern(pattern, keywordFormat); + } + + // Single line comment format expression + singleLineCommentFormat.setForeground(Qt::darkGray); + addPattern("//[^\n]*", singleLineCommentFormat); + + // Double quotation mark for string + quotationMark.setForeground(Qt::darkGreen); + addPattern("\".*\"", quotationMark); + + // Function format expression + functionFormat.setFontItalic(true); + functionFormat.setForeground(Qt::darkYellow); + addPattern("\\b[a-zA-Z_][a-zA-Z0-9_]*(?=\\s*\\()", functionFormat); + + // Color pattern for parenthesis + QColor parenthesisColor("#6495ED"); + parenthesisFormat.setForeground(parenthesisColor); + addPattern("[()]", parenthesisFormat); + + // Regex for single character format 'a', '\n', etc + charFormat.setForeground(Qt::darkCyan); + addPattern("'(\\\\.|[^'])'", charFormat); +} + +// Add syntax highlighting patterns +void Syntax::addPattern(const QString &pattern, const QTextCharFormat &format) +{ + SyntaxRule rule; + rule.pattern = QRegularExpression(pattern); + rule.format = format; + syntaxRules.append(rule); +} + +void Syntax::highlightBlock(const QString &text) +{ + foreach (const SyntaxRule &rule, syntaxRules) + { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) + { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } +}