Skip to content

Commit

Permalink
HackStudio: Display identifiers as clickable
Browse files Browse the repository at this point in the history
This extends the "navigate to include" feature to also display
identifiers as clickable when they're hovered over while left control
is pressed.
  • Loading branch information
itamar8910 authored and awesomekling committed Feb 20, 2021
1 parent adb6db9 commit 50f887c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
42 changes: 23 additions & 19 deletions Userland/DevTools/HackStudio/Editor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <[email protected]>
* Copyright (c) 2018-2021, Andreas Kling <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -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();
}
Expand All @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
5 changes: 3 additions & 2 deletions Userland/DevTools/HackStudio/Editor.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <[email protected]>
* Copyright (c) 2018-2021, Andreas Kling <[email protected]>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -76,6 +76,7 @@ class Editor final : public GUI::TextEditor {

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();
Expand Down Expand Up @@ -109,7 +110,7 @@ class Editor final : public GUI::TextEditor {
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;
Expand Down

0 comments on commit 50f887c

Please sign in to comment.