diff options
-rw-r--r-- | Base/res/themes/Dark.ini | 11 | ||||
-rw-r--r-- | Base/res/themes/Default.ini | 11 | ||||
-rw-r--r-- | Base/res/themes/Hotdog Stand.ini | 11 | ||||
-rw-r--r-- | Base/res/themes/Nord.ini | 11 | ||||
-rw-r--r-- | Base/res/themes/Xmas.ini | 11 | ||||
-rw-r--r-- | Libraries/LibGUI/CppSyntaxHighlighter.cpp | 25 | ||||
-rw-r--r-- | Libraries/LibGUI/CppSyntaxHighlighter.h | 2 | ||||
-rw-r--r-- | Libraries/LibGUI/JSSyntaxHighlighter.cpp | 173 | ||||
-rw-r--r-- | Libraries/LibGUI/JSSyntaxHighlighter.h | 2 | ||||
-rw-r--r-- | Libraries/LibGUI/SyntaxHighlighter.h | 3 | ||||
-rw-r--r-- | Libraries/LibGUI/TextEditor.cpp | 6 | ||||
-rw-r--r-- | Libraries/LibGfx/Palette.h | 12 | ||||
-rw-r--r-- | Libraries/LibGfx/SystemTheme.cpp | 11 | ||||
-rw-r--r-- | Libraries/LibGfx/SystemTheme.h | 11 |
14 files changed, 217 insertions, 83 deletions
diff --git a/Base/res/themes/Dark.ini b/Base/res/themes/Dark.ini index 2e4224b4d6..4c97577600 100644 --- a/Base/res/themes/Dark.ini +++ b/Base/res/themes/Dark.ini @@ -42,3 +42,14 @@ RulerActiveText=white RulerInactiveText=#d5d0c7 TextCursor=#9c9cd5 FocusOutline=#606060 +SyntaxComment=olivedrab +SyntaxNumber=greenyellow +SyntaxString=orange +SyntaxType=violet +SyntaxPunctuation=white +SyntaxOperator=white +SyntaxKeyword=deepskyblue +SyntaxControlKeyword=orchid +SyntaxIdentifier=lightskyblue +SyntaxPreprocessorStatement=darkgray +SyntaxPreprocessorValue=orange diff --git a/Base/res/themes/Default.ini b/Base/res/themes/Default.ini index 48b777f5ce..1c4602dd9f 100644 --- a/Base/res/themes/Default.ini +++ b/Base/res/themes/Default.ini @@ -42,3 +42,14 @@ RulerActiveText=#404040 RulerInactiveText=#808080 TextCursor=red FocusOutline=#909090 +SyntaxComment=#008000 +SyntaxNumber=#800000 +SyntaxString=#800000 +SyntaxType=#800080 +SyntaxPunctuation=black +SyntaxOperator=black +SyntaxKeyword=black +SyntaxControlKeyword=black +SyntaxIdentifier=#092e64 +SyntaxPreprocessorStatement=#008080 +SyntaxPreprocessorValue=#800000 diff --git a/Base/res/themes/Hotdog Stand.ini b/Base/res/themes/Hotdog Stand.ini index 96534338ae..bea62a02a8 100644 --- a/Base/res/themes/Hotdog Stand.ini +++ b/Base/res/themes/Hotdog Stand.ini @@ -42,3 +42,14 @@ RulerActiveText=yellow RulerInactiveText=white TextCursor=black FocusOutline=#909090 +SyntaxComment=#008000 +SyntaxNumber=#800000 +SyntaxString=#800000 +SyntaxType=#800080 +SyntaxPunctuation=black +SyntaxOperator=black +SyntaxKeyword=black +SyntaxControlKeyword=black +SyntaxIdentifier=#092e64 +SyntaxPreprocessorStatement=#008080 +SyntaxPreprocessorValue=#800000 diff --git a/Base/res/themes/Nord.ini b/Base/res/themes/Nord.ini index 04a3eaab9e..8df6737600 100644 --- a/Base/res/themes/Nord.ini +++ b/Base/res/themes/Nord.ini @@ -42,3 +42,14 @@ RulerActiveText=#95adc5 RulerInactiveText=#7e9dbc TextCursor=#7e9dbc FocusOutline=#7e9dbc +SyntaxComment=#008000 +SyntaxNumber=#800000 +SyntaxString=#800000 +SyntaxType=#800080 +SyntaxPunctuation=black +SyntaxOperator=black +SyntaxKeyword=black +SyntaxControlKeyword=black +SyntaxIdentifier=#092e64 +SyntaxPreprocessorStatement=#008080 +SyntaxPreprocessorValue=#800000 diff --git a/Base/res/themes/Xmas.ini b/Base/res/themes/Xmas.ini index 195b2c8184..ee609ef936 100644 --- a/Base/res/themes/Xmas.ini +++ b/Base/res/themes/Xmas.ini @@ -42,3 +42,14 @@ RulerActiveText=#404040 RulerInactiveText=#808080 TextCursor=#ee3532 FocusOutline=#909090 +SyntaxComment=#008000 +SyntaxNumber=#800000 +SyntaxString=#800000 +SyntaxType=#800080 +SyntaxPunctuation=black +SyntaxOperator=black +SyntaxKeyword=black +SyntaxControlKeyword=black +SyntaxIdentifier=#092e64 +SyntaxPreprocessorStatement=#008080 +SyntaxPreprocessorValue=#800000 diff --git a/Libraries/LibGUI/CppSyntaxHighlighter.cpp b/Libraries/LibGUI/CppSyntaxHighlighter.cpp index f1c2e296dc..329e792ad8 100644 --- a/Libraries/LibGUI/CppSyntaxHighlighter.cpp +++ b/Libraries/LibGUI/CppSyntaxHighlighter.cpp @@ -28,33 +28,36 @@ #include <LibGUI/CppSyntaxHighlighter.h> #include <LibGUI/TextEditor.h> #include <LibGfx/Font.h> +#include <LibGfx/Palette.h> namespace GUI { -static TextStyle style_for_token_type(CppToken::Type type) +static TextStyle style_for_token_type(Gfx::Palette palette, CppToken::Type type) { switch (type) { case CppToken::Type::Keyword: - return { Color::Black, &Gfx::Font::default_bold_fixed_width_font() }; + return { palette.syntax_keyword(), &Gfx::Font::default_bold_fixed_width_font() }; case CppToken::Type::KnownType: - return { Color::from_rgb(0x800080), &Gfx::Font::default_bold_fixed_width_font() }; + return { palette.syntax_type(), &Gfx::Font::default_bold_fixed_width_font() }; case CppToken::Type::Identifier: - return { Color::from_rgb(0x092e64) }; + return { palette.syntax_identifier() }; case CppToken::Type::DoubleQuotedString: case CppToken::Type::SingleQuotedString: + return { palette.syntax_string() }; case CppToken::Type::Integer: case CppToken::Type::Float: + return { palette.syntax_number() }; case CppToken::Type::IncludePath: - return { Color::from_rgb(0x800000) }; + return { palette.syntax_preprocessor_value() }; case CppToken::Type::EscapeSequence: - return { Color::from_rgb(0x800080), &Gfx::Font::default_bold_fixed_width_font() }; + return { palette.syntax_keyword(), &Gfx::Font::default_bold_fixed_width_font() }; case CppToken::Type::PreprocessorStatement: case CppToken::Type::IncludeStatement: - return { Color::from_rgb(0x008080) }; + return { palette.syntax_preprocessor_statement() }; case CppToken::Type::Comment: - return { Color::from_rgb(0x008000) }; + return { palette.syntax_comment() }; default: - return { Color::Black }; + return { palette.base_text() }; } } @@ -70,7 +73,7 @@ bool CppSyntaxHighlighter::is_navigatable(void* token) const return cpp_token == GUI::CppToken::Type::IncludePath; } -void CppSyntaxHighlighter::rehighlight() +void CppSyntaxHighlighter::rehighlight(Gfx::Palette palette) { ASSERT(m_editor); auto text = m_editor->text(); @@ -85,7 +88,7 @@ void CppSyntaxHighlighter::rehighlight() GUI::TextDocumentSpan span; span.range.set_start({ token.m_start.line, token.m_start.column }); span.range.set_end({ token.m_end.line, token.m_end.column }); - auto style = style_for_token_type(token.m_type); + auto style = style_for_token_type(palette, token.m_type); span.color = style.color; span.font = style.font; span.is_skippable = token.m_type == CppToken::Type::Whitespace; diff --git a/Libraries/LibGUI/CppSyntaxHighlighter.h b/Libraries/LibGUI/CppSyntaxHighlighter.h index 4f6f48354b..a96b5febe9 100644 --- a/Libraries/LibGUI/CppSyntaxHighlighter.h +++ b/Libraries/LibGUI/CppSyntaxHighlighter.h @@ -39,7 +39,7 @@ public: virtual bool is_navigatable(void*) const override; virtual SyntaxLanguage language() const override { return SyntaxLanguage::Cpp; } - virtual void rehighlight() override; + virtual void rehighlight(Gfx::Palette) override; protected: virtual Vector<MatchingTokenPair> matching_token_pairs() const override; diff --git a/Libraries/LibGUI/JSSyntaxHighlighter.cpp b/Libraries/LibGUI/JSSyntaxHighlighter.cpp index 19573a50bf..d3b74f22fb 100644 --- a/Libraries/LibGUI/JSSyntaxHighlighter.cpp +++ b/Libraries/LibGUI/JSSyntaxHighlighter.cpp @@ -27,53 +27,108 @@ #include <LibGUI/JSSyntaxHighlighter.h> #include <LibGUI/TextEditor.h> #include <LibGfx/Font.h> +#include <LibGfx/Palette.h> #include <LibJS/Lexer.h> #include <LibJS/Token.h> namespace GUI { -static TextStyle style_for_token_type(JS::TokenType type) +static TextStyle style_for_token_type(Gfx::Palette palette, JS::TokenType type) { switch (type) { + case JS::TokenType::Invalid: + case JS::TokenType::Eof: + return { palette.syntax_comment() }; + case JS::TokenType::NumericLiteral: + return { palette.syntax_number() }; + case JS::TokenType::StringLiteral: + case JS::TokenType::RegexLiteral: + case JS::TokenType::UnterminatedStringLiteral: + return { palette.syntax_string() }; + case JS::TokenType::BracketClose: + case JS::TokenType::BracketOpen: + case JS::TokenType::Caret: + case JS::TokenType::Comma: + case JS::TokenType::CurlyClose: + case JS::TokenType::CurlyOpen: + case JS::TokenType::ParenClose: + case JS::TokenType::ParenOpen: + case JS::TokenType::Semicolon: + return { palette.syntax_punctuation() }; + case JS::TokenType::Ampersand: + case JS::TokenType::AmpersandEquals: + case JS::TokenType::Asterisk: + case JS::TokenType::AsteriskAsteriskEquals: + case JS::TokenType::AsteriskEquals: + case JS::TokenType::DoubleAmpersand: + case JS::TokenType::DoubleAsterisk: + case JS::TokenType::DoublePipe: + case JS::TokenType::DoubleQuestionMark: + case JS::TokenType::Equals: + case JS::TokenType::EqualsEquals: + case JS::TokenType::EqualsEqualsEquals: + case JS::TokenType::ExclamationMark: + case JS::TokenType::ExclamationMarkEquals: + case JS::TokenType::ExclamationMarkEqualsEquals: + case JS::TokenType::GreaterThan: + case JS::TokenType::GreaterThanEquals: + case JS::TokenType::LessThan: + case JS::TokenType::LessThanEquals: + case JS::TokenType::Minus: + case JS::TokenType::MinusEquals: + case JS::TokenType::MinusMinus: + case JS::TokenType::Percent: + case JS::TokenType::PercentEquals: + case JS::TokenType::Period: + case JS::TokenType::Pipe: + case JS::TokenType::PipeEquals: + case JS::TokenType::Plus: + case JS::TokenType::PlusEquals: + case JS::TokenType::PlusPlus: + case JS::TokenType::QuestionMark: + case JS::TokenType::QuestionMarkPeriod: + case JS::TokenType::ShiftLeft: + case JS::TokenType::ShiftLeftEquals: + case JS::TokenType::ShiftRight: + case JS::TokenType::ShiftRightEquals: + case JS::TokenType::Slash: + case JS::TokenType::SlashEquals: + case JS::TokenType::Tilde: + case JS::TokenType::UnsignedShiftRight: + case JS::TokenType::UnsignedShiftRightEquals: + return { palette.syntax_operator() }; case JS::TokenType::BoolLiteral: - case JS::TokenType::NullLiteral: - return { Color::Black, &Gfx::Font::default_bold_fixed_width_font() }; - case JS::TokenType::Await: - case JS::TokenType::Catch: case JS::TokenType::Class: case JS::TokenType::Const: case JS::TokenType::Delete: - case JS::TokenType::Do: - case JS::TokenType::Else: - case JS::TokenType::Finally: - case JS::TokenType::For: case JS::TokenType::Function: - case JS::TokenType::If: case JS::TokenType::In: case JS::TokenType::Instanceof: case JS::TokenType::Interface: case JS::TokenType::Let: case JS::TokenType::New: - case JS::TokenType::QuestionMark: - case JS::TokenType::Return: - case JS::TokenType::Try: + case JS::TokenType::NullLiteral: case JS::TokenType::Typeof: case JS::TokenType::Var: case JS::TokenType::Void: + return { palette.syntax_keyword(), &Gfx::Font::default_bold_fixed_width_font() }; + case JS::TokenType::Await: + case JS::TokenType::Catch: + case JS::TokenType::Do: + case JS::TokenType::Else: + case JS::TokenType::Finally: + case JS::TokenType::For: + case JS::TokenType::If: + case JS::TokenType::Return: + case JS::TokenType::Try: case JS::TokenType::While: case JS::TokenType::Yield: - return { Color::Black, &Gfx::Font::default_bold_fixed_width_font() }; + return { palette.syntax_control_keyword(), &Gfx::Font::default_bold_fixed_width_font() }; case JS::TokenType::Identifier: - return { Color::from_rgb(0x092e64) }; - case JS::TokenType::NumericLiteral: - case JS::TokenType::StringLiteral: - case JS::TokenType::RegexLiteral: - return { Color::from_rgb(0x800000) }; - case JS::TokenType::Invalid: - case JS::TokenType::Eof: - return { Color::from_rgb(0x008000) }; + return { palette.syntax_identifier() }; + default: - return { Color::Black }; + return { palette.base_text() }; } } @@ -89,7 +144,7 @@ bool JSSyntaxHighlighter::is_navigatable(void* token) const return false; } -void JSSyntaxHighlighter::rehighlight() +void JSSyntaxHighlighter::rehighlight(Gfx::Palette palette) { ASSERT(m_editor); auto text = m_editor->text(); @@ -100,7 +155,7 @@ void JSSyntaxHighlighter::rehighlight() GUI::TextPosition position { 0, 0 }; GUI::TextPosition start { 0, 0 }; - auto advance_position = [&](char ch) { + auto advance_position = [&position](char ch) { if (ch == '\n') { position.set_line(position.line() + 1); position.set_column(0); @@ -108,51 +163,37 @@ void JSSyntaxHighlighter::rehighlight() position.set_column(position.column() + 1); }; - bool was_eof = false; - for (auto token = lexer.next(); !was_eof; token = lexer.next()) { - start = position; - if (!token.trivia().is_empty()) { - for (auto ch : token.trivia()) - advance_position(ch); - - GUI::TextDocumentSpan span; - - span.range.set_start(start); - if (position.column() > 0) - span.range.set_end({ position.line(), position.column() - 1 }); - else - span.range.set_end({ position.line() - 1, 0 }); - auto style = style_for_token_type(JS::TokenType::Invalid); - span.color = style.color; - span.font = style.font; - span.is_skippable = true; - spans.append(span); -#ifdef DEBUG_SYNTAX_HIGHLIGHTING - dbg() << token.name() << " \"" << token.trivia() << "\" (trivia) @ " << span.range.start().line() << ":" << span.range.start().column() << " - " << span.range.end().line() << ":" << span.range.end().column(); -#endif - } + auto append_token = [&](StringView str, const JS::Token& token, bool is_trivia) { + if (str.is_empty()) + return; start = position; - if (!token.value().is_empty()) { - for (auto ch : token.value()) - advance_position(ch); - - GUI::TextDocumentSpan span; - span.range.set_start(start); - if (position.column() > 0) - span.range.set_end({ position.line(), position.column() - 1 }); - else - span.range.set_end({ position.line() - 1, 0 }); - auto style = style_for_token_type(token.type()); - span.color = style.color; - span.font = style.font; - span.is_skippable = false; - span.data = reinterpret_cast<void*>(token.type()); - spans.append(span); + for (size_t i = 0; i < str.length() - 1; ++i) + advance_position(str[i]); + + GUI::TextDocumentSpan span; + span.range.set_start(start); + span.range.set_end({ position.line(), position.column() }); + auto type = is_trivia ? JS::TokenType::Invalid : token.type(); + auto style = style_for_token_type(palette, type); + span.color = style.color; + span.font = style.font; + span.is_skippable = is_trivia; + span.data = reinterpret_cast<void*>(static_cast<size_t>(type)); + spans.append(span); + advance_position(str[str.length() - 1]); + #ifdef DEBUG_SYNTAX_HIGHLIGHTING - dbg() << token.name() << " @ \"" << token.value() << "\" " << span.range.start().line() << ":" << span.range.start().column() << " - " << span.range.end().line() << ":" << span.range.end().column(); + dbg() << token.name() << (is_trivia ? " (trivia) @ \"" : " @ \"") << token.value() << "\" " + << span.range.start().line() << ":" << span.range.start().column() << " - " + << span.range.end().line() << ":" << span.range.end().column(); #endif - } + }; + + bool was_eof = false; + for (auto token = lexer.next(); !was_eof; token = lexer.next()) { + append_token(token.trivia(), token, true); + append_token(token.value(), token, false); if (token.type() == JS::TokenType::Eof) was_eof = true; diff --git a/Libraries/LibGUI/JSSyntaxHighlighter.h b/Libraries/LibGUI/JSSyntaxHighlighter.h index 00ed21344b..468f447121 100644 --- a/Libraries/LibGUI/JSSyntaxHighlighter.h +++ b/Libraries/LibGUI/JSSyntaxHighlighter.h @@ -39,7 +39,7 @@ public: virtual bool is_navigatable(void*) const override; virtual SyntaxLanguage language() const override { return SyntaxLanguage::Javascript; } - virtual void rehighlight() override; + virtual void rehighlight(Gfx::Palette) override; protected: virtual Vector<MatchingTokenPair> matching_token_pairs() const override; diff --git a/Libraries/LibGUI/SyntaxHighlighter.h b/Libraries/LibGUI/SyntaxHighlighter.h index ddb6a18d13..eda27ffead 100644 --- a/Libraries/LibGUI/SyntaxHighlighter.h +++ b/Libraries/LibGUI/SyntaxHighlighter.h @@ -29,6 +29,7 @@ #include <AK/Noncopyable.h> #include <AK/WeakPtr.h> #include <LibGUI/TextDocument.h> +#include <LibGfx/Palette.h> namespace GUI { @@ -51,7 +52,7 @@ public: virtual ~SyntaxHighlighter(); virtual SyntaxLanguage language() const = 0; - virtual void rehighlight() = 0; + virtual void rehighlight(Gfx::Palette) = 0; virtual void highlight_matching_token_pair(); virtual bool is_identifier(void*) const { return false; }; diff --git a/Libraries/LibGUI/TextEditor.cpp b/Libraries/LibGUI/TextEditor.cpp index babc705810..a8bd6118bb 100644 --- a/Libraries/LibGUI/TextEditor.cpp +++ b/Libraries/LibGUI/TextEditor.cpp @@ -1211,7 +1211,7 @@ void TextEditor::did_change() if (on_change) on_change(); if (m_highlighter) - m_highlighter->rehighlight(); + m_highlighter->rehighlight(palette()); m_has_pending_change_notification = false; }); } @@ -1491,7 +1491,7 @@ void TextEditor::flush_pending_change_notification_if_needed() if (on_change) on_change(); if (m_highlighter) - m_highlighter->rehighlight(); + m_highlighter->rehighlight(palette()); m_has_pending_change_notification = false; } @@ -1507,7 +1507,7 @@ void TextEditor::set_syntax_highlighter(OwnPtr<SyntaxHighlighter> highlighter) m_highlighter = move(highlighter); if (m_highlighter) { m_highlighter->attach(*this); - m_highlighter->rehighlight(); + m_highlighter->rehighlight(palette()); } else document().set_spans({}); } diff --git a/Libraries/LibGfx/Palette.h b/Libraries/LibGfx/Palette.h index b975f427ae..2d58890e74 100644 --- a/Libraries/LibGfx/Palette.h +++ b/Libraries/LibGfx/Palette.h @@ -105,6 +105,18 @@ public: Color active_link() const { return color(ColorRole::ActiveLink); } Color visited_link() const { return color(ColorRole::VisitedLink); } + Color syntax_comment() const { return color(ColorRole::SyntaxComment); } + Color syntax_number() const { return color(ColorRole::SyntaxNumber); } + Color syntax_string() const { return color(ColorRole::SyntaxString); } + Color syntax_identifier() const { return color(ColorRole::SyntaxIdentifier); } + Color syntax_type() const { return color(ColorRole::SyntaxType); } + Color syntax_punctuation() const { return color(ColorRole::SyntaxPunctuation); } + Color syntax_operator() const { return color(ColorRole::SyntaxOperator); } + Color syntax_keyword() const { return color(ColorRole::SyntaxKeyword); } + Color syntax_control_keyword() const { return color(ColorRole::SyntaxControlKeyword); } + Color syntax_preprocessor_statement() const { return color(ColorRole::SyntaxPreprocessorStatement); } + Color syntax_preprocessor_value() const { return color(ColorRole::SyntaxPreprocessorValue); } + Color color(ColorRole role) const { return m_impl->color(role); } void set_color(ColorRole, Color); diff --git a/Libraries/LibGfx/SystemTheme.cpp b/Libraries/LibGfx/SystemTheme.cpp index c41acb27b0..05aab14692 100644 --- a/Libraries/LibGfx/SystemTheme.cpp +++ b/Libraries/LibGfx/SystemTheme.cpp @@ -114,6 +114,17 @@ RefPtr<SharedBuffer> load_system_theme(const String& path) DO_COLOR(RulerInactiveText); DO_COLOR(TextCursor); DO_COLOR(FocusOutline); + DO_COLOR(SyntaxComment); + DO_COLOR(SyntaxNumber); + DO_COLOR(SyntaxString); + DO_COLOR(SyntaxType); + DO_COLOR(SyntaxPunctuation); + DO_COLOR(SyntaxOperator); + DO_COLOR(SyntaxKeyword); + DO_COLOR(SyntaxControlKeyword); + DO_COLOR(SyntaxIdentifier); + DO_COLOR(SyntaxPreprocessorStatement); + DO_COLOR(SyntaxPreprocessorValue); buffer->seal(); buffer->share_globally(); diff --git a/Libraries/LibGfx/SystemTheme.h b/Libraries/LibGfx/SystemTheme.h index e4b945728c..28e5dfb255 100644 --- a/Libraries/LibGfx/SystemTheme.h +++ b/Libraries/LibGfx/SystemTheme.h @@ -77,6 +77,17 @@ enum class ColorRole { RulerInactiveText, TextCursor, FocusOutline, + SyntaxComment, + SyntaxNumber, + SyntaxString, + SyntaxType, + SyntaxPunctuation, + SyntaxOperator, + SyntaxKeyword, + SyntaxControlKeyword, + SyntaxIdentifier, + SyntaxPreprocessorStatement, + SyntaxPreprocessorValue, __Count, |