Bläddra i källkod

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.
Itamar 4 år sedan
förälder
incheckning
50f887c9d5
2 ändrade filer med 26 tillägg och 21 borttagningar
  1. 23 19
      Userland/DevTools/HackStudio/Editor.cpp
  2. 3 2
      Userland/DevTools/HackStudio/Editor.h

+ 23 - 19
Userland/DevTools/HackStudio/Editor.cpp

@@ -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);
+}
 }

+ 3 - 2
Userland/DevTools/HackStudio/Editor.h

@@ -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;