Ensure current context switches away from buffer on delete-buffer

Fixes #3025
This commit is contained in:
Maxime Coste 2019-07-22 20:05:42 +10:00
parent 837416ea38
commit e42c81c8eb
10 changed files with 39 additions and 25 deletions

View File

@ -169,9 +169,6 @@ void Client::change_buffer(Buffer& buffer)
if (m_buffer_reload_dialog_opened) if (m_buffer_reload_dialog_opened)
close_buffer_reload_dialog(); close_buffer_reload_dialog();
auto* current = &m_window->buffer();
m_last_buffer = contains(BufferManager::instance(), current) ? current : nullptr;
auto& client_manager = ClientManager::instance(); auto& client_manager = ClientManager::instance();
m_window->options().unregister_watcher(*this); m_window->options().unregister_watcher(*this);
m_window->set_client(nullptr); m_window->set_client(nullptr);

View File

@ -68,9 +68,6 @@ public:
StringView get_env_var(StringView name) const; 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); } void exit(int status) { m_on_exit(status); }
int pid() const { return m_pid; } int pid() const { return m_pid; }
@ -132,8 +129,6 @@ private:
Vector<Key, MemoryDomain::Client> m_pending_keys; Vector<Key, MemoryDomain::Client> m_pending_keys;
bool m_buffer_reload_dialog_opened = false; bool m_buffer_reload_dialog_opened = false;
SafePtr<Buffer> m_last_buffer;
}; };
enum class Autoreload enum class Autoreload

View File

@ -167,21 +167,8 @@ void ClientManager::add_free_window(std::unique_ptr<Window>&& window, SelectionL
void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer) void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
{ {
for (auto& client : m_clients) for (auto& client : m_clients)
{ client->context().forget_buffer(buffer);
auto& context = client->context();
context.jump_list().forget_buffer(buffer);
if (client->last_buffer() == &buffer)
client->set_last_buffer(nullptr);
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<std::unique_ptr<Window>> removed_windows; Vector<std::unique_ptr<Window>> removed_windows;
m_free_windows.erase(std::remove_if(m_free_windows.begin(), m_free_windows.end(), m_free_windows.erase(std::remove_if(m_free_windows.begin(), m_free_windows.end(),
[&buffer, &removed_windows](WindowAndSelections& ws) { [&buffer, &removed_windows](WindowAndSelections& ws) {

View File

@ -788,6 +788,7 @@ void delete_buffer(const ParametersParser& parser, Context& context, const Shell
throw runtime_error(format("buffer '{}' is modified", buffer.name())); throw runtime_error(format("buffer '{}' is modified", buffer.name()));
manager.delete_buffer(buffer); manager.delete_buffer(buffer);
context.forget_buffer(buffer);
} }
const CommandDesc delete_buffer_cmd = { const CommandDesc delete_buffer_cmd = {

View File

@ -3,6 +3,7 @@
#include "alias_registry.hh" #include "alias_registry.hh"
#include "client.hh" #include "client.hh"
#include "face_registry.hh" #include "face_registry.hh"
#include "buffer_manager.hh"
#include "register_manager.hh" #include "register_manager.hh"
#include "window.hh" #include "window.hh"
@ -171,6 +172,12 @@ void Context::change_buffer(Buffer& buffer)
if (has_buffer() and m_edition_level > 0) if (has_buffer() and m_edition_level > 0)
this->buffer().commit_undo_group(); this->buffer().commit_undo_group();
if (has_buffer())
{
auto* current = &this->buffer();
m_last_buffer = contains(BufferManager::instance(), current) ? current : nullptr;
}
m_window.reset(); m_window.reset();
if (has_client()) if (has_client())
{ {
@ -185,6 +192,21 @@ void Context::change_buffer(Buffer& buffer)
input_handler().reset_normal_mode(); 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() SelectionList& Context::selections()
{ {
if (not m_selections) if (not m_selections)

View File

@ -89,6 +89,7 @@ public:
SelectionList& selections_write_only(); SelectionList& selections_write_only();
void change_buffer(Buffer& buffer); void change_buffer(Buffer& buffer);
void forget_buffer(Buffer& buffer);
void set_client(Client& client); void set_client(Client& client);
void set_window(Window& window); void set_window(Window& window);
@ -134,6 +135,7 @@ public:
void repeat_last_select() { if (m_last_select) m_last_select(*this); } void repeat_last_select() { if (m_last_select) m_last_select(*this); }
Buffer* last_buffer() const { return m_last_buffer.get(); }
private: private:
void begin_edition(); void begin_edition();
void end_edition(); void end_edition();
@ -147,6 +149,7 @@ private:
SafePtr<InputHandler> m_input_handler; SafePtr<InputHandler> m_input_handler;
SafePtr<Window> m_window; SafePtr<Window> m_window;
SafePtr<Client> m_client; SafePtr<Client> m_client;
SafePtr<Buffer> m_last_buffer;
Optional<SelectionList> m_selections; Optional<SelectionList> m_selections;

View File

@ -270,9 +270,8 @@ void goto_commands(Context& context, NormalParams params)
break; break;
case 'a': case 'a':
{ {
Buffer* target = nullptr; Buffer* target = context.last_buffer();
if (not context.has_client() or if (not target)
not (target = context.client().last_buffer()))
{ {
throw runtime_error("no last buffer"); throw runtime_error("no last buffer");
break; break;

View File

@ -0,0 +1 @@
<a-P>s.*/<ret>d

View File

@ -0,0 +1 @@
*test*out

View File

@ -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}
}