#pragma once #include #include #include #include "lumacs/buffer.hpp" // For Position and Range namespace lumacs { /// @brief Implements an Emacs-like kill ring (clipboard history). /// The kill ring stores killed (cut) text in a circular buffer. /// Also tracks yank position state for yank-pop functionality. class KillRingManager { public: explicit KillRingManager(size_t max_size = 60); /// @brief Pushes text onto the kill ring. If the last entry was also a kill /// (not a yank), it appends to that entry. Otherwise, it creates a new entry. /// @param text The text to push. void push(const std::string& text); /// @brief Retrieves the current (most recently pushed) entry in the kill ring. /// @return The current entry. Returns empty string if ring is empty. [[nodiscard]] std::string current() const; /// @brief Rotates the kill ring and retrieves the previous entry. /// Used for `yank-pop`. /// @return The previous entry. Returns empty string if ring is empty. [[nodiscard]] std::string previous(); /// @brief Checks if the kill ring is empty. [[nodiscard]] bool empty() const { return ring_.empty(); } /// @brief Clears the kill ring. void clear() { ring_.clear(); } // === Yank State Tracking === /// @brief Record the start and end positions of a yank operation. /// @param start The position where the yank started. /// @param end The position where the yank ended. void set_yank_range(Position start, Position end); /// @brief Get the yank start position if a yank was performed. [[nodiscard]] std::optional yank_start() const { return last_yank_start_; } /// @brief Get the yank end position if a yank was performed. [[nodiscard]] std::optional yank_end() const { return last_yank_end_; } /// @brief Update just the yank end position (after yank-pop replaces text). void set_yank_end(Position end) { last_yank_end_ = end; } /// @brief Check if a yank operation has been recorded. [[nodiscard]] bool has_yank_state() const { return last_yank_start_.has_value() && last_yank_end_.has_value(); } /// @brief Clear the yank state (e.g., after a non-yank command). void clear_yank_state() { last_yank_start_.reset(); last_yank_end_.reset(); } private: std::deque ring_; size_t max_size_; bool last_action_was_kill_ = false; // Tracks if the last push was a kill or append // Yank position tracking (moved from EditorCore) std::optional last_yank_start_; std::optional last_yank_end_; }; } // namespace lumacs