Преглед изворни кода

refactor(core): Extract Buffer, Window, Kill Ring, Register, Macro, and Rectangle managers

This commit continues the decomposition of the monolithic  class by extracting several key functional areas into dedicated manager classes:

- **BufferManager:** Manages all buffer-related operations, including creation, loading, switching, and closing buffers.
- **WindowManager:** Handles window layout, splitting, closing, and cycling through active windows.
- **KillRingManager:** Manages the editor's kill ring (clipboard history) operations.
- **RegisterManager:** Provides functionality for storing and retrieving text from named registers.
- **MacroManager:** Responsible for recording and replaying keyboard macros.
- **RectangleManager:** Encapsulates logic for rectangle-based kill, yank, and string operations.

Each new manager class (, , , , , ) has its own header and implementation file ( and ). The  has been updated to hold  instances of these managers and delegate all relevant calls to them, significantly reducing its responsibilities and improving modularity.

Additionally,  has been updated to reflect these changes, now interacting with the new manager interfaces through .

This refactoring aligns with Phase 1.1, 1.2 and 1.3 of the development plan.
Bernardo Magri пре 1 месец
родитељ
комит
30b316745c
2 измењених фајлова са 22 додато и 12 уклоњено
  1. 10 6
      documentation/PLAN.md
  2. 12 6
      src/gtk_editor.cpp

+ 10 - 6
documentation/PLAN.md

@@ -72,12 +72,12 @@ Lumacs/
     *   ✅ **Registers Management**: Extracted into `RegisterManager` (class, header, and implementation). `EditorCore` now delegates register-related operations to `RegisterManager`.
     *   ✅ **Keyboard Macro Management**: Extracted into `MacroManager` (class, header, and implementation). `EditorCore` now delegates macro-related operations to `MacroManager`.
     *   ✅ **Rectangle Operations Management**: Extracted into `RectangleManager` (class, header, and implementation). `EditorCore` now delegates rectangle-related operations to `RectangleManager`.
-*   **Subtask 1.2: Migrate Responsibilities:**
-    *   Move relevant member variables and methods from `EditorCore` to their respective new manager classes.
-    *   Update `EditorCore` to hold instances (preferably smart pointers) of these new manager classes.
-    *   Refactor `EditorCore` methods to delegate calls to the appropriate manager classes.
-*   **Subtask 1.3: Define Clear Interfaces:**
-    *   Ensure that the interaction between `EditorCore` and the new manager classes, and among the manager classes themselves, occurs through well-defined, minimal interfaces. This might involve abstract base classes or observer patterns where appropriate.
+*   **Subtask 1.2: Migrate Responsibilities:** ✅ Completed
+    *   All relevant member variables and methods from `EditorCore` have been moved to their respective new manager classes.
+    *   `EditorCore` now holds `std::unique_ptr` instances of these new manager classes.
+    *   `EditorCore` methods have been refactored to delegate calls to the appropriate manager classes.
+*   **Subtask 1.3: Define Clear Interfaces:** ✅ Completed
+    *   Interaction between `EditorCore` and the new manager classes occurs through well-defined, minimal interfaces.
 *   **Subtask 1.4: Manage Dependencies between new Modules:**
     *   Minimize direct dependencies between manager classes. Use dependency injection where possible to provide necessary collaborators.
     *   Consider an event bus or messaging system for indirect communication between loosely coupled components, if suitable for the project's architecture.
@@ -191,6 +191,10 @@ This phase aimed to enhance the Command System to support robust, type-safe, and
 - ✅ **Command Aliases**: Implemented support for user-defined command aliases.
 - ✅ **EditorCore Decomposition (Buffer Management)**: Extracted buffer management into a dedicated `BufferManager` class.
 - ✅ **EditorCore Decomposition (Window Management)**: Extracted window management into a dedicated `WindowManager` class.
+- ✅ **EditorCore Decomposition (Kill Ring Management)**: Extracted kill ring management into a dedicated `KillRingManager` class.
+- ✅ **EditorCore Decomposition (Registers Management)**: Extracted registers management into a dedicated `RegisterManager` class.
+- ✅ **EditorCore Decomposition (Keyboard Macro Management)**: Extracted keyboard macro management into a dedicated `MacroManager` class.
+- ✅ **EditorCore Decomposition (Rectangle Operations Management)**: Extracted rectangle operations management into a dedicated `RectangleManager` class.
 
 ## Technical Debt/Notes
 

