|
|
@@ -0,0 +1,125 @@
|
|
|
+#pragma once
|
|
|
+
|
|
|
+#include <string>
|
|
|
+#include <vector>
|
|
|
+#include <optional>
|
|
|
+#include <filesystem>
|
|
|
+#include <memory>
|
|
|
+
|
|
|
+namespace lumacs {
|
|
|
+
|
|
|
+/// Represents a cursor position in a buffer
|
|
|
+struct Position {
|
|
|
+ size_t line;
|
|
|
+ size_t column;
|
|
|
+
|
|
|
+ auto operator<=>(const Position&) const = default;
|
|
|
+};
|
|
|
+
|
|
|
+/// Represents a range in the buffer
|
|
|
+struct Range {
|
|
|
+ Position start;
|
|
|
+ Position end;
|
|
|
+
|
|
|
+ auto operator<=>(const Range&) const = default;
|
|
|
+};
|
|
|
+
|
|
|
+/// A text buffer that manages the content of a file or scratch buffer
|
|
|
+class Buffer {
|
|
|
+public:
|
|
|
+ /// Create an empty buffer
|
|
|
+ Buffer();
|
|
|
+
|
|
|
+ /// Create a buffer with a name (for scratch buffers)
|
|
|
+ explicit Buffer(std::string name);
|
|
|
+
|
|
|
+ /// Create a buffer from a file
|
|
|
+ static std::optional<Buffer> from_file(const std::filesystem::path& path);
|
|
|
+
|
|
|
+ // Disable copy, allow move
|
|
|
+ Buffer(const Buffer&) = delete;
|
|
|
+ Buffer& operator=(const Buffer&) = delete;
|
|
|
+ Buffer(Buffer&&) noexcept = default;
|
|
|
+ Buffer& operator=(Buffer&&) noexcept = default;
|
|
|
+
|
|
|
+ ~Buffer() = default;
|
|
|
+
|
|
|
+ // === Content Access ===
|
|
|
+
|
|
|
+ /// Get the number of lines in the buffer
|
|
|
+ [[nodiscard]] size_t line_count() const noexcept;
|
|
|
+
|
|
|
+ /// Get a line by index (0-based)
|
|
|
+ [[nodiscard]] const std::string& line(size_t index) const;
|
|
|
+
|
|
|
+ /// Get all lines
|
|
|
+ [[nodiscard]] const std::vector<std::string>& lines() const noexcept;
|
|
|
+
|
|
|
+ /// Get the entire buffer content as a single string
|
|
|
+ [[nodiscard]] std::string content() const;
|
|
|
+
|
|
|
+ // === Modification ===
|
|
|
+
|
|
|
+ /// Insert text at a position
|
|
|
+ void insert(Position pos, std::string_view text);
|
|
|
+
|
|
|
+ /// Insert a character at a position
|
|
|
+ void insert_char(Position pos, char c);
|
|
|
+
|
|
|
+ /// Insert a newline at a position
|
|
|
+ void insert_newline(Position pos);
|
|
|
+
|
|
|
+ /// Delete a range of text
|
|
|
+ void erase(Range range);
|
|
|
+
|
|
|
+ /// Delete a character at a position (backspace)
|
|
|
+ void erase_char(Position pos);
|
|
|
+
|
|
|
+ /// Replace text in a range
|
|
|
+ void replace(Range range, std::string_view text);
|
|
|
+
|
|
|
+ /// Clear the entire buffer
|
|
|
+ void clear();
|
|
|
+
|
|
|
+ // === File Operations ===
|
|
|
+
|
|
|
+ /// Save the buffer to its associated file
|
|
|
+ bool save();
|
|
|
+
|
|
|
+ /// Save the buffer to a specific file
|
|
|
+ bool save_as(const std::filesystem::path& path);
|
|
|
+
|
|
|
+ /// Check if the buffer has been modified since last save
|
|
|
+ [[nodiscard]] bool is_modified() const noexcept;
|
|
|
+
|
|
|
+ /// Get the file path associated with this buffer (if any)
|
|
|
+ [[nodiscard]] std::optional<std::filesystem::path> file_path() const noexcept;
|
|
|
+
|
|
|
+ // === Buffer Properties ===
|
|
|
+
|
|
|
+ /// Get the buffer name
|
|
|
+ [[nodiscard]] const std::string& name() const noexcept;
|
|
|
+
|
|
|
+ /// Set the buffer name
|
|
|
+ void set_name(std::string name);
|
|
|
+
|
|
|
+ /// Check if position is valid
|
|
|
+ [[nodiscard]] bool is_valid_position(Position pos) const noexcept;
|
|
|
+
|
|
|
+ /// Clamp a position to valid bounds
|
|
|
+ [[nodiscard]] Position clamp_position(Position pos) const noexcept;
|
|
|
+
|
|
|
+private:
|
|
|
+ std::string name_;
|
|
|
+ std::vector<std::string> lines_;
|
|
|
+ std::optional<std::filesystem::path> file_path_;
|
|
|
+ bool modified_;
|
|
|
+
|
|
|
+ /// Ensure the buffer has at least one line
|
|
|
+ void ensure_min_lines();
|
|
|
+
|
|
|
+ /// Mark the buffer as modified
|
|
|
+ void mark_modified();
|
|
|
+};
|
|
|
+
|
|
|
+} // namespace lumacs
|