HackStudio: Use String instead of LexicalPath

LexicalPath is a 'heavier' object than a String that is mainly used for
path parsing and validation, we don't actually need any of that in
GitRepo and its related files, so let's move to String :^)

I've also done some east-const conversion in the files that I was
editing for the string change.
This commit is contained in:
Conor Byrne 2021-12-31 18:18:08 +00:00 committed by Andreas Kling
parent 4cfc992125
commit 14b2656107
Notes: sideshowbarker 2024-07-17 21:51:06 +09:00
11 changed files with 79 additions and 77 deletions

View file

@ -38,7 +38,7 @@ EditorWrapper::EditorWrapper()
set_current_editor_wrapper(this);
};
m_editor->on_open = [](String path) {
m_editor->on_open = [](String const& path) {
open_file(path);
};
@ -93,10 +93,10 @@ void EditorWrapper::save()
void EditorWrapper::update_diff()
{
if (m_git_repo)
m_hunks = Diff::parse_hunks(m_git_repo->unstaged_diff(LexicalPath(filename())).value());
m_hunks = Diff::parse_hunks(m_git_repo->unstaged_diff(filename()).value());
}
void EditorWrapper::set_project_root(LexicalPath const& project_root)
void EditorWrapper::set_project_root(String const& project_root)
{
m_project_root = project_root;
auto result = GitRepo::try_to_create(*m_project_root);

View file

@ -43,8 +43,8 @@ public:
void set_filename(const String&);
const String& filename() const { return m_filename; }
Optional<LexicalPath> const& project_root() const { return m_project_root; }
void set_project_root(LexicalPath const& project_root);
Optional<String> const& project_root() const { return m_project_root; }
void set_project_root(String const& project_root);
GitRepo const* git_repo() const { return m_git_repo; }
@ -64,7 +64,7 @@ private:
RefPtr<GUI::Label> m_filename_label;
RefPtr<Editor> m_editor;
Optional<LexicalPath> m_project_root;
Optional<String> m_project_root;
RefPtr<GitRepo> m_git_repo;
Vector<Diff::Hunk> m_hunks;
};

View file

@ -8,12 +8,12 @@
namespace HackStudio {
NonnullRefPtr<GitFilesModel> GitFilesModel::create(Vector<LexicalPath>&& files)
NonnullRefPtr<GitFilesModel> GitFilesModel::create(Vector<String>&& files)
{
return adopt_ref(*new GitFilesModel(move(files)));
}
GitFilesModel::GitFilesModel(Vector<LexicalPath>&& files)
GitFilesModel::GitFilesModel(Vector<String>&& files)
: m_files(move(files))
{
}
@ -21,7 +21,7 @@ GitFilesModel::GitFilesModel(Vector<LexicalPath>&& files)
GUI::Variant GitFilesModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
{
if (role == GUI::ModelRole::Display) {
return m_files.at(index.row()).string();
return m_files.at(index.row());
}
return {};
}

View file

@ -7,7 +7,6 @@
#pragma once
#include "GitRepo.h"
#include <AK/LexicalPath.h>
#include <AK/NonnullRefPtr.h>
#include <LibGUI/Model.h>
@ -15,7 +14,7 @@ namespace HackStudio {
class GitFilesModel final : public GUI::Model {
public:
static NonnullRefPtr<GitFilesModel> create(Vector<LexicalPath>&& files);
static NonnullRefPtr<GitFilesModel> create(Vector<String>&& files);
virtual int row_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return m_files.size(); }
virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override { return 1; }
@ -30,7 +29,7 @@ public:
virtual GUI::ModelIndex index(int row, int column, const GUI::ModelIndex&) const override;
private:
explicit GitFilesModel(Vector<LexicalPath>&& files);
Vector<LexicalPath> m_files;
explicit GitFilesModel(Vector<String>&& files);
Vector<String> m_files;
};
}

View file

@ -56,7 +56,7 @@ void GitFilesView::mousedown_event(GUI::MouseEvent& event)
auto data = model()->index(item_index, model_column()).data();
VERIFY(data.is_string());
m_action_callback(LexicalPath(data.to_string()));
m_action_callback(data.to_string());
}
};

View file

