diff options
-rw-r--r-- | Meta/Lagom/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/SyntaxHighlighter.cpp | 115 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/SyntaxHighlighter.h | 28 | ||||
-rw-r--r-- | Userland/Libraries/LibSyntax/Highlighter.h | 1 |
5 files changed, 147 insertions, 1 deletions
diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index b350ac3c46..b4b73b6532 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -76,6 +76,7 @@ file(GLOB SHELL_SOURCES CONFIGURE_DEPENDS "../../Userland/Shell/*.cpp") file(GLOB SHELL_TESTS CONFIGURE_DEPENDS "../../Userland/Shell/Tests/*.sh") list(FILTER SHELL_SOURCES EXCLUDE REGEX ".*main.cpp$") file(GLOB LIBSQL_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibSQL/*.cpp") +list(REMOVE_ITEM LIBSQL_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/../../Userland/Libraries/LibSQL/SyntaxHighlighter.cpp") file(GLOB LIBSQL_TEST_SOURCES CONFIGURE_DEPENDS "../../Tests/LibSQL/*.cpp") file(GLOB LIBTEST_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibTest/*.cpp") diff --git a/Userland/Libraries/LibSQL/CMakeLists.txt b/Userland/Libraries/LibSQL/CMakeLists.txt index c6b2ffb545..faec52cb2a 100644 --- a/Userland/Libraries/LibSQL/CMakeLists.txt +++ b/Userland/Libraries/LibSQL/CMakeLists.txt @@ -1,8 +1,9 @@ set(SOURCES Lexer.cpp Parser.cpp + SyntaxHighlighter.cpp Token.cpp ) serenity_lib(LibSQL sql) -target_link_libraries(LibSQL LibCore) +target_link_libraries(LibSQL LibCore LibSyntax) diff --git a/Userland/Libraries/LibSQL/SyntaxHighlighter.cpp b/Userland/Libraries/LibSQL/SyntaxHighlighter.cpp new file mode 100644 index 0000000000..21d88beccb --- /dev/null +++ b/Userland/Libraries/LibSQL/SyntaxHighlighter.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, Dylan Katz <dykatz@uw.edu> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/Debug.h> +#include <LibGUI/TextEditor.h> +#include <LibGfx/Font.h> +#include <LibGfx/Palette.h> +#include <LibSQL/Lexer.h> +#include <LibSQL/SyntaxHighlighter.h> + +namespace SQL { + +static Syntax::TextStyle style_for_token_type(const Gfx::Palette& palette, TokenType type) +{ + switch (Token::category(type)) { + case TokenCategory::Keyword: + return { palette.syntax_keyword(), true }; + case TokenCategory::Identifier: + return { palette.syntax_identifier(), false }; + case TokenCategory::Number: + return { palette.syntax_number(), false }; + case TokenCategory::Blob: + case TokenCategory::String: + return { palette.syntax_string(), false }; + case TokenCategory::Operator: + return { palette.syntax_operator(), false }; + case TokenCategory::Punctuation: + return { palette.syntax_punctuation(), false }; + case TokenCategory::Invalid: + default: + return { palette.base_text(), false }; + } +} + +bool SyntaxHighlighter::is_identifier(void* token) const +{ + auto sql_token = static_cast<SQL::TokenType>(reinterpret_cast<size_t>(token)); + return sql_token == SQL::TokenType::Identifier; +} + +void SyntaxHighlighter::rehighlight(const Palette& palette) +{ + auto text = m_client->get_text(); + + SQL::Lexer lexer(text); + + Vector<GUI::TextDocumentSpan> spans; + + auto append_token = [&](StringView str, const SQL::Token& token) { + if (str.is_empty()) + return; + + GUI::TextPosition position { token.line_number() - 1, token.line_column() - 1 }; + for (size_t i = 0; i < str.length() - 1; ++i) { + if (str[i] == '\n') { + position.set_line(position.line() + 1); + position.set_column(0); + } else + position.set_column(position.column() + 1); + } + + GUI::TextDocumentSpan span; + span.range.set_start({ token.line_number() - 1, token.line_column() - 1 }); + span.range.set_end({ position.line(), position.column() }); + auto style = style_for_token_type(palette, token.type()); + span.attributes.color = style.color; + span.attributes.bold = style.bold; + span.data = reinterpret_cast<void*>(static_cast<size_t>(token.type())); + spans.append(span); + + dbgln_if(SYNTAX_HIGHLIGHTING_DEBUG, "{} @ '{}' {}:{} - {}:{}", + token.name(), + token.value(), + span.range.start().line(), span.range.start().column(), + span.range.end().line(), span.range.end().column()); + }; + + bool was_eof = false; + for (auto token = lexer.next(); !was_eof; token = lexer.next()) { + append_token(token.value(), token); + + if (token.type() == SQL::TokenType::Eof) + was_eof = true; + } + + m_client->do_set_spans(move(spans)); + + m_has_brace_buddies = false; + highlight_matching_token_pair(); + + m_client->do_update(); +} + +Vector<SyntaxHighlighter::MatchingTokenPair> SyntaxHighlighter::matching_token_pairs() const +{ + static Vector<SyntaxHighlighter::MatchingTokenPair> pairs; + if (pairs.is_empty()) { + pairs.append({ reinterpret_cast<void*>(TokenType::ParenOpen), reinterpret_cast<void*>(TokenType::ParenClose) }); + } + return pairs; +} + +bool SyntaxHighlighter::token_types_equal(void* token1, void* token2) const +{ + return static_cast<TokenType>(reinterpret_cast<size_t>(token1)) == static_cast<TokenType>(reinterpret_cast<size_t>(token2)); +} + +SyntaxHighlighter::~SyntaxHighlighter() +{ +} + +} diff --git a/Userland/Libraries/LibSQL/SyntaxHighlighter.h b/Userland/Libraries/LibSQL/SyntaxHighlighter.h new file mode 100644 index 0000000000..87fabe504c --- /dev/null +++ b/Userland/Libraries/LibSQL/SyntaxHighlighter.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021, Dylan Katz <dykatz@uw.edu> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibSyntax/Highlighter.h> + +namespace SQL { + +class SyntaxHighlighter final : public Syntax::Highlighter { +public: + SyntaxHighlighter() { } + virtual ~SyntaxHighlighter() override; + + virtual bool is_identifier(void*) const override; + + virtual Syntax::Language language() const override { return Syntax::Language::SQL; } + virtual void rehighlight(const Palette&) override; + +protected: + virtual Vector<MatchingTokenPair> matching_token_pairs() const override; + virtual bool token_types_equal(void*, void*) const override; +}; + +} diff --git a/Userland/Libraries/LibSyntax/Highlighter.h b/Userland/Libraries/LibSyntax/Highlighter.h index 56cd5a7b3b..dc2fe000e6 100644 --- a/Userland/Libraries/LibSyntax/Highlighter.h +++ b/Userland/Libraries/LibSyntax/Highlighter.h @@ -21,6 +21,7 @@ enum class Language { INI, GML, Shell, + SQL, }; struct TextStyle { |