#pragma once #include "lumacs/buffer.hpp" #include "lumacs/window.hpp" #include "lumacs/theme.hpp" #include "lumacs/config.hpp" #include "lumacs/keybinding.hpp" #include "lumacs/modeline.hpp" #include "lumacs/minibuffer_manager.hpp" #include "lumacs/completion_system.hpp" #include "lumacs/ui_interface.hpp" #include "lumacs/i_command_target.hpp" #include "lumacs/plugin_manager.hpp" #include "lumacs/buffer_manager.hpp" #include "lumacs/window_manager.hpp" #include "lumacs/kill_ring_manager.hpp" #include "lumacs/register_manager.hpp" #include "lumacs/macro_manager.hpp" #include "lumacs/rectangle_manager.hpp" #include "lumacs/layout_node.hpp" #include "lumacs/i_editor_notifier.hpp" #include "lumacs/i_window_manager.hpp" #include #include namespace lumacs { class LuaApi; class CommandSystem; class PluginManager; class EditorCore : public ICommandTarget, public IEditorNotifier, public IWindowManager { public: EditorCore(); ~EditorCore(); EditorCore(const EditorCore&) = delete; EditorCore& operator=(const EditorCore&) = delete; EditorCore(EditorCore&&) noexcept = default; EditorCore& operator=(EditorCore&&) noexcept = default; // === ICommandTarget Implementation === // Buffer Management (Delegated to BufferManager) [[nodiscard]] const Buffer& buffer() const noexcept override { return *buffer_manager_->active_buffer(); } [[nodiscard]] Buffer& buffer() noexcept override { return *buffer_manager_->active_buffer(); } 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(); } // IWindowManager implementation (helpers) void collect_windows(LayoutNode* node, std::vector>& windows) override; std::shared_ptr root_layout() const override { return window_manager_->root_layout(); } [[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; // 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; // Message Display void set_message(std::string msg, MessageSeverity severity = MessageSeverity::Info) 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_; } void set_theme(const std::string& theme_name); // Sets theme and emits event // 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; // 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; // Rectangles (Delegated to RectangleManager) void kill_rectangle() override; void yank_rectangle() override; void string_rectangle(const std::string& text) override; // === Original EditorCore methods not part of ICommandTarget === const std::string& last_message() const { return last_message_; } MessageSeverity last_message_severity() const { return last_message_severity_; } void check_and_clear_message(); // Message history navigation (M-p/M-n) void previous_message(); // Show previous message from history void next_message(); // Show next message in history void exit_message_history(); // Exit history browsing mode [[nodiscard]] bool is_browsing_message_history() const { return message_history_index_.has_value(); } [[nodiscard]] size_t message_history_size() const { return message_history_.size(); } 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(); [[nodiscard]] std::vector get_all_buffer_info() const { return buffer_manager_->get_all_buffer_info(); } const Viewport& viewport() const noexcept; void set_viewport_size(int width, int height); void adjust_scroll(); std::pair visible_line_range() const; using EventCallback = std::function; void on_event(EventCallback callback) { event_callbacks_.push_back(std::move(callback)); } void clear_event_callbacks() { event_callbacks_.clear(); } bool undo(); bool redo(); bool can_undo() const; bool can_redo() const; [[nodiscard]] KillRingManager& kill_ring_manager() noexcept { return *kill_ring_manager_; } [[nodiscard]] const KillRingManager& kill_ring_manager() const noexcept { return *kill_ring_manager_; } [[nodiscard]] RegisterManager& register_manager() noexcept { return *register_manager_; } [[nodiscard]] const RegisterManager& register_manager() const noexcept { return *register_manager_; } [[nodiscard]] MacroManager& macro_manager() noexcept { return *macro_manager_; } [[nodiscard]] const MacroManager& macro_manager() const noexcept { return *macro_manager_; } [[nodiscard]] RectangleManager& rectangle_manager() noexcept { return *rectangle_manager_; } [[nodiscard]] const RectangleManager& rectangle_manager() const noexcept { return *rectangle_manager_; } [[nodiscard]] KeyBindingManager& keybinding_manager() noexcept { return *keybinding_manager_; } [[nodiscard]] const KeyBindingManager& keybinding_manager() const noexcept { return *keybinding_manager_; } [[nodiscard]] LuaApi* lua_api() const { return lua_api_.get(); } [[nodiscard]] CommandSystem& command_system() noexcept { return *command_system_; } [[nodiscard]] const CommandSystem& command_system() const noexcept { return *command_system_; } [[nodiscard]] CompletionSystem& completion_system() noexcept { return *completion_system_; } [[nodiscard]] const CompletionSystem& completion_system() const noexcept { return *completion_system_; } [[nodiscard]] ModelineManager& modeline_manager() noexcept { return modeline_manager_member_; } [[nodiscard]] const ModelineManager& modeline_manager() const noexcept { return modeline_manager_member_; } [[nodiscard]] MinibufferManager& minibuffer_manager() noexcept { return *minibuffer_manager_; } [[nodiscard]] const MinibufferManager& minibuffer_manager() const noexcept { return *minibuffer_manager_; } [[nodiscard]] PluginManager& plugin_manager() noexcept { return *plugin_manager_; } [[nodiscard]] const PluginManager& plugin_manager() const noexcept { return *plugin_manager_; } [[nodiscard]] BufferManager& buffer_manager() noexcept { return *buffer_manager_; } [[nodiscard]] const BufferManager& buffer_manager() const noexcept { return *buffer_manager_; } [[nodiscard]] WindowManager& window_manager() noexcept { return *window_manager_; } [[nodiscard]] const WindowManager& window_manager() const noexcept { return *window_manager_; } /// @brief Set extended echo area lines (for packages like which-key) /// These lines appear above the main minibuffer line void set_echo_area_lines(const std::vector& lines); /// @brief Clear extended echo area lines void clear_echo_area_lines(); /// @brief Get extended echo area lines [[nodiscard]] const std::vector& echo_area_lines() const { return echo_area_lines_; } /// @brief Check idle state and run idle hooks /// Called by UI frontends during idle time void check_idle_hooks(); /// @brief Notify that user input occurred (resets idle timer) void notify_user_activity(); /// @brief Get time since last user activity (milliseconds) [[nodiscard]] int64_t idle_time_ms() const; void emit_event(EditorEvent event) override; private: Position calculate_forward_word_pos(Position start_pos); Position calculate_backward_word_pos(Position start_pos); std::string last_message_; MessageSeverity last_message_severity_ = MessageSeverity::Info; std::optional message_clear_time_; std::vector event_callbacks_; // Message history for M-p/M-n navigation static constexpr size_t MAX_MESSAGE_HISTORY = 50; std::vector message_history_; std::optional message_history_index_; // nullopt = not browsing history // Subsystems - Order matters for initialization based on dependencies // Declared in dependency order ThemeManager theme_manager_; // No dependencies Config config_; // No dependencies ModelineManager modeline_manager_member_; // Direct member, declared here std::unique_ptr lua_api_; // Depends on nothing std::unique_ptr completion_system_; // Depends on EditorCore (this) std::unique_ptr minibuffer_manager_; // Depends on EditorCore, LuaApi, CompletionSystem std::unique_ptr command_system_; // Depends on EditorCore, MinibufferManager std::unique_ptr keybinding_manager_; // Depends on CommandSystem std::unique_ptr plugin_manager_; // Depends on EditorCore, LuaApi std::unique_ptr buffer_manager_; // Depends on EditorCore std::unique_ptr window_manager_; // Depends on EditorCore, BufferManager std::unique_ptr kill_ring_manager_; // No dependencies std::unique_ptr register_manager_; // No dependencies std::unique_ptr macro_manager_; // Depends on EditorCore std::unique_ptr rectangle_manager_; // Depends on EditorCore // Extended echo area for packages like which-key std::vector echo_area_lines_; // Idle tracking for Lua hooks std::chrono::steady_clock::time_point last_activity_time_; }; } // namespace lumacs