Ensure current context switches away from buffer on delete-buffer
Fixes #3025
This commit is contained in:
parent
837416ea38
commit
e42c81c8eb
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<a-P>s.*/<ret>d
|
|
@ -0,0 +1 @@
|
||||||
|
*test*out
|
|
@ -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}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user