summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-10-08 13:43:39 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-10-08 13:43:39 +0100
commit7776c38755bfa4674b21989d7a7ef9561c02c366 (patch)
treec76ac93a95365a2ce8cca3b2446ef07d123c5b20 /src
parent3098cd12f8bf2ace612079cdee8ef58b449b64d0 (diff)
Detect ungraceful exits, and backup modified buffers in these cases
Diffstat (limited to 'src')
-rw-r--r--src/client.cc4
-rw-r--r--src/client_manager.cc9
-rw-r--r--src/client_manager.hh9
-rw-r--r--src/commands.cc2
-rw-r--r--src/main.cc2
-rw-r--r--src/remote.cc4
6 files changed, 19 insertions, 11 deletions
diff --git a/src/client.cc b/src/client.cc
index da218b7c..9c3ffc3a 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -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);
}
}
diff --git a/src/client_manager.cc b/src/client_manager.cc
index aab87ea2..ceceb15f 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -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)
diff --git a/src/client_manager.hh b/src/client_manager.hh
index 3db5fb8f..cd7f12bf 100644
--- a/src/client_manager.hh
+++ b/src/client_manager.hh
@@ -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;
diff --git a/src/commands.cc b/src/commands.cc
index 034dd483..d46c8db5 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -299,7 +299,7 @@ void quit()
}
}
// unwind back to this client event handler.
- throw client_removed{};
+ throw client_removed{ true };
}
const CommandDesc quit_cmd = {
diff --git a/src/main.cc b/src/main.cc
index fbf61fbf..31bc2cfa 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -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;
});
}
diff --git a/src/remote.cc b/src/remote.cc
index d4a84aa7..1e1edc23 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -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 };
}
}