/// /// \file Buffer.h /// \author kyle /// \date 2023-10-10 /// \brief A buffer is the basic document type. /// #ifndef KEPP_FRAME_H #define KEPP_FRAME_H #include #include #include "Defs.h" #include "File.h" #include "Cursor.h" typedef std::vector> BufferContents; /// A Buffer is the atom of text editing. It represents a single document, /// whether a memory-only buffer or a file-backed buffer. /// /// \details /// /// There are currently two main types of Buffers: file-backed and virtual. /// A virtual buffer describes any buffer that isn't backed by a file. /// /// A virtual buffer can be promoted to a file frame, but a file buffer /// cannot be demoted to a virtual buffer. class Buffer { public: enum class FileStatus : uint8_t { /// The file operation succeeded correctly. FileStatusOK = 0, /// The file can't be written to because it is marked /// read-only. This refers to a buffer being marked as /// read-only, not to whether the underlying file is /// actually read-only. FileStatusReadOnly = 1, /// There was an I/O error trying to write to the file. FileStatusIOFailed = 2, /// The Buffer couldn't be flushed because it is a virtual /// buffer. If the user explicitly tried to save the buffer, /// they should be prompted for a path. FileStatusVirtual = 3, /// The underlying file doesn't have the right permissions; /// for example, it's not writeable if the user is trying to /// write the file. FileStatusInvalidPermissions = 4, /// The underlying file doesn't exist. FileStatusNonExistent = 5, }; static std::string FileStatusToString(FileStatus status); static bool StatusOK(FileStatus status) { return status == FileStatus::FileStatusOK; } /// The constructor with no arguments generates a new anonymous /// buffer. Buffer(); /// A single constructor generates a virtual buffer. Buffer(std::string fName); /// Instantiate a Buffer pointing to fPath. Buffer(std::string fName, std::string fPath); void Close(); /// Instantiate a buffer from a filesystem path. Buffer(std::filesystem::path fPath); std::string Name() const { return this->name; } bool IsVirtual() { return !this->file.has_value(); } Buffer::FileStatus Flush(OptString altPath); /// Refresh reads the contents of the file back into the /// buffer. /// /// \warning This does not care if the file is dirty or not - /// it WILL overwrite the contents of the buffer. /// /// \return A FileStatus indicating whether the read was successful. Buffer::FileStatus Refresh(); void ChangePath(std::string newPath); Cursor Cursor() { return this->cursor; } void MarkDirty(); bool IsDirty() { return this->dirty; } size_t Size(); private: void clearContents(); class Cursor cursor; bool dirty; std::string name; OptString path; OptFile file; BufferContents contents; }; #endif // KEPP_FRAME_H