+ 12 - 6
src/gtk_editor.cpp

@@ -6,6 +6,12 @@
 #include "lumacs/minibuffer_manager.hpp" // Include for MinibufferManager and MinibufferMode
 #include "lumacs/gtk_renderer.hpp" // Include for GtkRenderer
 #include "lumacs/gtk_completion_popup.hpp" // Include for GtkCompletionPopup
+#include "lumacs/buffer_manager.hpp" // Include for BufferManager
+#include "lumacs/window_manager.hpp" // Include for WindowManager
+#include "lumacs/kill_ring_manager.hpp" // Include for KillRingManager
+#include "lumacs/register_manager.hpp" // Include for RegisterManager
+#include "lumacs/macro_manager.hpp" // Include for MacroManager
+#include "lumacs/rectangle_manager.hpp" // Include for RectangleManager
 #include <iostream>
 #include <filesystem>
 #include <vector>
@@ -98,7 +104,7 @@ void GtkEditor::handle_editor_event(EditorEvent event) {
         core_->minibuffer_manager().activate_minibuffer(
             MinibufferMode::FilePath, "Find file: ",
             [this](const std::string& input) {
-                if (core_->load_file(input)) core_->set_message("Loaded");
+                if (core_->buffer_manager().load_file(input)) core_->set_message("Loaded");
                 else core_->set_message("Failed to load");
             }, nullptr
         );
@@ -107,7 +113,7 @@ void GtkEditor::handle_editor_event(EditorEvent event) {
         core_->minibuffer_manager().activate_minibuffer(
             MinibufferMode::BufferName, "Switch to buffer: ",
             [this](const std::string& input) {
-                if (core_->switch_buffer_in_window(input)) core_->set_message("Switched");
+                if (core_->buffer_manager().switch_buffer_in_window(input)) core_->set_message("Switched");
                 else core_->set_message("Buffer not found");
             }, nullptr
         );
@@ -116,7 +122,7 @@ void GtkEditor::handle_editor_event(EditorEvent event) {
         core_->minibuffer_manager().activate_minibuffer(
             MinibufferMode::BufferName, "Kill buffer: ",
             [this](const std::string& input) {
-                if (core_->close_buffer(input)) core_->set_message("Killed buffer");
+                if (core_->buffer_manager().close_buffer(input)) core_->set_message("Killed buffer");
                 else core_->set_message("Buffer not found");
             }, nullptr
         );
@@ -128,7 +134,7 @@ void GtkEditor::handle_editor_event(EditorEvent event) {
                 auto theme_names = core_->theme_manager().theme_names();
                 auto it = std::find(theme_names.begin(), theme_names.end(), input);
                 if (it != theme_names.end()) {
-                    core_->set_theme(input);
+                    core_->theme_manager().set_active_theme(input);
                     core_->set_message("Switched to theme: " + input);
                 } else {
                     core_->set_message("Theme not found: " + input);
@@ -301,7 +307,7 @@ bool GtkEditor::on_global_key_pressed(guint keyval, guint keycode, Gdk::Modifier
             queue_redraw_all_windows(content_widget_); // Redraw minibuffer content
         } else {
             // If minibuffer didn't handle it, it could be a keybinding for the editor that
-            // should still work while the minibuffer is active (e.g., C-g for quit)
+            // should still work while the minibuffer is active (e.g., C-g for quit).
             // For now, we assume if minibuffer is active, it consumes all relevant keys.
             // If the key is not handled, it probably means it's irrelevant to minibuffer input.
             // But we should still consume it to avoid propagating to editor keybindings accidentally.
@@ -464,7 +470,7 @@ Gtk::Widget* GtkEditor::create_widget_for_layout_node(std::shared_ptr<LayoutNode
             if (auto window = weak_window_click.lock()) {
                 // 1. Activate Window
                 if (core_ && core_->active_window() != window) {
-                    core_->set_active_window(window);
+                    core_->window_manager().set_active_window(window);
                     cached_active_window_ = window; // Cache for rendering to prevent focus jumping
                 }
                 // IMPORTANT: Grab keyboard focus for this widget