diff --git a/src/client.cc b/src/client.cc index 27a56c80..0d729bc3 100644 --- a/src/client.cc +++ b/src/client.cc @@ -138,7 +138,7 @@ void Client::change_buffer(Buffer& buffer) m_window->options().register_watcher(*this); m_ui->set_ui_options(m_window->options()["ui_options"].get()); - context().m_selections = std::move(ws.selections); + context().selections_write_only() = std::move(ws.selections); context().set_window(*m_window); m_window->set_dimensions(ui().dimensions()); @@ -177,7 +177,7 @@ void Client::reload_buffer() ByteCoord cursor_pos = context().selections().main().cursor(); Buffer* buf = create_buffer_from_file(buffer.name()); kak_assert(buf == &buffer); - context().selections() = SelectionList{buffer, buffer.clamp(cursor_pos)}; + context().selections_write_only() = SelectionList{buffer, buffer.clamp(cursor_pos)}; context().window().set_position(view_pos); context().print_status({ "'" + buffer.display_name() + "' reloaded", get_face("Information") }); diff --git a/src/commands.cc b/src/commands.cc index 964ae0e1..66ba66d9 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -175,7 +175,7 @@ void edit(const ParametersParser& parser, Context& context) std::max(0, str_to_int(parser[2]) - 1) : 0; auto& buffer = context.buffer(); - context.selections() = { buffer, buffer.clamp({ line, column }) }; + context.selections_write_only() = { buffer, buffer.clamp({ line, column }) }; if (context.has_window()) context.window().center_line(context.selections().main().cursor().line); } @@ -1180,7 +1180,7 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func) ScopedEdition edition{c}; for (auto& sel : sels) { - c.selections() = SelectionList{ sels.buffer(), sel, sels.timestamp() }; + c.selections_write_only() = SelectionList{ sels.buffer(), sel, sels.timestamp() }; c.selections().update(); func(parser, c); @@ -1489,7 +1489,7 @@ const CommandDesc select_cmd = { CommandCompleter{}, [](const ParametersParser& parser, Context& context) { - context.selections() = selection_list_from_string(context.buffer(), parser[0]); + context.selections_write_only() = selection_list_from_string(context.buffer(), parser[0]); } }; diff --git a/src/context.cc b/src/context.cc index ca186cb1..bd67a6b3 100644 --- a/src/context.cc +++ b/src/context.cc @@ -197,6 +197,13 @@ SelectionList& Context::selections() return *m_selections; } +SelectionList& Context::selections_write_only() +{ + if (not m_selections) + throw runtime_error("no selections in context"); + return *m_selections; +} + const SelectionList& Context::selections() const { return const_cast(*this).selections(); diff --git a/src/context.hh b/src/context.hh index 4ff765de..48b01a87 100644 --- a/src/context.hh +++ b/src/context.hh @@ -90,6 +90,9 @@ public: const SelectionList& selections() const; Vector selections_content() const; + // Return potentially out of date selections + SelectionList& selections_write_only(); + void change_buffer(Buffer& buffer); void set_client(Client& client); @@ -141,7 +144,6 @@ private: SafePtr m_window; SafePtr m_client; - friend class Client; Optional m_selections; String m_name; diff --git a/src/input_handler.cc b/src/input_handler.cc index 8b672288..98f2436a 100644 --- a/src/input_handler.cc +++ b/src/input_handler.cc @@ -60,7 +60,7 @@ struct MouseHandler { m_dragging = true; m_anchor = context.window().buffer_coord(key.mouse_coord()); - context.selections() = SelectionList{ context.buffer(), m_anchor }; + context.selections_write_only() = SelectionList{ context.buffer(), m_anchor }; return true; } if (key.modifiers == Key::Modifiers::MouseRelease) @@ -69,7 +69,7 @@ struct MouseHandler return true; m_dragging = false; auto cursor = context.window().buffer_coord(key.mouse_coord()); - context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} }; + context.selections_write_only() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} }; return true; } if (key.modifiers == Key::Modifiers::MousePos) @@ -77,7 +77,7 @@ struct MouseHandler if (not m_dragging) return true; auto cursor = context.window().buffer_coord(key.mouse_coord()); - context.selections() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} }; + context.selections_write_only() = SelectionList{ context.buffer(), Selection{m_anchor, cursor} }; return true; } if (key.modifiers == Key::Modifiers::MouseWheelDown) diff --git a/src/normal.cc b/src/normal.cc index 7f737032..8bd8691e 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -563,7 +563,7 @@ void regex_prompt(Context& context, const String prompt, T func) if (event != PromptEvent::Change and context.has_ui()) context.ui().info_hide(); selections.update(); - context.selections() = selections; + context.selections_write_only() = selections; context.input_handler().set_prompt_face(get_face("Prompt")); if (event == PromptEvent::Abort) return; @@ -600,7 +600,7 @@ void regex_prompt(Context& context, const String prompt, T func) } catch (runtime_error&) { - context.selections() = selections; + context.selections_write_only() = selections; // only validation should propagate errors, // incremental search should not. if (event == PromptEvent::Validate) @@ -733,7 +733,7 @@ void join_lines_select_spaces(Context& context, NormalParams) } if (selections.empty()) return; - context.selections() = selections; + context.selections_write_only() = std::move(selections); ScopedEdition edition(context); context.selections().insert(" "_str, InsertMode::Replace); } @@ -743,7 +743,7 @@ void join_lines(Context& context, NormalParams params) SelectionList sels{context.selections()}; auto restore_sels = on_scope_end([&]{ sels.update(); - context.selections() = std::move(sels); + context.selections_write_only() = std::move(sels); }); join_lines_select_spaces(context, params); @@ -766,7 +766,7 @@ void keep(Context& context, NormalParams) } if (keep.empty()) throw runtime_error("no selections remaining"); - context.selections() = std::move(keep); + context.selections_write_only() = std::move(keep); }); } @@ -788,7 +788,7 @@ void keep_pipe(Context& context, NormalParams) } if (keep.empty()) throw runtime_error("no selections remaining"); - context.selections() = std::move(keep); + context.selections_write_only() = std::move(keep); }); } template @@ -1100,7 +1100,7 @@ void jump(Context& context, NormalParams) BufferManager::instance().set_last_used_buffer(buffer); if (&buffer != &context.buffer()) context.change_buffer(buffer); - context.selections() = jump; + context.selections_write_only() = jump; } void save_selections(Context& context, NormalParams) @@ -1267,7 +1267,7 @@ void undo(Context& context, NormalParams) { auto ranges = compute_modified_ranges(buffer, timestamp); if (not ranges.empty()) - context.selections() = std::move(ranges); + context.selections_write_only() = std::move(ranges); context.selections().avoid_eol(); } else if (not res) @@ -1284,7 +1284,7 @@ void redo(Context& context, NormalParams) { auto ranges = compute_modified_ranges(buffer, timestamp); if (not ranges.empty()) - context.selections() = std::move(ranges); + context.selections_write_only() = std::move(ranges); context.selections().avoid_eol(); }