mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-09 04:37:52 +03:00
HackStudio: Make TODO entries clickable
Now you can click a TODO entry to set focus on that position of that file.
This commit is contained in:
parent
935c7b2f4b
commit
e0f1c237d2
Notes:
sideshowbarker
2024-07-18 11:36:52 +09:00
Author: https://github.com/guerinoni Commit: https://github.com/SerenityOS/serenity/commit/e0f1c237d21 Pull-request: https://github.com/SerenityOS/serenity/pull/6614 Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/itamar8910 ✅ Reviewed-by: https://github.com/linusg
@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibCpp/Parser.h>
|
||||
#include <LibGUI/AutocompleteProvider.h>
|
||||
#include <LibIPC/Decoder.h>
|
||||
#include <LibIPC/Encoder.h>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String>& todo_entries)
|
||||
void ServerConnection::todo_entries_in_document(String const& filename, Vector<Cpp::Parser::TodoEntry> const& todo_entries)
|
||||
{
|
||||
ToDoEntries::the().set_entries(filename, move(todo_entries));
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <AK/Weakable.h>
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
#include <LibCpp/Preprocessor.h>
|
||||
#include <LibIPC/ServerConnection.h>
|
||||
|
||||
#include <DevTools/HackStudio/LanguageServers/LanguageClientEndpoint.h>
|
||||
@ -46,7 +47,7 @@ protected:
|
||||
virtual void auto_complete_suggestions(Vector<GUI::AutocompleteProvider::Entry> const&) override;
|
||||
virtual void declaration_location(GUI::AutocompleteProvider::ProjectLocation const&) override;
|
||||
virtual void declarations_in_document(String const&, Vector<GUI::AutocompleteProvider::Declaration> const&) override;
|
||||
virtual void todo_entries_in_document(String const&, Vector<String> const&) override;
|
||||
virtual void todo_entries_in_document(String const&, Vector<Cpp::Parser::TodoEntry> const&) override;
|
||||
void set_wrapper(ServerConnectionWrapper& wrapper) { m_wrapper = &wrapper; }
|
||||
|
||||
String m_project_path;
|
||||
|
@ -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<String>&& todo_entries)
|
||||
void CodeComprehensionEngine::set_todo_entries_of_document(String const& filename, Vector<Cpp::Parser::TodoEntry>&& todo_entries)
|
||||
{
|
||||
VERIFY(set_todo_entries_of_document_callback);
|
||||
set_todo_entries_of_document_callback(filename, move(todo_entries));
|
||||
|
@ -30,12 +30,12 @@ public:
|
||||
|
||||
public:
|
||||
Function<void(const String&, Vector<GUI::AutocompleteProvider::Declaration>&&)> set_declarations_of_document_callback;
|
||||
Function<void(const String&, Vector<String>&&)> set_todo_entries_of_document_callback;
|
||||
Function<void(String const&, Vector<Cpp::Parser::TodoEntry>&&)> set_todo_entries_of_document_callback;
|
||||
|
||||
protected:
|
||||
const FileDB& filedb() const { return m_filedb; }
|
||||
void set_declarations_of_document(const String&, Vector<GUI::AutocompleteProvider::Declaration>&&);
|
||||
void set_todo_entries_of_document(const String&, Vector<String>&&);
|
||||
void set_todo_entries_of_document(String const&, Vector<Cpp::Parser::TodoEntry>&&);
|
||||
const HashMap<String, Vector<GUI::AutocompleteProvider::Declaration>>& all_declarations() const { return m_all_declarations; }
|
||||
|
||||
private:
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector<GUI::AutocompleteProvider::Declaration>&& declarations) {
|
||||
async_declarations_in_document(filename, move(declarations));
|
||||
};
|
||||
m_autocomplete_engine->set_todo_entries_of_document_callback = [this](const String& filename, Vector<String>&& todo_entries) {
|
||||
m_autocomplete_engine->set_todo_entries_of_document_callback = [this](String const& filename, Vector<Cpp::Parser::TodoEntry>&& todo_entries) {
|
||||
async_todo_entries_in_document(filename, move(todo_entries));
|
||||
};
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ endpoint LanguageClient
|
||||
auto_complete_suggestions(Vector<GUI::AutocompleteProvider::Entry> suggestions) =|
|
||||
declaration_location(GUI::AutocompleteProvider::ProjectLocation location) =|
|
||||
declarations_in_document(String filename, Vector<GUI::AutocompleteProvider::Declaration> declarations) =|
|
||||
todo_entries_in_document(String filename, Vector<String> todo_entries) =|
|
||||
todo_entries_in_document(String filename, Vector<Cpp::Parser::TodoEntry> todo_entries) =|
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "ShellComprehensionEngine.h"
|
||||
#include <DevTools/HackStudio/LanguageServers/ClientConnection.h>
|
||||
#include <LibCpp/Parser.h>
|
||||
|
||||
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<GUI::AutocompleteProvider::Declaration>&& declarations) {
|
||||
async_declarations_in_document(filename, move(declarations));
|
||||
};
|
||||
m_autocomplete_engine->set_todo_entries_of_document_callback = [this](const String& filename, Vector<String>&& todo_entries) {
|
||||
m_autocomplete_engine->set_todo_entries_of_document_callback = [this](String const& filename, Vector<Cpp::Parser::TodoEntry>&& todo_entries) {
|
||||
async_todo_entries_in_document(filename, move(todo_entries));
|
||||
};
|
||||
}
|
||||
|
@ -14,20 +14,20 @@ ToDoEntries& HackStudio::ToDoEntries::the()
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void ToDoEntries::set_entries(const String& filename, const Vector<String>&& entries)
|
||||
void ToDoEntries::set_entries(String const& filename, Vector<Cpp::Parser::TodoEntry> const&& entries)
|
||||
{
|
||||
m_document_to_entries.set(filename, move(entries));
|
||||
if (on_update)
|
||||
on_update();
|
||||
}
|
||||
|
||||
Vector<ToDoEntryPair> ToDoEntries::get_entries()
|
||||
Vector<Cpp::Parser::TodoEntry> ToDoEntries::get_entries()
|
||||
{
|
||||
Vector<ToDoEntryPair> ret;
|
||||
for (auto& it : m_document_to_entries)
|
||||
Vector<Cpp::Parser::TodoEntry> 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;
|
||||
}
|
||||
|
||||
|
@ -10,29 +10,25 @@
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCpp/Parser.h>
|
||||
|
||||
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<String>&& entries);
|
||||
void set_entries(String const& filename, Vector<Cpp::Parser::TodoEntry> const&& entries);
|
||||
|
||||
Vector<ToDoEntryPair> get_entries();
|
||||
Vector<Cpp::Parser::TodoEntry> get_entries();
|
||||
|
||||
Function<void()> on_update = nullptr;
|
||||
|
||||
private:
|
||||
ToDoEntries() = default;
|
||||
HashMap<String, Vector<String>> m_document_to_entries;
|
||||
HashMap<String, Vector<Cpp::Parser::TodoEntry>> m_document_to_entries;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -6,13 +6,8 @@
|
||||
|
||||
#include "ToDoEntriesWidget.h"
|
||||
#include "HackStudio.h"
|
||||
#include "Project.h"
|
||||
#include "ToDoEntries.h"
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibGUI/BoxLayout.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/TableView.h>
|
||||
#include <LibGUI/TextBox.h>
|
||||
#include <LibGfx/FontDatabase.h>
|
||||
|
||||
namespace HackStudio {
|
||||
@ -22,16 +17,18 @@ public:
|
||||
enum Column {
|
||||
Filename,
|
||||
Text,
|
||||
Line,
|
||||
Column,
|
||||
__Count
|
||||
};
|
||||
|
||||
explicit ToDoEntriesModel(const Vector<ToDoEntryPair>&& matches)
|
||||
explicit ToDoEntriesModel(Vector<Cpp::Parser::TodoEntry> 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<ToDoEntryPair> m_matches;
|
||||
Vector<Cpp::Parser::TodoEntry> m_matches;
|
||||
};
|
||||
|
||||
void ToDoEntriesWidget::refresh()
|
||||
@ -91,6 +96,11 @@ ToDoEntriesWidget::ToDoEntriesWidget()
|
||||
{
|
||||
set_layout<GUI::VerticalBoxLayout>();
|
||||
m_result_view = add<GUI::TableView>();
|
||||
|
||||
m_result_view->on_activation = [](auto& index) {
|
||||
auto& match = *(Cpp::Parser::TodoEntry const*)index.internal_data();
|
||||
open_file(match.filename, match.line, match.column);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/TableView.h>
|
||||
#include <LibGUI/TextBox.h>
|
||||
#include <LibGUI/Widget.h>
|
||||
|
||||
namespace HackStudio {
|
||||
|
@ -961,13 +961,13 @@ void Parser::print_tokens() const
|
||||
}
|
||||
}
|
||||
|
||||
Vector<String> Parser::get_todo_entries() const
|
||||
Vector<Parser::TodoEntry> Parser::get_todo_entries() const
|
||||
{
|
||||
Vector<String> ret;
|
||||
Vector<TodoEntry> 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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,14 @@ public:
|
||||
void print_tokens() const;
|
||||
const Vector<String>& errors() const { return m_state.errors; }
|
||||
const Preprocessor::Definitions& preprocessor_definitions() const { return m_preprocessor_definitions; }
|
||||
Vector<String> get_todo_entries() const;
|
||||
|
||||
struct TodoEntry {
|
||||
String content;
|
||||
String filename;
|
||||
size_t line { 0 };
|
||||
size_t column { 0 };
|
||||
};
|
||||
Vector<TodoEntry> get_todo_entries() const;
|
||||
|
||||
struct TokenAndPreprocessorDefinition {
|
||||
Token token;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <AK/Vector.h>
|
||||
|
||||
namespace Cpp {
|
||||
|
||||
class Preprocessor {
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user