HackStudio: Add header navigation
This commit is contained in:
parent
d8a73dd979
commit
879bf3e97b
Notes:
sideshowbarker
2024-07-19 08:45:23 +09:00
Author: https://github.com/oriko1010 Commit: https://github.com/SerenityOS/serenity/commit/879bf3e97b5 Pull-request: https://github.com/SerenityOS/serenity/pull/1421
4 changed files with 95 additions and 4 deletions
|
@ -34,14 +34,14 @@
|
|||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/ScrollBar.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibMarkdown/MDDocument.h>
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/HTMLHeadElement.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
#include <LibWeb/Parser/HTMLParser.h>
|
||||
#include <LibMarkdown/MDDocument.h>
|
||||
|
||||
//#define EDITOR_DEBUG
|
||||
// #define EDITOR_DEBUG
|
||||
|
||||
Editor::Editor()
|
||||
{
|
||||
|
@ -194,3 +194,76 @@ void Editor::mousemove_event(GUI::MouseEvent& event)
|
|||
}
|
||||
GUI::Application::the().hide_tooltip();
|
||||
}
|
||||
|
||||
void Editor::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!(event.modifiers() & Mod_Ctrl)) {
|
||||
GUI::TextEditor::mousedown_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
auto text_position = text_position_at(event.position());
|
||||
if (!text_position.is_valid()) {
|
||||
GUI::TextEditor::mousedown_event(event);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& span : document().spans()) {
|
||||
if (span.range.contains(text_position)) {
|
||||
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);
|
||||
#ifdef EDITOR_DEBUG
|
||||
dbg() << "Ctrl+click: " << adjusted_range << " \"" << header_path << "\"";
|
||||
#endif
|
||||
navigate_to_include_if_available(header_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GUI::TextEditor::mousedown_event(event);
|
||||
}
|
||||
|
||||
static HashMap<String, String>& include_paths()
|
||||
{
|
||||
static HashMap<String, String> paths;
|
||||
|
||||
auto add_directory = [](String base, Optional<String> recursive, auto handle_directory) -> void {
|
||||
Core::DirIterator it(recursive.value_or(base), Core::DirIterator::Flags::SkipDots);
|
||||
while (it.has_next()) {
|
||||
auto path = it.next_full_path();
|
||||
if (!Core::File::is_directory(path)) {
|
||||
auto key = path.substring(base.length() + 1, path.length() - base.length() - 1);
|
||||
#ifdef EDITOR_DEBUG
|
||||
dbg() << "Adding header \"" << key << "\" in path \"" << path << "\"";
|
||||
#endif
|
||||
paths.set(key, path);
|
||||
} else {
|
||||
handle_directory(base, path, handle_directory);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (paths.is_empty()) {
|
||||
add_directory(".", {}, add_directory);
|
||||
add_directory("/usr/local/include", {}, add_directory);
|
||||
add_directory("/usr/local/include/c++/9.2.0", {}, add_directory);
|
||||
add_directory("/usr/include", {}, add_directory);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
void Editor::navigate_to_include_if_available(String path)
|
||||
{
|
||||
auto it = include_paths().find(path);
|
||||
if (it == include_paths().end()) {
|
||||
#ifdef EDITOR_DEBUG
|
||||
dbg() << "no header " << path << " found.";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
on_open(it->value);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
virtual ~Editor() override;
|
||||
|
||||
Function<void()> on_focus;
|
||||
Function<void(String)> on_open;
|
||||
|
||||
EditorWrapper& wrapper();
|
||||
const EditorWrapper& wrapper() const;
|
||||
|
@ -46,8 +47,10 @@ private:
|
|||
virtual void focusout_event(Core::Event&) override;
|
||||
virtual void paint_event(GUI::PaintEvent&) override;
|
||||
virtual void mousemove_event(GUI::MouseEvent&) override;
|
||||
virtual void mousedown_event(GUI::MouseEvent&) override;
|
||||
|
||||
void show_documentation_tooltip_if_available(const String&, const Gfx::Point& screen_location);
|
||||
void navigate_to_include_if_available(String);
|
||||
|
||||
explicit Editor();
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <LibGfx/Font.h>
|
||||
|
||||
extern RefPtr<EditorWrapper> g_current_editor_wrapper;
|
||||
extern Function<void(String)> g_open_file;
|
||||
|
||||
EditorWrapper::EditorWrapper()
|
||||
{
|
||||
|
@ -67,6 +68,10 @@ EditorWrapper::EditorWrapper()
|
|||
m_editor->on_focus = [this] {
|
||||
g_current_editor_wrapper = this;
|
||||
};
|
||||
|
||||
m_editor->on_open = [this](String path) {
|
||||
g_open_file(path);
|
||||
};
|
||||
}
|
||||
|
||||
EditorWrapper::~EditorWrapper()
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
|
||||
NonnullRefPtrVector<EditorWrapper> g_all_editor_wrappers;
|
||||
RefPtr<EditorWrapper> g_current_editor_wrapper;
|
||||
Function<void(String)> g_open_file;
|
||||
|
||||
String g_currently_open_file;
|
||||
OwnPtr<Project> g_project;
|
||||
|
@ -529,6 +530,8 @@ int main(int argc, char** argv)
|
|||
remove_current_editor_action->set_enabled(g_all_editor_wrappers.size() > 1);
|
||||
};
|
||||
|
||||
g_open_file = open_file;
|
||||
|
||||
open_file("main.cpp");
|
||||
|
||||
update_actions();
|
||||
|
@ -547,8 +550,15 @@ void run(TerminalWrapper& wrapper)
|
|||
|
||||
void open_file(const String& filename)
|
||||
{
|
||||
auto file = g_project->get_file(filename);
|
||||
current_editor().set_document(const_cast<GUI::TextDocument&>(file->document()));
|
||||
auto project_file = g_project->get_file(filename);
|
||||
if (project_file) {
|
||||
current_editor().set_document(const_cast<GUI::TextDocument&>(project_file->document()));
|
||||
current_editor().set_readonly(false);
|
||||
} else {
|
||||
auto external_file = ProjectFile::construct_with_name(filename);
|
||||
current_editor().set_document(const_cast<GUI::TextDocument&>(external_file->document()));
|
||||
current_editor().set_readonly(true);
|
||||
}
|
||||
|
||||
if (filename.ends_with(".cpp") || filename.ends_with(".h"))
|
||||
current_editor().set_syntax_highlighter(make<GUI::CppSyntaxHighlighter>());
|
||||
|
|
Loading…
Add table
Reference in a new issue