Serenity Operating System
1/*
2 * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "SyntaxHighlighter.h"
8#include <LibCMake/CMakeCache/Lexer.h>
9
10namespace CMake::Cache {
11
12static Syntax::TextStyle style_for_token_type(Gfx::Palette const& palette, Token::Type type)
13{
14 switch (type) {
15 case Token::Type::Comment:
16 case Token::Type::HelpText:
17 return { palette.syntax_comment() };
18 case Token::Type::Key:
19 return { palette.syntax_identifier() };
20 case Token::Type::Type:
21 return { palette.syntax_type() };
22 case Token::Type::Colon:
23 case Token::Type::Equals:
24 return { palette.syntax_punctuation() };
25 case Token::Type::Value:
26 return { palette.syntax_string() };
27 case Token::Type::Garbage:
28 return { palette.red() };
29 default:
30 return { palette.base_text() };
31 }
32}
33
34bool SyntaxHighlighter::is_identifier(u64 token_type) const
35{
36 auto cmake_token = static_cast<Token::Type>(token_type);
37 return cmake_token == Token::Type::Key;
38}
39
40void SyntaxHighlighter::rehighlight(Gfx::Palette const& palette)
41{
42 auto text = m_client->get_text();
43 auto tokens = Lexer::lex(text).release_value_but_fixme_should_propagate_errors();
44
45 Vector<GUI::TextDocumentSpan> spans;
46 auto highlight_span = [&](Token::Type type, Position const& start, Position const& end) {
47 GUI::TextDocumentSpan span;
48 span.range.set_start({ start.line, start.column });
49 span.range.set_end({ end.line, end.column });
50 if (!span.range.is_valid())
51 return;
52
53 auto style = style_for_token_type(palette, type);
54 span.attributes.color = style.color;
55 span.attributes.bold = style.bold;
56 if (type == Token::Type::Garbage) {
57 span.attributes.underline = true;
58 span.attributes.underline_color = palette.red();
59 span.attributes.underline_style = Gfx::TextAttributes::UnderlineStyle::Wavy;
60 }
61 span.is_skippable = false;
62 span.data = static_cast<u64>(type);
63 spans.append(move(span));
64 };
65
66 for (auto const& token : tokens) {
67 highlight_span(token.type, token.start, token.end);
68 }
69
70 m_client->do_set_spans(move(spans));
71
72 m_has_brace_buddies = false;
73 highlight_matching_token_pair();
74
75 m_client->do_update();
76}
77
78Vector<SyntaxHighlighter::MatchingTokenPair> SyntaxHighlighter::matching_token_pairs_impl() const
79{
80 static Vector<MatchingTokenPair> empty;
81 return empty;
82}
83
84bool SyntaxHighlighter::token_types_equal(u64 token1, u64 token2) const
85{
86 return static_cast<Token::Type>(token1) == static_cast<Token::Type>(token2);
87}
88
89}