summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2020-09-12 20:53:20 +0300
committerAndreas Kling <kling@serenityos.org>2020-09-15 21:43:29 +0200
commitd1eedd0e9f1b0f78b5e9bafe22c94684c4f1176b (patch)
tree2f881ea15b396a3deef7a7498f07704251d82de7
parentba11082b4b62b5bdee6c35ab0c9dcfb82efb3d6b (diff)
downloadserenity-d1eedd0e9f1b0f78b5e9bafe22c94684c4f1176b.zip
HackStudio: View unstaged diffs in files with DiffViewer
-rw-r--r--DevTools/HackStudio/CMakeLists.txt3
-rw-r--r--DevTools/HackStudio/Git/GitWidget.cpp32
-rw-r--r--DevTools/HackStudio/Git/GitWidget.h6
-rw-r--r--DevTools/HackStudio/main.cpp15
4 files changed, 54 insertions, 2 deletions
diff --git a/DevTools/HackStudio/CMakeLists.txt b/DevTools/HackStudio/CMakeLists.txt
index 2f392cabff..2199e1b28c 100644
--- a/DevTools/HackStudio/CMakeLists.txt
+++ b/DevTools/HackStudio/CMakeLists.txt
@@ -1,5 +1,6 @@
set(SOURCES
CursorTool.cpp
+ Git/DiffViewer.cpp
Git/GitWidget.cpp
Git/GitFilesModel.cpp
Git/GitRepo.cpp
@@ -29,4 +30,4 @@ set(SOURCES
)
serenity_bin(HackStudio)
-target_link_libraries(HackStudio LibWeb LibMarkdown LibGUI LibGfx LibCore LibVT LibDebug LibX86)
+target_link_libraries(HackStudio LibWeb LibMarkdown LibGUI LibGfx LibCore LibVT LibDebug LibX86 LibDiff)
diff --git a/DevTools/HackStudio/Git/GitWidget.cpp b/DevTools/HackStudio/Git/GitWidget.cpp
index e8dfb3b4a4..448ec755e9 100644
--- a/DevTools/HackStudio/Git/GitWidget.cpp
+++ b/DevTools/HackStudio/Git/GitWidget.cpp
@@ -27,6 +27,8 @@
#include "GitWidget.h"
#include "GitFilesModel.h"
#include <AK/LogStream.h>
+#include <LibCore/File.h>
+#include <LibDiff/Format.h>
#include <LibGUI/Application.h>
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Button.h>
@@ -36,6 +38,7 @@
#include <LibGUI/Model.h>
#include <LibGUI/Painter.h>
#include <LibGfx/Bitmap.h>
+#include <stdio.h>
namespace HackStudio {
@@ -64,6 +67,10 @@ GitWidget::GitWidget(const LexicalPath& repo_root)
m_unstaged_files = unstaged.add<GitFilesView>(
[this](const auto& file) { stage_file(file); },
Gfx::Bitmap::load_from_file("/res/icons/16x16/plus.png").release_nonnull());
+ m_unstaged_files->on_selection = [this](const GUI::ModelIndex& index) {
+ const auto& selected = index.data().as_string();
+ show_diff(LexicalPath(selected));
+ };
auto& staged = add<GUI::Widget>();
staged.set_layout<GUI::VerticalBoxLayout>();
@@ -135,4 +142,29 @@ void GitWidget::commit()
m_git_repo->commit(message);
refresh();
}
+
+void GitWidget::set_view_diff_callback(ViewDiffCallback callback)
+{
+ m_view_diff_callback = move(callback);
+}
+
+void GitWidget::show_diff(const LexicalPath& file_path)
+{
+ if (!m_git_repo->is_tracked(file_path)) {
+ auto file = Core::File::construct(file_path.string());
+ if (!file->open(Core::IODevice::ReadOnly)) {
+ perror("open");
+ ASSERT_NOT_REACHED();
+ }
+
+ auto content = file->read_all();
+ String content_string((char*)content.data(), content.size());
+ m_view_diff_callback("", Diff::generate_only_additions(content_string));
+ return;
+ }
+ const auto& original_content = m_git_repo->original_file_content(file_path);
+ const auto& diff = m_git_repo->unstaged_diff(file_path);
+ ASSERT(original_content.has_value() && diff.has_value());
+ m_view_diff_callback(original_content.value(), diff.value());
+}
}
diff --git a/DevTools/HackStudio/Git/GitWidget.h b/DevTools/HackStudio/Git/GitWidget.h
index 417af9ebbb..6cc8ae8bbd 100644
--- a/DevTools/HackStudio/Git/GitWidget.h
+++ b/DevTools/HackStudio/Git/GitWidget.h
@@ -28,17 +28,21 @@
#include "GitFilesView.h"
#include "GitRepo.h"
+#include <AK/Function.h>
#include <LibGUI/Forward.h>
#include <LibGUI/Widget.h>
namespace HackStudio {
+typedef Function<void(const String& original_content, const String& diff)> ViewDiffCallback;
+
class GitWidget final : public GUI::Widget {
C_OBJECT(GitWidget)
public:
virtual ~GitWidget() override {}
void refresh();
+ void set_view_diff_callback(ViewDiffCallback callback);
private:
explicit GitWidget(const LexicalPath& repo_root);
@@ -46,11 +50,13 @@ private:
void stage_file(const LexicalPath&);
void unstage_file(const LexicalPath&);
void commit();
+ void show_diff(const LexicalPath&);
LexicalPath m_repo_root;
RefPtr<GitFilesView> m_unstaged_files;
RefPtr<GitFilesView> m_staged_files;
RefPtr<GitRepo> m_git_repo;
+ ViewDiffCallback m_view_diff_callback;
};
}
diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp
index 045b058127..0866c69c9f 100644
--- a/DevTools/HackStudio/main.cpp
+++ b/DevTools/HackStudio/main.cpp
@@ -33,6 +33,7 @@
#include "FindInFilesWidget.h"
#include "FormEditorWidget.h"
#include "FormWidget.h"
+#include "Git/DiffViewer.h"
#include "Git/GitWidget.h"
#include "HackStudio.h"
#include "Locator.h"
@@ -99,6 +100,7 @@ RefPtr<GUI::StackWidget> g_right_hand_stack;
RefPtr<GUI::Splitter> g_editors_splitter;
RefPtr<GUI::Widget> g_form_inner_container;
RefPtr<FormEditorWidget> g_form_editor_widget;
+RefPtr<DiffViewer> g_diff_viewer;
static RefPtr<GUI::TabWidget> s_action_tab_widget;
@@ -118,6 +120,7 @@ static void add_new_editor(GUI::Widget& parent)
enum class EditMode {
Text,
Form,
+ Diff,
};
static void set_edit_mode(EditMode mode)
@@ -126,7 +129,12 @@ static void set_edit_mode(EditMode mode)
g_right_hand_stack->set_active_widget(g_editors_splitter);
} else if (mode == EditMode::Form) {
g_right_hand_stack->set_active_widget(g_form_inner_container);
+ } else if (mode == EditMode::Diff) {
+ g_right_hand_stack->set_active_widget(g_diff_viewer);
+ } else {
+ ASSERT_NOT_REACHED();
}
+ g_right_hand_stack->active_widget()->update();
}
static void build(TerminalWrapper&);
@@ -416,6 +424,8 @@ static int main_impl(int argc, char** argv)
add_properties_pane("Form widget tree:", form_widget_tree_view);
add_properties_pane("Widget properties:", GUI::TableView::construct());
+ g_diff_viewer = g_right_hand_stack->add<DiffViewer>();
+
g_editors_splitter = g_right_hand_stack->add<GUI::VerticalSplitter>();
g_editors_splitter->layout()->set_margins({ 0, 3, 0, 0 });
add_new_editor(*g_editors_splitter);
@@ -563,7 +573,10 @@ static int main_impl(int argc, char** argv)
auto& debug_info_widget = s_action_tab_widget->add_tab<DebugInfoWidget>("Debug");
auto& disassembly_widget = s_action_tab_widget->add_tab<DisassemblyWidget>("Disassembly");
auto& git_widget = s_action_tab_widget->add_tab<GitWidget>("Git", LexicalPath(g_project->root_directory()));
- (void)git_widget;
+ git_widget.set_view_diff_callback([](const auto& original_content, const auto& diff) {
+ g_diff_viewer->set_content(original_content, diff);
+ set_edit_mode(EditMode::Diff);
+ });
auto& locator = widget.add<Locator>();