Detect ungraceful exits, and backup modified buffers in these cases

This commit is contained in:
Maxime Coste 2015-10-08 13:43:39 +01:00
parent 3098cd12f8
commit 7776c38755
6 changed files with 19 additions and 11 deletions

View File

@ -86,9 +86,9 @@ void Client::handle_available_input(EventMode mode)
context().print_status({ error.what().str(), get_face("Error") });
context().hooks().run_hook("RuntimeError", error.what(), context());
}
catch (Kakoune::client_removed&)
catch (Kakoune::client_removed& removed)
{
ClientManager::instance().remove_client(*this);
ClientManager::instance().remove_client(*this, removed.graceful);
}
}

View File

@ -50,9 +50,9 @@ Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
client->context().hooks().run_hook("RuntimeError", error.what(),
client->context());
}
catch (Kakoune::client_removed&)
catch (Kakoune::client_removed& removed)
{
m_clients.pop_back();
remove_client(*client, removed.graceful);
return nullptr;
}
@ -69,13 +69,16 @@ void ClientManager::handle_pending_inputs() const
client->handle_available_input(EventMode::Pending);
}
void ClientManager::remove_client(Client& client)
void ClientManager::remove_client(Client& client, bool graceful)
{
auto it = find_if(m_clients,
[&](const std::unique_ptr<Client>& ptr)
{ return ptr.get() == &client; });
kak_assert(it != m_clients.end());
m_clients.erase(it);
if (not graceful and m_clients.empty())
BufferManager::instance().backup_modified_buffers();
}
WindowAndSelections ClientManager::get_free_window(Buffer& buffer)

View File

@ -7,7 +7,12 @@
namespace Kakoune
{
struct client_removed{};
struct client_removed
{
client_removed(bool graceful) : graceful{graceful} {}
const bool graceful;
};
struct WindowAndSelections
{
@ -39,7 +44,7 @@ public:
Client* get_client_ifp(StringView name);
Client& get_client(StringView name);
bool validate_client_name(StringView name) const;
void remove_client(Client& client);
void remove_client(Client& client, bool graceful);
using ClientList = Vector<std::unique_ptr<Client>, MemoryDomain::Client>;
using iterator = ClientList::const_iterator;

View File

@ -299,7 +299,7 @@ void quit()
}
}
// unwind back to this client event handler.
throw client_removed{};
throw client_removed{ true };
}
const CommandDesc quit_cmd = {

View File

@ -309,7 +309,7 @@ void create_local_client(std::unique_ptr<UserInterface> ui, StringView init_comm
signal(SIGHUP, [](int) {
if (client)
ClientManager::instance().remove_client(*client);
ClientManager::instance().remove_client(*client, false);
client = nullptr;
});
}

View File

@ -391,12 +391,12 @@ Key RemoteUI::get_key()
}
catch (peer_disconnected&)
{
throw client_removed{};
throw client_removed{ false };
}
catch (socket_error&)
{
write_to_debug_buffer("ungraceful deconnection detected");
throw client_removed{};
throw client_removed{ false };
}
}