From e42c81c8eb53a6562f0d7313a6a9a92d8360238f Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 22 Jul 2019 20:05:42 +1000 Subject: [PATCH] Ensure current context switches away from buffer on delete-buffer Fixes #3025 --- src/client.cc | 3 --- src/client.hh | 5 ----- src/client_manager.cc | 15 +------------ src/commands.cc | 1 + src/context.cc | 22 +++++++++++++++++++ src/context.hh | 3 +++ src/normal.cc | 5 ++--- .../cmd | 1 + .../out | 1 + .../rc | 8 +++++++ 10 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 test/regression/3025-last-buffer-does-not-work-in-draft-context/cmd create mode 100644 test/regression/3025-last-buffer-does-not-work-in-draft-context/out create mode 100644 test/regression/3025-last-buffer-does-not-work-in-draft-context/rc diff --git a/src/client.cc b/src/client.cc index 5bed81fe..e3239ce5 100644 --- a/src/client.cc +++ b/src/client.cc @@ -169,9 +169,6 @@ void Client::change_buffer(Buffer& buffer) if (m_buffer_reload_dialog_opened) close_buffer_reload_dialog(); - auto* current = &m_window->buffer(); - m_last_buffer = contains(BufferManager::instance(), current) ? current : nullptr; - auto& client_manager = ClientManager::instance(); m_window->options().unregister_watcher(*this); m_window->set_client(nullptr); diff --git a/src/client.hh b/src/client.hh index 4b640ebe..fd1cd1a6 100644 --- a/src/client.hh +++ b/src/client.hh @@ -68,9 +68,6 @@ public: StringView get_env_var(StringView name) const; - Buffer* last_buffer() const { return m_last_buffer.get(); } - void set_last_buffer(Buffer* last_buffer) { m_last_buffer = last_buffer; } - void exit(int status) { m_on_exit(status); } int pid() const { return m_pid; } @@ -132,8 +129,6 @@ private: Vector m_pending_keys; bool m_buffer_reload_dialog_opened = false; - - SafePtr m_last_buffer; }; enum class Autoreload diff --git a/src/client_manager.cc b/src/client_manager.cc index b95e80ec..d1ac5bf3 100644 --- a/src/client_manager.cc +++ b/src/client_manager.cc @@ -167,21 +167,8 @@ void ClientManager::add_free_window(std::unique_ptr&& window, SelectionL void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer) { for (auto& client : m_clients) - { - auto& context = client->context(); - context.jump_list().forget_buffer(buffer); - if (client->last_buffer() == &buffer) - client->set_last_buffer(nullptr); + client->context().forget_buffer(buffer); - if (&context.buffer() != &buffer) - continue; - - if (context.is_editing()) - context.input_handler().reset_normal_mode(); - - Buffer* last = client->last_buffer(); - context.change_buffer(last ? *last : BufferManager::instance().get_first_buffer()); - } Vector> removed_windows; m_free_windows.erase(std::remove_if(m_free_windows.begin(), m_free_windows.end(), [&buffer, &removed_windows](WindowAndSelections& ws) { diff --git a/src/commands.cc b/src/commands.cc index 09316b2d..779e8d6d 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -788,6 +788,7 @@ void delete_buffer(const ParametersParser& parser, Context& context, const Shell throw runtime_error(format("buffer '{}' is modified", buffer.name())); manager.delete_buffer(buffer); + context.forget_buffer(buffer); } const CommandDesc delete_buffer_cmd = { diff --git a/src/context.cc b/src/context.cc index d969ffd0..2a0822ec 100644 --- a/src/context.cc +++ b/src/context.cc @@ -3,6 +3,7 @@ #include "alias_registry.hh" #include "client.hh" #include "face_registry.hh" +#include "buffer_manager.hh" #include "register_manager.hh" #include "window.hh" @@ -171,6 +172,12 @@ void Context::change_buffer(Buffer& buffer) if (has_buffer() and m_edition_level > 0) this->buffer().commit_undo_group(); + if (has_buffer()) + { + auto* current = &this->buffer(); + m_last_buffer = contains(BufferManager::instance(), current) ? current : nullptr; + } + m_window.reset(); if (has_client()) { @@ -185,6 +192,21 @@ void Context::change_buffer(Buffer& buffer) input_handler().reset_normal_mode(); } +void Context::forget_buffer(Buffer& buffer) +{ + m_jump_list.forget_buffer(buffer); + if (m_last_buffer.get() == &buffer) + m_last_buffer = nullptr; + + if (&this->buffer() != &buffer) + return; + + if (is_editing() && has_input_handler()) + input_handler().reset_normal_mode(); + + change_buffer(m_last_buffer ? *m_last_buffer : BufferManager::instance().get_first_buffer()); +} + SelectionList& Context::selections() { if (not m_selections) diff --git a/src/context.hh b/src/context.hh index b71e6547..728c4cad 100644 --- a/src/context.hh +++ b/src/context.hh @@ -89,6 +89,7 @@ public: SelectionList& selections_write_only(); void change_buffer(Buffer& buffer); + void forget_buffer(Buffer& buffer); void set_client(Client& client); void set_window(Window& window); @@ -134,6 +135,7 @@ public: void repeat_last_select() { if (m_last_select) m_last_select(*this); } + Buffer* last_buffer() const { return m_last_buffer.get(); } private: void begin_edition(); void end_edition(); @@ -147,6 +149,7 @@ private: SafePtr m_input_handler; SafePtr m_window; SafePtr m_client; + SafePtr m_last_buffer; Optional m_selections; diff --git a/src/normal.cc b/src/normal.cc index 0dd56af7..ad085458 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -270,9 +270,8 @@ void goto_commands(Context& context, NormalParams params) break; case 'a': { - Buffer* target = nullptr; - if (not context.has_client() or - not (target = context.client().last_buffer())) + Buffer* target = context.last_buffer(); + if (not target) { throw runtime_error("no last buffer"); break; diff --git a/test/regression/3025-last-buffer-does-not-work-in-draft-context/cmd b/test/regression/3025-last-buffer-does-not-work-in-draft-context/cmd new file mode 100644 index 00000000..6df292b2 --- /dev/null +++ b/test/regression/3025-last-buffer-does-not-work-in-draft-context/cmd @@ -0,0 +1 @@ +s.*/d diff --git a/test/regression/3025-last-buffer-does-not-work-in-draft-context/out b/test/regression/3025-last-buffer-does-not-work-in-draft-context/out new file mode 100644 index 00000000..997d573c --- /dev/null +++ b/test/regression/3025-last-buffer-does-not-work-in-draft-context/out @@ -0,0 +1 @@ +*test*out diff --git a/test/regression/3025-last-buffer-does-not-work-in-draft-context/rc b/test/regression/3025-last-buffer-does-not-work-in-draft-context/rc new file mode 100644 index 00000000..c192daa1 --- /dev/null +++ b/test/regression/3025-last-buffer-does-not-work-in-draft-context/rc @@ -0,0 +1,8 @@ +declare-option str-list bufnames +eval -draft -save-regs '' %{ + edit -scratch *test* + set-option global bufnames %val{bufname} + db! + set-option -add global bufnames %val{bufname} + set-register '"' %opt{bufnames} +}