From e0f1c237d21be3e2831092319f50bb429ad1f7a9 Mon Sep 17 00:00:00 2001 From: Federico Guerinoni Date: Tue, 1 Jun 2021 23:54:55 +0200 Subject: [PATCH] HackStudio: Make TODO entries clickable Now you can click a TODO entry to set focus on that position of that file. --- .../HackStudio/AutoCompleteResponse.h | 30 +++++++++++++++++ .../DevTools/HackStudio/LanguageClient.cpp | 2 +- Userland/DevTools/HackStudio/LanguageClient.h | 3 +- .../CodeComprehensionEngine.cpp | 2 +- .../LanguageServers/CodeComprehensionEngine.h | 4 +-- .../LanguageServers/Cpp/ClientConnection.h | 2 +- .../LanguageServers/LanguageClient.ipc | 2 +- .../LanguageServers/Shell/ClientConnection.h | 3 +- Userland/DevTools/HackStudio/ToDoEntries.cpp | 12 +++---- Userland/DevTools/HackStudio/ToDoEntries.h | 12 +++---- .../DevTools/HackStudio/ToDoEntriesWidget.cpp | 32 ++++++++++++------- .../DevTools/HackStudio/ToDoEntriesWidget.h | 2 -- Userland/Libraries/LibCpp/Parser.cpp | 6 ++-- Userland/Libraries/LibCpp/Parser.h | 9 +++++- Userland/Libraries/LibCpp/Preprocessor.h | 1 + 15 files changed, 83 insertions(+), 39 deletions(-) diff --git a/Userland/DevTools/HackStudio/AutoCompleteResponse.h b/Userland/DevTools/HackStudio/AutoCompleteResponse.h index b2ade7fee4..17e805b722 100644 --- a/Userland/DevTools/HackStudio/AutoCompleteResponse.h +++ b/Userland/DevTools/HackStudio/AutoCompleteResponse.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -102,4 +103,33 @@ inline bool decode(Decoder& decoder, GUI::AutocompleteProvider::Declaration& dec return true; } +template<> +inline bool encode(Encoder& encoder, Cpp::Parser::TodoEntry const& entry) +{ + encoder << entry.content; + encoder << entry.filename; + encoder << (u64)entry.line; + encoder << (u64)entry.column; + return true; +} + +template<> +inline bool decode(Decoder& decoder, Cpp::Parser::TodoEntry& entry) +{ + u64 line = 0; + u64 column = 0; + if (!decoder.decode(entry.content)) + return false; + if (!decoder.decode(entry.filename)) + return false; + if (!decoder.decode(line)) + return false; + if (!decoder.decode(column)) + return false; + + entry.line = line; + entry.column = column; + return true; +} + } diff --git a/Userland/DevTools/HackStudio/LanguageClient.cpp b/Userland/DevTools/HackStudio/LanguageClient.cpp index 72335a9c36..6e47813609 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.cpp +++ b/Userland/DevTools/HackStudio/LanguageClient.cpp @@ -99,7 +99,7 @@ void ServerConnection::declarations_in_document(const String& filename, const Ve ProjectDeclarations::the().set_declared_symbols(filename, declarations); } -void ServerConnection::todo_entries_in_document(const String& filename, const Vector& todo_entries) +void ServerConnection::todo_entries_in_document(String const& filename, Vector const& todo_entries) { ToDoEntries::the().set_entries(filename, move(todo_entries)); } diff --git a/Userland/DevTools/HackStudio/LanguageClient.h b/Userland/DevTools/HackStudio/LanguageClient.h index 1555ccccad..fcaad65d1c 100644 --- a/Userland/DevTools/HackStudio/LanguageClient.h +++ b/Userland/DevTools/HackStudio/LanguageClient.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ protected: virtual void auto_complete_suggestions(Vector const&) override; virtual void declaration_location(GUI::AutocompleteProvider::ProjectLocation const&) override; virtual void declarations_in_document(String const&, Vector const&) override; - virtual void todo_entries_in_document(String const&, Vector const&) override; + virtual void todo_entries_in_document(String const&, Vector const&) override; void set_wrapper(ServerConnectionWrapper& wrapper) { m_wrapper = &wrapper; } String m_project_path; diff --git a/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.cpp b/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.cpp index 02dd66bb44..aec90ce5af 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.cpp +++ b/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.cpp @@ -32,7 +32,7 @@ void CodeComprehensionEngine::set_declarations_of_document(const String& filenam set_declarations_of_document_callback(filename, move(declarations)); } -void CodeComprehensionEngine::set_todo_entries_of_document(const String& filename, Vector&& todo_entries) +void CodeComprehensionEngine::set_todo_entries_of_document(String const& filename, Vector&& todo_entries) { VERIFY(set_todo_entries_of_document_callback); set_todo_entries_of_document_callback(filename, move(todo_entries)); diff --git a/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.h b/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.h index 75c2020201..e7a6aabaf6 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.h +++ b/Userland/DevTools/HackStudio/LanguageServers/CodeComprehensionEngine.h @@ -30,12 +30,12 @@ public: public: Function&&)> set_declarations_of_document_callback; - Function&&)> set_todo_entries_of_document_callback; + Function&&)> set_todo_entries_of_document_callback; protected: const FileDB& filedb() const { return m_filedb; } void set_declarations_of_document(const String&, Vector&&); - void set_todo_entries_of_document(const String&, Vector&&); + void set_todo_entries_of_document(String const&, Vector&&); const HashMap>& all_declarations() const { return m_all_declarations; } private: diff --git a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h index 96234a2164..5c88f59ac0 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Cpp/ClientConnection.h @@ -22,7 +22,7 @@ public: m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector&& declarations) { async_declarations_in_document(filename, move(declarations)); }; - m_autocomplete_engine->set_todo_entries_of_document_callback = [this](const String& filename, Vector&& todo_entries) { + m_autocomplete_engine->set_todo_entries_of_document_callback = [this](String const& filename, Vector&& todo_entries) { async_todo_entries_in_document(filename, move(todo_entries)); }; } diff --git a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc index ed6397f41c..6400dd7b29 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc +++ b/Userland/DevTools/HackStudio/LanguageServers/LanguageClient.ipc @@ -3,5 +3,5 @@ endpoint LanguageClient auto_complete_suggestions(Vector suggestions) =| declaration_location(GUI::AutocompleteProvider::ProjectLocation location) =| declarations_in_document(String filename, Vector declarations) =| - todo_entries_in_document(String filename, Vector todo_entries) =| + todo_entries_in_document(String filename, Vector todo_entries) =| } diff --git a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h index 67a5da80f6..285f01920e 100644 --- a/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h +++ b/Userland/DevTools/HackStudio/LanguageServers/Shell/ClientConnection.h @@ -8,6 +8,7 @@ #include "ShellComprehensionEngine.h" #include +#include namespace LanguageServers::Shell { @@ -21,7 +22,7 @@ class ClientConnection final : public LanguageServers::ClientConnection { m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector&& declarations) { async_declarations_in_document(filename, move(declarations)); }; - m_autocomplete_engine->set_todo_entries_of_document_callback = [this](const String& filename, Vector&& todo_entries) { + m_autocomplete_engine->set_todo_entries_of_document_callback = [this](String const& filename, Vector&& todo_entries) { async_todo_entries_in_document(filename, move(todo_entries)); }; } diff --git a/Userland/DevTools/HackStudio/ToDoEntries.cpp b/Userland/DevTools/HackStudio/ToDoEntries.cpp index 00c27cd8d2..1a706bbf7e 100644 --- a/Userland/DevTools/HackStudio/ToDoEntries.cpp +++ b/Userland/DevTools/HackStudio/ToDoEntries.cpp @@ -14,20 +14,20 @@ ToDoEntries& HackStudio::ToDoEntries::the() return s_instance; } -void ToDoEntries::set_entries(const String& filename, const Vector&& entries) +void ToDoEntries::set_entries(String const& filename, Vector const&& entries) { m_document_to_entries.set(filename, move(entries)); if (on_update) on_update(); } -Vector ToDoEntries::get_entries() +Vector ToDoEntries::get_entries() { - Vector ret; - for (auto& it : m_document_to_entries) + Vector ret; + for (auto& it : m_document_to_entries) { for (auto& entry : it.value) - ret.append({ it.key, entry }); - + ret.append({ entry.content, it.key, entry.line, entry.column }); + } return ret; } diff --git a/Userland/DevTools/HackStudio/ToDoEntries.h b/Userland/DevTools/HackStudio/ToDoEntries.h index 849145b374..8efe89e414 100644 --- a/Userland/DevTools/HackStudio/ToDoEntries.h +++ b/Userland/DevTools/HackStudio/ToDoEntries.h @@ -10,29 +10,25 @@ #include #include #include +#include namespace HackStudio { -struct ToDoEntryPair { - String filename; - String comment; -}; - class ToDoEntries { AK_MAKE_NONCOPYABLE(ToDoEntries); public: static ToDoEntries& the(); - void set_entries(const String& filename, const Vector&& entries); + void set_entries(String const& filename, Vector const&& entries); - Vector get_entries(); + Vector get_entries(); Function on_update = nullptr; private: ToDoEntries() = default; - HashMap> m_document_to_entries; + HashMap> m_document_to_entries; }; } diff --git a/Userland/DevTools/HackStudio/ToDoEntriesWidget.cpp b/Userland/DevTools/HackStudio/ToDoEntriesWidget.cpp index ff7a3f119f..141fc27f31 100644 --- a/Userland/DevTools/HackStudio/ToDoEntriesWidget.cpp +++ b/Userland/DevTools/HackStudio/ToDoEntriesWidget.cpp @@ -6,13 +6,8 @@ #include "ToDoEntriesWidget.h" #include "HackStudio.h" -#include "Project.h" #include "ToDoEntries.h" -#include #include -#include -#include -#include #include namespace HackStudio { @@ -22,16 +17,18 @@ public: enum Column { Filename, Text, + Line, + Column, __Count }; - explicit ToDoEntriesModel(const Vector&& matches) + explicit ToDoEntriesModel(Vector const&& matches) : m_matches(move(matches)) { } - virtual int row_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return m_matches.size(); } - virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return Column::__Count; } + virtual int row_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return m_matches.size(); } + virtual int column_count(GUI::ModelIndex const& = GUI::ModelIndex()) const override { return Column::__Count; } virtual String column_name(int column) const override { @@ -40,12 +37,16 @@ public: return "Filename"; case Column::Text: return "Text"; + case Column::Line: + return "Line"; + case Column::Column: + return "Col"; default: VERIFY_NOT_REACHED(); } } - virtual GUI::Variant data(const GUI::ModelIndex& index, GUI::ModelRole role) const override + virtual GUI::Variant data(GUI::ModelIndex const& index, GUI::ModelRole role) const override { if (role == GUI::ModelRole::TextAlignment) return Gfx::TextAlignment::CenterLeft; @@ -60,7 +61,11 @@ public: case Column::Filename: return match.filename; case Column::Text: - return match.comment; + return match.content; + case Column::Line: + return String::formatted("{}", match.line + 1); + case Column::Column: + return String::formatted("{}", match.column); } } return {}; @@ -77,7 +82,7 @@ public: } private: - Vector m_matches; + Vector m_matches; }; void ToDoEntriesWidget::refresh() @@ -91,6 +96,11 @@ ToDoEntriesWidget::ToDoEntriesWidget() { set_layout(); m_result_view = add(); + + m_result_view->on_activation = [](auto& index) { + auto& match = *(Cpp::Parser::TodoEntry const*)index.internal_data(); + open_file(match.filename, match.line, match.column); + }; } } diff --git a/Userland/DevTools/HackStudio/ToDoEntriesWidget.h b/Userland/DevTools/HackStudio/ToDoEntriesWidget.h index ca252fd924..f62f8d5d2f 100644 --- a/Userland/DevTools/HackStudio/ToDoEntriesWidget.h +++ b/Userland/DevTools/HackStudio/ToDoEntriesWidget.h @@ -6,9 +6,7 @@ #pragma once -#include #include -#include #include namespace HackStudio { diff --git a/Userland/Libraries/LibCpp/Parser.cpp b/Userland/Libraries/LibCpp/Parser.cpp index c4b913ef6a..4906216e09 100644 --- a/Userland/Libraries/LibCpp/Parser.cpp +++ b/Userland/Libraries/LibCpp/Parser.cpp @@ -961,13 +961,13 @@ void Parser::print_tokens() const } } -Vector Parser::get_todo_entries() const +Vector Parser::get_todo_entries() const { - Vector ret; + Vector ret; for (auto& token : m_tokens) { if (token.type() == Token::Type::Comment) { if (token.text().contains("TODO")) { - ret.append(token.text()); + ret.append({ token.text(), m_filename, token.start().line, token.start().column }); } } } diff --git a/Userland/Libraries/LibCpp/Parser.h b/Userland/Libraries/LibCpp/Parser.h index 1ac0226151..8409144241 100644 --- a/Userland/Libraries/LibCpp/Parser.h +++ b/Userland/Libraries/LibCpp/Parser.h @@ -35,7 +35,14 @@ public: void print_tokens() const; const Vector& errors() const { return m_state.errors; } const Preprocessor::Definitions& preprocessor_definitions() const { return m_preprocessor_definitions; } - Vector get_todo_entries() const; + + struct TodoEntry { + String content; + String filename; + size_t line { 0 }; + size_t column { 0 }; + }; + Vector get_todo_entries() const; struct TokenAndPreprocessorDefinition { Token token; diff --git a/Userland/Libraries/LibCpp/Preprocessor.h b/Userland/Libraries/LibCpp/Preprocessor.h index e62cb95027..c96bd8180a 100644 --- a/Userland/Libraries/LibCpp/Preprocessor.h +++ b/Userland/Libraries/LibCpp/Preprocessor.h @@ -14,6 +14,7 @@ #include namespace Cpp { + class Preprocessor { public: