Commit 603a150a authored by heretik's avatar heretik
Browse files

add coloration for simplistic interpretation of c++

parent 162a4c13
#include "block_data.hpp"
#include "syntax_highlighter.hpp"
#include <QFont>
#include <QTextDocument>
#include <memory>
#include <sstream>
namespace {
const auto keywords = {
"alignas", "alignof", "and", "and_eq", "asm", "atomic_cancel", "atomic_commit", "atomic_noexcept",
"auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char8_t", "char16_t",
"char32_t", "class", "compl", "concept", "const", "consteval", "constexpr", "const_cast", "continue",
"co_await", "co_return", "co_yield", "decltype", "default", "delete", "do", "double", "dynamic_cast",
"else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if",
"inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", "nullptr",
"operator", "or", "or_eq", "private", "protected", "public", "reflexpr", "register", "reinterpret_cast",
"requires", "return", "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
"switch", "synchronized", "template", "this", "thread_local", "throw", "true", "try", "typedef",
"typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while",
"xor", "xor_eq",
};
const std::vector<std::pair<const char *, QColor>> regex_and_colors = {
{ "^#.*", Qt::darkYellow }, // standard types
{ "\\bstd::[a-z0-9]+\\b", Qt::blue }, // standard types
{ "\\b[A-Z][a-z0-9_]+", Qt::blue }, // types
{ "(\".*\")|(\\b\\d+\\b)", Qt::darkGreen }, // string literals
{ "//[^\n]*", Qt::gray }, // comment
};
}
SyntaxHighlighter::SyntaxHighlighter( QTextDocument *parent )
: QSyntaxHighlighter( parent )
......@@ -10,12 +38,36 @@ SyntaxHighlighter::SyntaxHighlighter( QTextDocument *parent )
, format_multiline_comment_{}
, regex_comment_start_{ R"(/\*)" }
, regex_comment_end_{ R"(\*/)" }
, regex_and_formats_{}
{
// formats
format_error_.setUnderlineStyle( QTextCharFormat::WaveUnderline );
format_error_.setUnderlineColor( Qt::red );
format_multiline_comment_.setForeground( Qt::gray );
// constructs keyword regex
auto os = std::ostringstream{};
os << "\\b(";
auto first = true;
for( const auto &it : keywords ) {
if( not first ) {
os << '|';
}
os << it;
first = false;
}
os << ")\\b";
QTextCharFormat format_keyword;
format_keyword.setForeground( Qt::darkMagenta );
format_keyword.setFontWeight( QFont::Bold );
regex_and_formats_.emplace_back( QRegularExpression{ QString::fromStdString( os.str() ) }, format_keyword );
// other regexs
for( const auto &[ regex, color ] : regex_and_colors ) {
QTextCharFormat format;
format.setForeground( color );
regex_and_formats_.emplace_back( QRegularExpression{ regex }, format );
}
}
void SyntaxHighlighter::highlightBlock( const QString &text )
......@@ -30,6 +82,17 @@ void SyntaxHighlighter::highlightBlock( const QString &text )
format_to_merge = format_error_;
}
// regex
for( const auto &[ regex, format ] : regex_and_formats_ ) {
auto merged_format = format;
merged_format.merge( format_to_merge );
QRegularExpressionMatchIterator matchIterator = regex.globalMatch( text );
while( matchIterator.hasNext() ) {
QRegularExpressionMatch match = matchIterator.next();
setFormat( match.capturedStart(), match.capturedLength(), merged_format );
}
}
// compute comments zone
constexpr auto end_line_is_in_comment = 1;
constexpr auto end_line_is_not_in_comment = 0;
......@@ -40,6 +103,8 @@ void SyntaxHighlighter::highlightBlock( const QString &text )
start_index = text.indexOf( regex_comment_start_ );
}
auto format = format_multiline_comment_;
format.merge( format_to_merge );
while( start_index >= 0 ) {
auto match = QRegularExpressionMatch{ regex_comment_end_.match( text, start_index ) };
auto end_index = match.capturedStart();
......@@ -50,8 +115,6 @@ void SyntaxHighlighter::highlightBlock( const QString &text )
} else {
comment_length = end_index - start_index + match.capturedLength();
}
auto format = format_multiline_comment_;
format.merge( format_to_merge );
setFormat( start_index, comment_length, format );
start_index = text.indexOf( regex_comment_start_, start_index + comment_length );
}
......
......@@ -4,6 +4,7 @@
#include <QRegularExpression>
#include <QSyntaxHighlighter>
#include <vector>
class SyntaxHighlighter
: public QSyntaxHighlighter
......@@ -17,10 +18,11 @@ protected:
void highlightBlock( const QString &text ) override;
private:
QTextCharFormat format_error_;
QTextCharFormat format_multiline_comment_;
QRegularExpression regex_comment_start_;
QRegularExpression regex_comment_end_;
QTextCharFormat format_error_;
QTextCharFormat format_multiline_comment_;
QRegularExpression regex_comment_start_;
QRegularExpression regex_comment_end_;
std::vector<std::pair<QRegularExpression, QTextCharFormat>> regex_and_formats_;
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment