diff --git a/src/buffer.cc b/src/buffer.cc index b0e70748..22f4a794 100644 --- a/src/buffer.cc +++ b/src/buffer.cc @@ -158,6 +158,12 @@ bool Buffer::set_name(String name) return false; } +void Buffer::throw_if_read_only() const +{ + if (m_flags & Flags::ReadOnly) + throw runtime_error("Buffer is read-only"); +} + void Buffer::update_display_name() { if (m_flags & Flags::File) @@ -315,8 +321,10 @@ void Buffer::commit_undo_group() m_history_cursor = node; } -bool Buffer::undo(size_t count) noexcept +bool Buffer::undo(size_t count) { + throw_if_read_only(); + commit_undo_group(); if (not m_history_cursor->parent) @@ -333,8 +341,10 @@ bool Buffer::undo(size_t count) noexcept return true; } -bool Buffer::redo(size_t count) noexcept +bool Buffer::redo(size_t count) { + throw_if_read_only(); + if (not m_history_cursor->redo_child) return false; @@ -350,8 +360,10 @@ bool Buffer::redo(size_t count) noexcept return true; } -void Buffer::move_to(HistoryNode* history_node) noexcept +void Buffer::move_to(HistoryNode* history_node) { + throw_if_read_only(); + commit_undo_group(); auto find_lowest_common_parent = [](HistoryNode* a, HistoryNode* b) { @@ -419,7 +431,7 @@ Buffer::HistoryNode* Buffer::find_history_node(HistoryNode* node, const Func& fu return nullptr; } -bool Buffer::move_to(size_t history_id) noexcept +bool Buffer::move_to(size_t history_id) { auto* target_node = find_history_node(&m_history, [history_id](auto* node) { return node->id == history_id; }); @@ -548,6 +560,8 @@ void Buffer::apply_modification(const Modification& modification) BufferCoord Buffer::insert(BufferCoord pos, StringView content) { + throw_if_read_only(); + kak_assert(is_valid(pos)); if (content.empty()) return pos; @@ -568,6 +582,8 @@ BufferCoord Buffer::insert(BufferCoord pos, StringView content) BufferCoord Buffer::erase(BufferCoord begin, BufferCoord end) { + throw_if_read_only(); + kak_assert(is_valid(begin) and is_valid(end)); // do not erase last \n except if we erase from the start of a line, and normalize // end coord @@ -585,6 +601,8 @@ BufferCoord Buffer::erase(BufferCoord begin, BufferCoord end) BufferCoord Buffer::replace(BufferCoord begin, BufferCoord end, StringView content) { + throw_if_read_only(); + if (is_end(end) and not content.empty() and content.back() == '\n') { end = back_coord(); diff --git a/src/buffer.hh b/src/buffer.hh index 0eb6a4f4..d8f18015 100644 --- a/src/buffer.hh +++ b/src/buffer.hh @@ -139,9 +139,9 @@ public: void set_fs_timestamp(timespec ts); void commit_undo_group(); - bool undo(size_t count = 1) noexcept; - bool redo(size_t count = 1) noexcept; - bool move_to(size_t history_id) noexcept; + bool undo(size_t count = 1); + bool redo(size_t count = 1); + bool move_to(size_t history_id); size_t current_history_id() const noexcept; size_t next_history_id() const noexcept { return m_next_history_id; } @@ -218,6 +218,7 @@ public: void on_registered(); void on_unregistered(); + void throw_if_read_only() const; private: void on_option_changed(const Option& option) override; @@ -272,7 +273,7 @@ private: SafePtr m_last_save_history_cursor; UndoGroup m_current_undo_group; - void move_to(HistoryNode* history_node) noexcept; + void move_to(HistoryNode* history_node); template HistoryNode* find_history_node(HistoryNode* node, const Func& func); diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index 1e282695..4a6e3816 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -181,12 +181,17 @@ void write_to_debug_buffer(StringView str) // where the user can put its cursor to scroll with new messages const bool eol_back = not str.empty() and str.back() == '\n'; if (Buffer* buffer = BufferManager::instance().get_buffer_ifp(debug_buffer_name)) + { + buffer->flags() &= ~Buffer::Flags::ReadOnly; + auto restore = on_scope_end([buffer] { buffer->flags() |= Buffer::Flags::ReadOnly; }); + buffer->insert(buffer->back_coord(), eol_back ? str : str + "\n"); + } else { String line = str + (eol_back ? "\n" : "\n\n"); BufferManager::instance().create_buffer( - debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug, + debug_buffer_name.str(), Buffer::Flags::NoUndo | Buffer::Flags::Debug | Buffer::Flags::ReadOnly, line, InvalidTime); } } diff --git a/src/input_handler.cc b/src/input_handler.cc index f8211a2e..3662e12f 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -1061,6 +1061,8 @@ public: context().hooks().run_hook("InsertIdle", "", context()); }} { + context().buffer().throw_if_read_only(); + last_insert().recording.set(); last_insert().mode = mode; last_insert().keys.clear(); @@ -1068,11 +1070,6 @@ public: last_insert().count = count; context().hooks().run_hook("InsertBegin", "", context()); prepare(mode, count); - - if (context().has_client() and - context().options()["readonly"].get()) - context().print_status({ "Warning: This buffer is readonly", - get_face("Error") }); } void on_enabled() override