move Client as a public class instead of a ClientManager implementation detail
This commit is contained in:
parent
385241d2c0
commit
cc91a71a96
|
@ -11,26 +11,15 @@
|
||||||
namespace Kakoune
|
namespace Kakoune
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ClientManager::Client
|
Client::Client(std::unique_ptr<UserInterface>&& ui,
|
||||||
|
Window& window, String name)
|
||||||
|
: m_user_interface(std::move(ui)),
|
||||||
|
m_input_handler(*m_user_interface),
|
||||||
|
m_name(std::move(name))
|
||||||
{
|
{
|
||||||
Client(std::unique_ptr<UserInterface>&& ui, Window& window,
|
kak_assert(not m_name.empty());
|
||||||
String name)
|
context().change_editor(window);
|
||||||
: user_interface(std::move(ui)),
|
}
|
||||||
input_handler(*user_interface),
|
|
||||||
name(std::move(name))
|
|
||||||
{
|
|
||||||
kak_assert(not this->name.empty());
|
|
||||||
context().change_editor(window);
|
|
||||||
}
|
|
||||||
Client(Client&&) = delete;
|
|
||||||
Client& operator=(Client&& other) = delete;
|
|
||||||
|
|
||||||
Context& context() { return input_handler.context(); }
|
|
||||||
|
|
||||||
std::unique_ptr<UserInterface> user_interface;
|
|
||||||
InputHandler input_handler;
|
|
||||||
String name;
|
|
||||||
};
|
|
||||||
|
|
||||||
ClientManager::ClientManager() = default;
|
ClientManager::ClientManager() = default;
|
||||||
ClientManager::~ClientManager() = default;
|
ClientManager::~ClientManager() = default;
|
||||||
|
@ -43,7 +32,7 @@ String ClientManager::generate_name() const
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto& client : m_clients)
|
for (auto& client : m_clients)
|
||||||
{
|
{
|
||||||
if (client->name == name)
|
if (client->m_name == name)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -54,53 +43,57 @@ String ClientManager::generate_name() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
const String& init_commands)
|
const String& init_commands)
|
||||||
{
|
{
|
||||||
Buffer& buffer = **BufferManager::instance().begin();
|
Buffer& buffer = **BufferManager::instance().begin();
|
||||||
m_clients.emplace_back(new Client{std::move(ui), get_unused_window_for_buffer(buffer),
|
Client* client = new Client{std::move(ui), get_unused_window_for_buffer(buffer),
|
||||||
generate_name()});
|
generate_name()};
|
||||||
Context* context = &m_clients.back()->context();
|
m_clients.emplace_back(client);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CommandManager::instance().execute(init_commands, *context);
|
CommandManager::instance().execute(init_commands, client->context());
|
||||||
}
|
}
|
||||||
catch (Kakoune::runtime_error& error)
|
catch (Kakoune::runtime_error& error)
|
||||||
{
|
{
|
||||||
context->print_status({ error.what(), get_color("Error") });
|
client->context().print_status({ error.what(), get_color("Error") });
|
||||||
context->hooks().run_hook("RuntimeError", error.what(), *context);
|
client->context().hooks().run_hook("RuntimeError", error.what(),
|
||||||
|
client->context());
|
||||||
}
|
}
|
||||||
catch (Kakoune::client_removed&)
|
catch (Kakoune::client_removed&)
|
||||||
{
|
{
|
||||||
m_clients.pop_back();
|
m_clients.pop_back();
|
||||||
return;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->ui().set_input_callback([context, this]() {
|
client->m_user_interface->set_input_callback([client, this]() {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
context->input_handler().handle_available_inputs();
|
client->m_input_handler.handle_available_inputs();
|
||||||
context->window().forget_timestamp();
|
client->context().window().forget_timestamp();
|
||||||
}
|
}
|
||||||
catch (Kakoune::runtime_error& error)
|
catch (Kakoune::runtime_error& error)
|
||||||
{
|
{
|
||||||
context->print_status({ error.what(), get_color("Error") });
|
client->context().print_status({ error.what(), get_color("Error") });
|
||||||
context->hooks().run_hook("RuntimeError", error.what(), *context);
|
client->context().hooks().run_hook("RuntimeError", error.what(),
|
||||||
|
client->context());
|
||||||
}
|
}
|
||||||
catch (Kakoune::client_removed&)
|
catch (Kakoune::client_removed&)
|
||||||
{
|
{
|
||||||
ClientManager::instance().remove_client_by_context(*context);
|
ClientManager::instance().remove_client(*client);
|
||||||
}
|
}
|
||||||
ClientManager::instance().redraw_clients();
|
ClientManager::instance().redraw_clients();
|
||||||
});
|
});
|
||||||
redraw_clients();
|
redraw_clients();
|
||||||
|
|
||||||
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::remove_client_by_context(Context& context)
|
void ClientManager::remove_client(Client& client)
|
||||||
{
|
{
|
||||||
for (auto it = m_clients.begin(); it != m_clients.end(); ++it)
|
for (auto it = m_clients.begin(); it != m_clients.end(); ++it)
|
||||||
{
|
{
|
||||||
if (&(*it)->context() == &context)
|
if (it->get() == &client)
|
||||||
{
|
{
|
||||||
m_clients.erase(it);
|
m_clients.erase(it);
|
||||||
return;
|
return;
|
||||||
|
@ -139,7 +132,7 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (client->context().editor().is_editing())
|
if (client->context().editor().is_editing())
|
||||||
throw runtime_error("client '" + client->name + "' is inserting in '" +
|
throw runtime_error("client '" + client->m_name + "' is inserting in '" +
|
||||||
buffer.display_name() + '\'');
|
buffer.display_name() + '\'');
|
||||||
|
|
||||||
// change client context to edit the first buffer which is not the
|
// change client context to edit the first buffer which is not the
|
||||||
|
@ -161,40 +154,32 @@ void ClientManager::ensure_no_client_uses_buffer(Buffer& buffer)
|
||||||
m_windows.erase(end, m_windows.end());
|
m_windows.erase(end, m_windows.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientManager::set_client_name(Context& context, String name)
|
void ClientManager::set_client_name(Client& client, String name)
|
||||||
{
|
{
|
||||||
auto it = find_if(m_clients, [&name](std::unique_ptr<Client>& client)
|
auto it = find_if(m_clients, [&name](std::unique_ptr<Client>& client)
|
||||||
{ return client->name == name; });
|
{ return client->m_name == name; });
|
||||||
if (it != m_clients.end() and &(*it)->context() != &context)
|
if (it != m_clients.end() and it->get() != &client)
|
||||||
throw runtime_error("name not unique: " + name);
|
throw runtime_error("name not unique: " + name);
|
||||||
|
client.m_name = std::move(name);
|
||||||
for (auto& client : m_clients)
|
|
||||||
{
|
|
||||||
if (&client->context() == &context)
|
|
||||||
{
|
|
||||||
client->name = std::move(name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw runtime_error("no client for current context");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String ClientManager::get_client_name(const Context& context)
|
Client& ClientManager::get_client(const Context& context)
|
||||||
{
|
{
|
||||||
for (auto& client : m_clients)
|
for (auto& client : m_clients)
|
||||||
{
|
{
|
||||||
if (&client->context() == &context)
|
if (&client->context() == &context)
|
||||||
return client->name;
|
return *client;
|
||||||
}
|
}
|
||||||
throw runtime_error("no client for current context");
|
throw runtime_error("no client for current context");
|
||||||
}
|
}
|
||||||
|
|
||||||
Context& ClientManager::get_client_context(const String& name)
|
Client& ClientManager::get_client(const String& name)
|
||||||
{
|
{
|
||||||
auto it = find_if(m_clients, [&name](std::unique_ptr<Client>& client)
|
for (auto& client : m_clients)
|
||||||
{ return client->name == name; });
|
{
|
||||||
if (it != m_clients.end())
|
if (client->m_name == name)
|
||||||
return (*it)->context();
|
return *client;
|
||||||
|
}
|
||||||
throw runtime_error("no client named: " + name);
|
throw runtime_error("no client named: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,34 @@ namespace Kakoune
|
||||||
|
|
||||||
struct client_removed{};
|
struct client_removed{};
|
||||||
|
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Context& context() { return m_input_handler.context(); }
|
||||||
|
const String& name() const { return m_name; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class ClientManager;
|
||||||
|
|
||||||
|
Client(std::unique_ptr<UserInterface>&& ui,
|
||||||
|
Window& window, String name);
|
||||||
|
Client(Client&&) = delete;
|
||||||
|
Client& operator=(Client&& other) = delete;
|
||||||
|
|
||||||
|
const std::unique_ptr<UserInterface> m_user_interface;
|
||||||
|
InputHandler m_input_handler;
|
||||||
|
String m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ClientManager : public Singleton<ClientManager>
|
class ClientManager : public Singleton<ClientManager>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClientManager();
|
ClientManager();
|
||||||
~ClientManager();
|
~ClientManager();
|
||||||
|
|
||||||
void create_client(std::unique_ptr<UserInterface>&& ui,
|
Client* create_client(std::unique_ptr<UserInterface>&& ui,
|
||||||
const String& init_cmd);
|
const String& init_cmd);
|
||||||
|
|
||||||
bool empty() const { return m_clients.empty(); }
|
bool empty() const { return m_clients.empty(); }
|
||||||
size_t count() const { return m_clients.size(); }
|
size_t count() const { return m_clients.size(); }
|
||||||
|
@ -26,14 +46,14 @@ public:
|
||||||
|
|
||||||
void redraw_clients() const;
|
void redraw_clients() const;
|
||||||
|
|
||||||
void set_client_name(Context& context, String name);
|
Client& get_client(const Context& context);
|
||||||
String get_client_name(const Context& context);
|
Client& get_client(const String& name);
|
||||||
Context& get_client_context(const String& name);
|
void set_client_name(Client& client, String name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void remove_client_by_context(Context& context);
|
void remove_client(Client& client);
|
||||||
String generate_name() const;
|
String generate_name() const;
|
||||||
|
|
||||||
struct Client;
|
|
||||||
std::vector<std::unique_ptr<Client>> m_clients;
|
std::vector<std::unique_ptr<Client>> m_clients;
|
||||||
std::vector<std::unique_ptr<Window>> m_windows;
|
std::vector<std::unique_ptr<Window>> m_windows;
|
||||||
};
|
};
|
||||||
|
|
|
@ -535,7 +535,7 @@ void context_wrap(const CommandParameters& params, Context& context, Func func)
|
||||||
ParametersParser::Flags::None, 1);
|
ParametersParser::Flags::None, 1);
|
||||||
|
|
||||||
Context& real_context = parser.has_option("client") ?
|
Context& real_context = parser.has_option("client") ?
|
||||||
ClientManager::instance().get_client_context(parser.option_value("client"))
|
ClientManager::instance().get_client(parser.option_value("client")).context()
|
||||||
: context;
|
: context;
|
||||||
|
|
||||||
if (parser.has_option("draft"))
|
if (parser.has_option("draft"))
|
||||||
|
@ -745,7 +745,8 @@ void set_client_name(const CommandParameters& params, Context& context)
|
||||||
{
|
{
|
||||||
ParametersParser parser(params, OptionMap{},
|
ParametersParser parser(params, OptionMap{},
|
||||||
ParametersParser::Flags::None, 1, 1);
|
ParametersParser::Flags::None, 1, 1);
|
||||||
ClientManager::instance().set_client_name(context, params[0]);
|
auto& manager = ClientManager::instance();
|
||||||
|
manager.set_client_name(manager.get_client(context), params[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_register(const CommandParameters& params, Context& context)
|
void set_register(const CommandParameters& params, Context& context)
|
||||||
|
|
|
@ -86,7 +86,7 @@ void register_env_vars()
|
||||||
{ return Server::instance().filename(); });
|
{ return Server::instance().filename(); });
|
||||||
shell_manager.register_env_var("client",
|
shell_manager.register_env_var("client",
|
||||||
[](const String& name, const Context& context)
|
[](const String& name, const Context& context)
|
||||||
{ return ClientManager::instance().get_client_name(context); });
|
{ return ClientManager::instance().get_client(context).name(); });
|
||||||
shell_manager.register_env_var("cursor_line",
|
shell_manager.register_env_var("cursor_line",
|
||||||
[](const String& name, const Context& context)
|
[](const String& name, const Context& context)
|
||||||
{ return int_to_str((int)context.editor().main_selection().last().line() + 1); });
|
{ return int_to_str((int)context.editor().main_selection().last().line() + 1); });
|
||||||
|
|
Loading…
Reference in New Issue
Block a user