@ -6,14 +6,13 @@
#pragma once
#include <AK/LexicalPath.h>
#include <LibGUI/ListView.h>
#include <LibGfx/Bitmap.h>
namespace HackStudio {
// A "GitFileAction" is either the staging or the unstaging of a file.
using GitFileActionCallback = Function<void(const LexicalPath& file)>;
using GitFileActionCallback = Function<void(String const& file)>;
class GitFilesView : public GUI::ListView {
C_OBJECT(GitFilesView)

View file

@ -9,7 +9,7 @@
namespace HackStudio {
GitRepo::CreateResult GitRepo::try_to_create(const LexicalPath& repository_root)
GitRepo::CreateResult GitRepo::try_to_create(String const& repository_root)
{
if (!git_is_installed()) {
return { CreateResult::Type::GitProgramNotFound, nullptr };
@ -21,7 +21,7 @@ GitRepo::CreateResult GitRepo::try_to_create(const LexicalPath& repository_root)
return { CreateResult::Type::Success, adopt_ref(*new GitRepo(repository_root)) };
}
RefPtr<GitRepo> GitRepo::initialize_repository(const LexicalPath& repository_root)
RefPtr<GitRepo> GitRepo::initialize_repository(String const& repository_root)
{
auto res = command_wrapper({ "init" }, repository_root);
if (res.is_null())
@ -31,7 +31,7 @@ RefPtr<GitRepo> GitRepo::initialize_repository(const LexicalPath& repository_roo
return adopt_ref(*new GitRepo(repository_root));
}
Vector<LexicalPath> GitRepo::unstaged_files() const
Vector<String> GitRepo::unstaged_files() const
{
auto modified = modified_files();
auto untracked = untracked_files();
@ -39,7 +39,7 @@ Vector<LexicalPath> GitRepo::unstaged_files() const
return modified;
}
//
Vector<LexicalPath> GitRepo::staged_files() const
Vector<String> GitRepo::staged_files() const
{
auto raw_result = command({ "diff", "--cached", "--name-only" });
if (raw_result.is_null())
@ -47,7 +47,7 @@ Vector<LexicalPath> GitRepo::staged_files() const
return parse_files_list(raw_result);
}
Vector<LexicalPath> GitRepo::modified_files() const
Vector<String> GitRepo::modified_files() const
{
auto raw_result = command({ "ls-files", "--modified", "--exclude-standard" });
if (raw_result.is_null())
@ -55,7 +55,7 @@ Vector<LexicalPath> GitRepo::modified_files() const
return parse_files_list(raw_result);
}
Vector<LexicalPath> GitRepo::untracked_files() const
Vector<String> GitRepo::untracked_files() const
{
auto raw_result = command({ "ls-files", "--others", "--exclude-standard" });
if (raw_result.is_null())
@ -63,66 +63,67 @@ Vector<LexicalPath> GitRepo::untracked_files() const
return parse_files_list(raw_result);
}
Vector<LexicalPath> GitRepo::parse_files_list(const String& raw_result)
Vector<String> GitRepo::parse_files_list(String const& raw_result)
{
auto lines = raw_result.split('\n');
Vector<LexicalPath> files;
for (const auto& line : lines) {
Vector<String> files;
for (auto const& line : lines) {
files.empend(line);
}
return files;
}
String GitRepo::command(const Vector<String>& command_parts) const
String GitRepo::command(Vector<String> const& command_parts) const
{
return command_wrapper(command_parts, m_repository_root);
}
String GitRepo::command_wrapper(const Vector<String>& command_parts, const LexicalPath& chdir)
String GitRepo::command_wrapper(Vector<String> const& command_parts, String const& chdir)
{
return Core::command("git", command_parts, chdir);
return Core::command("git", command_parts, LexicalPath(chdir));
}
bool GitRepo::git_is_installed()
{
return !command_wrapper({ "--help" }, LexicalPath("/")).is_null();
return !command_wrapper({ "--help" }, "/").is_null();
}
bool GitRepo::git_repo_exists(const LexicalPath& repo_root)
bool GitRepo::git_repo_exists(String const& repo_root)
{
return !command_wrapper({ "status" }, repo_root).is_null();
}
bool GitRepo::stage(const LexicalPath& file)
bool GitRepo::stage(String const& file)
{
return !command({ "add", file.string() }).is_null();
return !command({ "add", file }).is_null();
}
bool GitRepo::unstage(const LexicalPath& file)
bool GitRepo::unstage(String const& file)
{
return !command({ "reset", "HEAD", "--", file.string() }).is_null();
return !command({ "reset", "HEAD", "--", file }).is_null();
}
bool GitRepo::commit(const String& message)
bool GitRepo::commit(String const& message)
{
return !command({ "commit", "-m", message }).is_null();
}
Optional<String> GitRepo::original_file_content(const LexicalPath& file) const
Optional<String> GitRepo::original_file_content(String const& file) const
{
return command({ "show", String::formatted("HEAD:{}", file) });
}
Optional<String> GitRepo::unstaged_diff(const LexicalPath& file) const
Optional<String> GitRepo::unstaged_diff(String const& file) const
{
return command({ "diff", file.string().characters() });
return command({ "diff", file.characters() });
}
bool GitRepo::is_tracked(const LexicalPath& file) const
bool GitRepo::is_tracked(String const& file) const
{
auto res = command({ "ls-files", file.string() });
auto res = command({ "ls-files", file });
if (res.is_null())
return false;
return !res.is_empty();
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
* Copyright (c) 2021, Conor Byrne <conor@cbyrne.dev>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -27,35 +28,37 @@ public:
RefPtr<GitRepo> repo;
};
static CreateResult try_to_create(const LexicalPath& repository_root);
static RefPtr<GitRepo> initialize_repository(const LexicalPath& repository_root);
static CreateResult try_to_create(String const& repository_root);
static RefPtr<GitRepo> initialize_repository(String const& repository_root);
Vector<LexicalPath> unstaged_files() const;
Vector<LexicalPath> staged_files() const;
bool stage(const LexicalPath& file);
bool unstage(const LexicalPath& file);
bool commit(const String& message);
Optional<String> original_file_content(const LexicalPath& file) const;
Optional<String> unstaged_diff(const LexicalPath& file) const;
bool is_tracked(const LexicalPath& file) const;
bool stage(String const& file);
bool unstage(String const& file);
bool commit(String const& message);
bool is_tracked(String const& file) const;
Vector<String> unstaged_files() const;
Vector<String> staged_files() const;
Optional<String> original_file_content(String const& file) const;
Optional<String> unstaged_diff(String const& file) const;
private:
static String command_wrapper(const Vector<String>& command_parts, const LexicalPath& chdir);
static bool git_is_installed();
static bool git_repo_exists(const LexicalPath& repo_root);
static Vector<LexicalPath> parse_files_list(const String&);
static bool git_repo_exists(String const& repo_root);
explicit GitRepo(const LexicalPath& repository_root)
static String command_wrapper(Vector<String> const& command_parts, String const& chdir);
static Vector<String> parse_files_list(String const&);
explicit GitRepo(String const& repository_root)
: m_repository_root(repository_root)
{
}
Vector<LexicalPath> modified_files() const;
Vector<LexicalPath> untracked_files() const;
Vector<String> modified_files() const;
Vector<String> untracked_files() const;
String command(const Vector<String>& command_parts) const;
String command(Vector<String> const& command_parts) const;
LexicalPath m_repository_root;
String m_repository_root;
};
}

View file

@ -21,7 +21,7 @@
namespace HackStudio {
GitWidget::GitWidget(const LexicalPath& repo_root)
GitWidget::GitWidget(String const& repo_root)
: m_repo_root(repo_root)
{
set_layout<GUI::HorizontalBoxLayout>();
@ -42,7 +42,7 @@ GitWidget::GitWidget(const LexicalPath& repo_root)
unstaged_header.set_fixed_height(20);
m_unstaged_files = unstaged.add<GitFilesView>(
[this](const auto& file) { stage_file(file); },
[this](auto const& file) { stage_file(file); },
Gfx::Bitmap::try_load_from_file("/res/icons/16x16/plus.png").release_value_but_fixme_should_propagate_errors());
m_unstaged_files->on_selection_change = [this] {
const auto& index = m_unstaged_files->selection().first();
@ -50,7 +50,7 @@ GitWidget::GitWidget(const LexicalPath& repo_root)
return;
const auto& selected = index.data().as_string();
show_diff(LexicalPath(selected));
show_diff(selected);
};
auto& staged = add<GUI::Widget>();
@ -70,7 +70,7 @@ GitWidget::GitWidget(const LexicalPath& repo_root)
staged_header.set_fixed_height(20);
m_staged_files = staged.add<GitFilesView>(
[this](const auto& file) { unstage_file(file); },
[this](auto const& file) { unstage_file(file); },
Gfx::Bitmap::try_load_from_file("/res/icons/16x16/minus.png").release_value_but_fixme_should_propagate_errors());
}
@ -117,7 +117,7 @@ void GitWidget::refresh()
m_staged_files->set_model(GitFilesModel::create(m_git_repo->staged_files()));
}
void GitWidget::stage_file(const LexicalPath& file)
void GitWidget::stage_file(String const& file)
{
dbgln("staging: {}", file);
bool rc = m_git_repo->stage(file);
@ -125,7 +125,7 @@ void GitWidget::stage_file(const LexicalPath& file)
refresh();
}
void GitWidget::unstage_file(const LexicalPath& file)
void GitWidget::unstage_file(String const& file)
{
dbgln("unstaging: {}", file);
bool rc = m_git_repo->unstage(file);
@ -153,10 +153,10 @@ void GitWidget::set_view_diff_callback(ViewDiffCallback callback)
m_view_diff_callback = move(callback);
}
void GitWidget::show_diff(const LexicalPath& file_path)
void GitWidget::show_diff(String const& file_path)
{
if (!m_git_repo->is_tracked(file_path)) {
auto file = Core::File::construct(file_path.string());
auto file = Core::File::construct(file_path);
if (!file->open(Core::OpenMode::ReadOnly)) {
perror("open");
VERIFY_NOT_REACHED();
@ -173,7 +173,7 @@ void GitWidget::show_diff(const LexicalPath& file_path)
m_view_diff_callback(original_content.value(), diff.value());
}
void GitWidget::change_repo(LexicalPath const& repo_root)
void GitWidget::change_repo(String const& repo_root)
{
m_repo_root = repo_root;
m_git_repo = nullptr;

View file

@ -24,19 +24,19 @@ public:
void refresh();
void set_view_diff_callback(ViewDiffCallback callback);
bool initialized() const { return !m_git_repo.is_null(); };
void change_repo(LexicalPath const& repo_root);
void change_repo(String const& repo_root);
private:
explicit GitWidget(const LexicalPath& repo_root);
explicit GitWidget(String const& repo_root);
bool initialize();
bool initialize_if_needed();
void stage_file(const LexicalPath&);
void unstage_file(const LexicalPath&);
void stage_file(String const&);
void unstage_file(String const&);
void commit();
void show_diff(const LexicalPath&);
void show_diff(String const&);
LexicalPath m_repo_root;
String m_repo_root;
RefPtr<GitFilesView> m_unstaged_files;
RefPtr<GitFilesView> m_staged_files;
RefPtr<GitRepo> m_git_repo;

View file

@ -208,7 +208,7 @@ void HackStudioWidget::open_project(const String& root_path)
m_project_tree_view->update();
}
if (m_git_widget && m_git_widget->initialized()) {
m_git_widget->change_repo(LexicalPath(root_path));
m_git_widget->change_repo(root_path);
m_git_widget->refresh();
}
if (Debugger::is_initialized()) {
@ -217,7 +217,7 @@ void HackStudioWidget::open_project(const String& root_path)
debugger.set_source_root(m_project->root_path());
}
for (auto& editor_wrapper : m_all_editor_wrappers)
editor_wrapper.set_project_root(LexicalPath(m_project->root_path()));
editor_wrapper.set_project_root(m_project->root_path());
m_locations_history.clear();
m_locations_history_end_index = 0;
@ -597,7 +597,7 @@ void HackStudioWidget::add_new_editor(GUI::Widget& parent)
m_all_editor_wrappers.append(wrapper);
wrapper->editor().set_focus(true);
wrapper->editor().set_font(*m_editor_font);
wrapper->set_project_root(LexicalPath(m_project->root_path()));
wrapper->set_project_root(m_project->root_path());
wrapper->editor().on_cursor_change = [this] { on_cursor_change(); };
wrapper->on_change = [this] { update_gml_preview(); };
set_edit_mode(EditMode::Text);
@ -1103,7 +1103,7 @@ void HackStudioWidget::create_action_tab(GUI::Widget& parent)
};
m_disassembly_widget = m_action_tab_widget->add_tab<DisassemblyWidget>("Disassembly");
m_git_widget = m_action_tab_widget->add_tab<GitWidget>("Git", LexicalPath(m_project->root_path()));
m_git_widget = m_action_tab_widget->add_tab<GitWidget>("Git", m_project->root_path());
m_git_widget->set_view_diff_callback([this](const auto& original_content, const auto& diff) {
m_diff_viewer->set_content(original_content, diff);
set_edit_mode(EditMode::Diff);