#pragma once #include "lumacs/buffer.hpp" #include "lumacs/window.hpp" // #include "lumacs/kill_ring.hpp" // Now using KillRingManager #include "lumacs/theme.hpp" #include "lumacs/config.hpp" #include "lumacs/keybinding.hpp" #include "lumacs/modeline.hpp" #include "lumacs/minibuffer_manager.hpp" // Added include #include "lumacs/completion_system.hpp" // Added include #include "lumacs/ui_interface.hpp" // Include for EditorEvent #include "lumacs/i_command_target.hpp" // New include for ICommandTarget #include "lumacs/plugin_manager.hpp" // New include for PluginManager #include "lumacs/buffer_manager.hpp" // New include for BufferManager #include "lumacs/window_manager.hpp" // New include for WindowManager #include "lumacs/kill_ring_manager.hpp" // New include for KillRingManager #include "lumacs/register_manager.hpp" // New include for RegisterManager #include "lumacs/macro_manager.hpp" // New include for MacroManager #include "lumacs/rectangle_manager.hpp" // New include for RectangleManager #include #include #include #include #include #include // For std::chrono::steady_clock #include // For std::optional namespace lumacs { class LuaApi; // Forward declaration class CommandSystem; // Forward declaration class PluginManager; // Forward declaration // class WindowManager; // Forward declaration already in window_manager.hpp /// @brief Core logic of the Lumacs editor, independent of the UI framework. /// /// This class acts as the central controller/facade for the editor's logic. /// It manages buffers, windows, the kill ring, registers, macros, configuration, /// and subsystems like the command system and Lua API. /// It emits events to notify the UI (IEditorView) of state changes. class EditorCore : public ICommandTarget { // Inherit from ICommandTarget public: EditorCore(); ~EditorCore(); // Disable copy, allow move EditorCore(const EditorCore&) = delete; EditorCore& operator=(const EditorCore&) = delete; EditorCore(EditorCore&&) noexcept = default; // Should now be fine due to unique_ptr members EditorCore& operator=(EditorCore&&) noexcept = default; // Should now be fine due to unique_ptr members // === ICommandTarget Implementation === // These methods implement the ICommandTarget interface. // Buffer Management (Delegated to BufferManager) [[nodiscard]] const Buffer& buffer() const noexcept override { return buffer_manager_->active_buffer()->get(); } [[nodiscard]] Buffer& buffer() noexcept override { return buffer_manager_->active_buffer()->get(); } bool load_file(const std::filesystem::path& path) override { return buffer_manager_->load_file(path); } void new_buffer(std::string name = "*scratch*") override { buffer_manager_->new_buffer(std::move(name)); } [[nodiscard]] std::vector get_buffer_names() const override { return buffer_manager_->get_buffer_names(); } [[nodiscard]] std::shared_ptr get_buffer_by_name(const std::string& name) override { return buffer_manager_->get_buffer_by_name(name); } bool switch_buffer_in_window(const std::string& name) override { return buffer_manager_->switch_buffer_in_window(name); } bool close_buffer(const std::string& name) override { return buffer_manager_->close_buffer(name); } // Window Management (Delegated to WindowManager) [[nodiscard]] std::shared_ptr active_window() const override { return window_manager_->active_window(); } bool set_active_window(std::shared_ptr window) override { return window_manager_->set_active_window(window); } void split_horizontally() override { window_manager_->split_horizontally(); } void split_vertically() override { window_manager_->split_vertically(); } void close_active_window() override { window_manager_->close_active_window(); } void next_window() override { window_manager_->next_window(); } // Cursor Management [[nodiscard]] Position cursor() const noexcept override; void set_cursor(Position pos) override; // Basic Editing void move_up() override; void move_down() override; void move_left() override; void move_right() override; void move_to_line_start() override; void move_to_line_end() override; void move_forward_word() override; void move_backward_word() override; void page_up() override; void page_down() override; void goto_beginning() override; void goto_end() override; void goto_line(size_t line) override; void kill_line() override; void kill_region() override; void copy_region_as_kill() override; void yank() override; void yank_pop() override; void kill_word() override; void backward_kill_word() override; // Message Display void set_message(std::string msg) override; // Quit void request_quit() override; // Configuration Config& config() override { return config_; } const Config& config() const override { return config_; } // Theme Management ThemeManager& theme_manager() override { return theme_manager_; } const ThemeManager& theme_manager() const override { return theme_manager_; } // === Original EditorCore methods not part of ICommandTarget === /// @brief Get the last set message. const std::string& last_message() const { return last_message_; } /// @brief Check if a message is set and if its display time has expired. /// Clears the message if expired. void check_and_clear_message(); // === Actions === // These methods trigger specific input modes in the UI. void enter_command_mode(); void enter_buffer_switch_mode(); void enter_kill_buffer_mode(); void enter_find_file_mode(); void enter_theme_selection_mode(); void enter_isearch_mode(); void enter_isearch_backward_mode(); /// @brief Get detailed information about all buffers. [[nodiscard]] std::vector get_all_buffer_info() const { return buffer_manager_->get_all_buffer_info(); } /// @brief Get the root node of the window layout tree. std::shared_ptr root_layout() const { return window_manager_->root_layout(); } // === Viewport Management (Proxies to active window) === const Viewport& viewport() const noexcept; void set_viewport_size(int width, int height); void adjust_scroll(); std::pair visible_line_range() const; // === Event Callbacks === using EventCallback = std::function; /// @brief Register a callback to be notified of editor events. void on_event(EventCallback callback) { event_callbacks_.push_back(std::move(callback)); } /// @brief Clear all registered event callbacks. void clear_event_callbacks() { event_callbacks_.clear(); } // === Undo/Redo === bool undo(); bool redo(); bool can_undo() const; bool can_redo() const; // === Kill Ring === // Delegated to KillRingManager void kill_line() override; void kill_region() override; void copy_region_as_kill() override; void yank() override; void yank_pop() override; void kill_word() override; void backward_kill_word() override; /// @brief Access the global Kill Ring (clipboard history). [[nodiscard]] KillRingManager& kill_ring_manager() noexcept { return *kill_ring_manager_; } [[nodiscard]] const KillRingManager& kill_ring_manager() const noexcept { return *kill_ring_manager_; } // === Registers === // Delegated to RegisterManager void copy_to_register(char register_name, const std::string& text) override; bool insert_register(char register_name) override; void copy_region_to_register(char register_name) override; bool yank_from_register(char register_name) override; /// @brief Access the global Register Manager. [[nodiscard]] RegisterManager& register_manager() noexcept { return *register_manager_; } [[nodiscard]] const RegisterManager& register_manager() const noexcept { return *register_manager_; } // === Keyboard Macros === // Delegated to MacroManager void start_kbd_macro() override; void end_kbd_macro_or_call() override; void record_key_sequence(const std::string& key_sequence) override; [[nodiscard]] bool is_recording_macro() const noexcept override { return macro_manager_->is_recording_macro(); } /// @brief Access the global Macro Manager. [[nodiscard]] MacroManager& macro_manager() noexcept { return *macro_manager_; } [[nodiscard]] const MacroManager& macro_manager() const noexcept { return *macro_manager_; } // === Rectangles === // Delegated to RectangleManager void kill_rectangle() override; void yank_rectangle() override; void string_rectangle(const std::string& text) override; /// @brief Access the global Rectangle Manager. [[nodiscard]] RectangleManager& rectangle_manager() noexcept { return *rectangle_manager_; } [[nodiscard]] const RectangleManager& rectangle_manager() const noexcept { return *rectangle_manager_; } // === Key Binding System === [[nodiscard]] KeyBindingManager& keybinding_manager() noexcept { return *keybinding_manager_; } [[nodiscard]] const KeyBindingManager& keybinding_manager() const noexcept { return *keybinding_manager_; } // === Lua API === [[nodiscard]] LuaApi* lua_api() const { return lua_api_.get(); } // === Command System === [[nodiscard]] CommandSystem& command_system() noexcept { return *command_system_; } [[nodiscard]] const CommandSystem& command_system() const noexcept { return *command_system_; } // === Modeline Manager === [[nodiscard]] ModelineManager& modeline_manager() noexcept { return modeline_manager_; } [[nodiscard]] const ModelineManager& modeline_manager() const noexcept { return modeline_manager_; } // === Minibuffer Manager === [[nodiscard]] MinibufferManager& minibuffer_manager() noexcept { return *minibuffer_manager_; } [[nodiscard]] const MinibufferManager& minibuffer_manager() const noexcept { return *minibuffer_manager_; } // === Completion System === [[nodiscard]] CompletionSystem& completion_system() noexcept { return *completion_system_; } [[nodiscard]] const CompletionSystem& completion_system() const noexcept { return *completion_system_; } // === Plugin Manager === [[nodiscard]] PluginManager& plugin_manager() noexcept { return *plugin_manager_; } [[nodiscard]] const PluginManager& plugin_manager() const noexcept { return *plugin_manager_; } // === Buffer Manager === [[nodiscard]] BufferManager& buffer_manager() noexcept { return *buffer_manager_; } [[nodiscard]] const BufferManager& buffer_manager() const noexcept { return *buffer_manager_; } /// @brief Helper to collect all windows in traversal order. /// @param node The current node to traverse. /// @param windows The vector to populate with windows. void collect_windows(LayoutNode* node, std::vector>& windows) { window_manager_->collect_windows(node, windows); } private: // Word movement helpers Position calculate_forward_word_pos(Position start_pos); Position calculate_backward_word_pos(Position start_pos); std::string last_message_; std::optional message_clear_time_; std::vector event_callbacks_; // Last yank position (for yank-pop) std::optional last_yank_start_; std::optional last_yank_end_; // Subsystems ThemeManager theme_manager_; Config config_; std::unique_ptr command_system_; // Must be declared before KeyBindingManager std::unique_ptr keybinding_manager_; // Changed to unique_ptr std::unique_ptr lua_api_; ModelineManager modeline_manager_; std::unique_ptr completion_system_; // Added missing member std::unique_ptr minibuffer_manager_; // Added missing member std::unique_ptr plugin_manager_; // Added missing member std::unique_ptr buffer_manager_; // New: BufferManager std::unique_ptr window_manager_; // New: WindowManager std::unique_ptr kill_ring_manager_; // New: KillRingManager std::unique_ptr register_manager_; // New: RegisterManager std::unique_ptr macro_manager_; // New: MacroManager std::unique_ptr rectangle_manager_; // New: RectangleManager void emit_event(EditorEvent event); }; } // namespace lumacs