HackStudio: Display identifiers as clickable

This extends the "navigate to include" feature to also display
identifiers as clickable when they're hovered over while left control
is pressed.
This commit is contained in:
Itamar 2021-02-20 09:48:54 +02:00 committed by Andreas Kling
parent adb6db9774
commit 50f887c9d5
Notes: sideshowbarker 2024-07-18 22:06:52 +09:00
2 changed files with 26 additions and 21 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -213,18 +213,19 @@ void Editor::mousemove_event(GUI::MouseEvent& event)
return;
bool hide_tooltip = true;
bool is_over_link = false;
bool is_over_clickable = false;
auto ruler_line_rect = ruler_content_rect(text_position.line());
auto hovering_lines_ruler = (event.position().x() < ruler_line_rect.width());
if (hovering_lines_ruler && !is_in_drag_select())
set_override_cursor(Gfx::StandardCursor::Arrow);
else if (m_hovering_editor)
set_override_cursor(m_hovering_link && event.ctrl() ? Gfx::StandardCursor::Hand : Gfx::StandardCursor::IBeam);
set_override_cursor(m_hovering_clickable && event.ctrl() ? Gfx::StandardCursor::Hand : Gfx::StandardCursor::IBeam);
for (auto& span : document().spans()) {
bool is_clickable = (highlighter->is_navigatable(span.data) || highlighter->is_identifier(span.data));
if (span.range.contains(m_previous_text_position) && !span.range.contains(text_position)) {
if (highlighter->is_navigatable(span.data) && span.attributes.underline) {
if (is_clickable && span.attributes.underline) {
span.attributes.underline = false;
wrapper().editor().update();
}
@ -239,14 +240,15 @@ void Editor::mousemove_event(GUI::MouseEvent& event)
dbgln("Hovering: {} \"{}\"", adjusted_range, hovered_span_text);
#endif
if (highlighter->is_navigatable(span.data)) {
is_over_link = true;
if (is_clickable) {
is_over_clickable = true;
bool was_underlined = span.attributes.underline;
span.attributes.underline = event.modifiers() & Mod_Ctrl;
if (span.attributes.underline != was_underlined) {
wrapper().editor().update();
}
}
if (highlighter->is_identifier(span.data)) {
show_documentation_tooltip_if_available(hovered_span_text, event.position().translated(screen_relative_rect().location()));
hide_tooltip = false;
@ -258,7 +260,7 @@ void Editor::mousemove_event(GUI::MouseEvent& event)
if (hide_tooltip)
m_documentation_tooltip_window->hide();
m_hovering_link = is_over_link && (event.modifiers() & Mod_Ctrl);
m_hovering_clickable = (is_over_clickable) && (event.modifiers() & Mod_Ctrl);
}
void Editor::mousedown_event(GUI::MouseEvent& event)
@ -292,20 +294,10 @@ void Editor::mousedown_event(GUI::MouseEvent& event)
}
if (auto* span = document().span_at(text_position)) {
if (!highlighter->is_navigatable(span->data)) {
GUI::TextEditor::mousedown_event(event);
if (highlighter->is_navigatable(span->data)) {
on_navigatable_link_click(*span);
return;
}
auto adjusted_range = span->range;
adjusted_range.end().set_column(adjusted_range.end().column() + 1);
auto span_text = document().text_in_range(adjusted_range);
auto header_path = span_text.substring(1, span_text.length() - 2);
#if EDITOR_DEBUG
dbgln("Ctrl+click: {} \"{}\"", adjusted_range, header_path);
#endif
navigate_to_include_if_available(header_path);
return;
}
GUI::TextEditor::mousedown_event(event);
@ -525,4 +517,16 @@ void Editor::flush_file_content_to_langauge_server()
code_document().file_path(),
document().text());
}
void Editor::on_navigatable_link_click(const GUI::TextDocumentSpan& span)
{
auto adjusted_range = span.range;
adjusted_range.end().set_column(adjusted_range.end().column() + 1);
auto span_text = document().text_in_range(adjusted_range);
auto header_path = span_text.substring(1, span_text.length() - 2);
#if EDITOR_DEBUG
dbgln("Ctrl+click: {} \"{}\"", adjusted_range, header_path);
#endif
navigate_to_include_if_available(header_path);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -76,6 +76,7 @@ private:
void show_documentation_tooltip_if_available(const String&, const Gfx::IntPoint& screen_location);
void navigate_to_include_if_available(String);
void on_navigatable_link_click(const GUI::TextDocumentSpan&);
Gfx::IntRect breakpoint_icon_rect(size_t line_number) const;
static const Gfx::Bitmap& breakpoint_icon_bitmap();
@ -109,7 +110,7 @@ private:
String m_last_parsed_token;
GUI::TextPosition m_previous_text_position { 0, 0 };
bool m_hovering_editor { false };
bool m_hovering_link { false };
bool m_hovering_clickable { false };
bool m_autocomplete_in_focus { false };
OwnPtr<LanguageClient> m_language_client;