1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:37:36 +00:00

LibSyntax+LibGUI+LibJS: Move JS syntax highlighter to LibJS

This is a little bit messy but the basic idea is:

Syntax::Highlighter now has a Syntax::HighlighterClient to talk to the
outside world. It mostly communicates in LibGUI primitives that are
available in headers, so inlineable.

GUI::TextEditor inherits from Syntax::HighlighterClient.

This let us to move GUI::JSSyntaxHighlighter to JS::SyntaxHighlighter
and remove LibGUI's dependency on LibJS.
This commit is contained in:
Andreas Kling 2021-02-07 16:56:02 +01:00
parent 22baa5e64f
commit ddbf20ecf6
23 changed files with 139 additions and 80 deletions

View file

@ -29,5 +29,6 @@
namespace Syntax {
class Highlighter;
class HighlighterClient;
}

View file

@ -25,6 +25,7 @@
*/
#include <LibGUI/TextEditor.h>
#include <LibGfx/Color.h>
#include <LibSyntax/Highlighter.h>
namespace Syntax {
@ -35,8 +36,7 @@ Highlighter::~Highlighter()
void Highlighter::highlight_matching_token_pair()
{
ASSERT(m_editor);
auto& document = m_editor->document();
auto& document = m_client->get_document();
enum class Direction {
Forward,
@ -93,7 +93,7 @@ void Highlighter::highlight_matching_token_pair()
buddy1.attributes.background_color = Color::DarkCyan;
buddy0.attributes.color = Color::White;
buddy1.attributes.color = Color::White;
m_editor->update();
m_client->do_update();
};
auto pairs = matching_token_pairs();
@ -103,7 +103,7 @@ void Highlighter::highlight_matching_token_pair()
auto token_type = span.data;
for (auto& pair : pairs) {
if (token_types_equal(token_type, pair.open) && span.range.start() == m_editor->cursor()) {
if (token_types_equal(token_type, pair.open) && span.range.start() == m_client->get_cursor()) {
auto buddy = find_span_of_type(i, pair.close, pair.open, Direction::Forward);
if (buddy.has_value())
make_buddies(i, buddy.value());
@ -115,7 +115,7 @@ void Highlighter::highlight_matching_token_pair()
right_of_end.set_column(right_of_end.column() + 1);
for (auto& pair : pairs) {
if (token_types_equal(token_type, pair.close) && right_of_end == m_editor->cursor()) {
if (token_types_equal(token_type, pair.close) && right_of_end == m_client->get_cursor()) {
auto buddy = find_span_of_type(i, pair.open, pair.close, Direction::Backward);
if (buddy.has_value())
make_buddies(i, buddy.value());
@ -125,29 +125,27 @@ void Highlighter::highlight_matching_token_pair()
}
}
void Highlighter::attach(GUI::TextEditor& editor)
void Highlighter::attach(HighlighterClient& client)
{
ASSERT(!m_editor);
m_editor = editor;
ASSERT(!m_client);
m_client = &client;
}
void Highlighter::detach()
{
ASSERT(m_editor);
m_editor = nullptr;
m_client = nullptr;
}
void Highlighter::cursor_did_change()
{
ASSERT(m_editor);
auto& document = m_editor->document();
auto& document = m_client->get_document();
if (m_has_brace_buddies) {
if (m_brace_buddies[0].index >= 0 && m_brace_buddies[0].index < static_cast<int>(document.spans().size()))
document.set_span_at_index(m_brace_buddies[0].index, m_brace_buddies[0].span_backup);
if (m_brace_buddies[1].index >= 0 && m_brace_buddies[1].index < static_cast<int>(document.spans().size()))
document.set_span_at_index(m_brace_buddies[1].index, m_brace_buddies[1].span_backup);
m_has_brace_buddies = false;
m_editor->update();
m_client->do_update();
}
highlight_matching_token_pair();
}

View file

@ -30,6 +30,7 @@
#include <AK/WeakPtr.h>
#include <LibGUI/TextDocument.h>
#include <LibGfx/Palette.h>
#include <LibSyntax/HighlighterClient.h>
namespace Syntax {
@ -61,14 +62,15 @@ public:
virtual bool is_identifier(void*) const { return false; };
virtual bool is_navigatable(void*) const { return false; };
void attach(GUI::TextEditor& editor);
void attach(HighlighterClient&);
void detach();
void cursor_did_change();
protected:
Highlighter() { }
WeakPtr<GUI::TextEditor> m_editor;
// FIXME: This should be WeakPtr somehow
HighlighterClient* m_client { nullptr };
struct MatchingTokenPair {
void* open;

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <LibGUI/Forward.h>
namespace Syntax {
class HighlighterClient {
public:
virtual ~HighlighterClient() = default;
virtual Vector<GUI::TextDocumentSpan>& spans() = 0;
virtual const Vector<GUI::TextDocumentSpan>& spans() const = 0;
virtual void set_span_at_index(size_t index, GUI::TextDocumentSpan span) = 0;
virtual String highlighter_did_request_text() const = 0;
virtual void highlighter_did_request_update() = 0;
virtual GUI::TextDocument& highlighter_did_request_document() = 0;
virtual GUI::TextPosition highlighter_did_request_cursor() const = 0;
virtual void highlighter_did_set_spans(Vector<GUI::TextDocumentSpan>) = 0;
void do_set_spans(Vector<GUI::TextDocumentSpan> spans) { highlighter_did_set_spans(move(spans)); }
void do_update() { highlighter_did_request_update(); }
String get_text() const { return highlighter_did_request_text(); }
GUI::TextDocument& get_document() { return highlighter_did_request_document(); }
GUI::TextPosition get_cursor() const { return highlighter_did_request_cursor(); }
};
}