Support initial command passing when a client is connecting

This commit is contained in:
Maxime Coste 2012-12-18 21:20:36 +01:00
parent 9ca69820ac
commit 26632726ad
5 changed files with 62 additions and 41 deletions

View File

@ -2,17 +2,20 @@
#include "event_manager.hh"
#include "buffer_manager.hh"
#include "command_manager.hh"
namespace Kakoune
{
void ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
Buffer& buffer, int event_fd)
Buffer& buffer, int event_fd,
const String& init_commands)
{
m_clients.emplace_back(new Client{std::move(ui), get_unused_window_for_buffer(buffer)});
InputHandler* input_handler = &m_clients.back()->input_handler;
Context* context = &m_clients.back()->context;
CommandManager::instance().execute(init_commands, *context);
EventManager::instance().watch(event_fd, [input_handler, context, this](int fd) {
try
{

View File

@ -13,7 +13,8 @@ class ClientManager : public Singleton<ClientManager>
{
public:
void create_client(std::unique_ptr<UserInterface>&& ui,
Buffer& buffer, int event_fd);
Buffer& buffer, int event_fd,
const String& init_cmd);
bool empty() const { return m_clients.empty(); }
size_t count() const { return m_clients.size(); }

View File

@ -570,10 +570,7 @@ struct Server : public Singleton<Server>
throw runtime_error("accept failed");
fcntl(sock, F_SETFD, FD_CLOEXEC);
auto& buffer = *BufferManager::instance().begin();
RemoteUI* ui = new RemoteUI{sock};
ClientManager::instance().create_client(
std::unique_ptr<UserInterface>{ui}, *buffer, sock);
EventManager::instance().watch(sock, handle_remote);
};
EventManager::instance().watch(m_listen_sock, accepter);
}
@ -664,10 +661,10 @@ void create_local_client(const String& file)
buffer = new Buffer("*scratch*", Buffer::Flags::None);
ClientManager::instance().create_client(
std::unique_ptr<UserInterface>{ui}, *buffer, 0);
std::unique_ptr<UserInterface>{ui}, *buffer, 0, "");
}
RemoteClient* connect_to(const String& pid)
RemoteClient* connect_to(const String& pid, const String& init_command)
{
auto filename = "/tmp/kak-" + pid;
@ -680,7 +677,7 @@ RemoteClient* connect_to(const String& pid)
throw runtime_error("connect to " + filename + " failed");
NCursesUI* ui = new NCursesUI{};
RemoteClient* remote_client = new RemoteClient{sock, ui};
RemoteClient* remote_client = new RemoteClient{sock, ui, init_command};
EventManager::instance().watch(sock, [=](int) {
try
@ -717,7 +714,7 @@ int main(int argc, char* argv[])
{
try
{
std::unique_ptr<RemoteClient> client(connect_to(argv[2]));
std::unique_ptr<RemoteClient> client(connect_to(argv[2], ""));
while (true)
event_manager.handle_next_events();
}

View File

@ -2,6 +2,9 @@
#include "display_buffer.hh"
#include "debug.hh"
#include "client_manager.hh"
#include "buffer_manager.hh"
#include "event_manager.hh"
#include <sys/types.h>
#include <sys/socket.h>
@ -161,6 +164,36 @@ DisplayBuffer read<DisplayBuffer>(int socket)
return db;
}
class RemoteUI : public UserInterface
{
public:
RemoteUI(int socket);
~RemoteUI();
void print_status(const String& status, CharCount cursor_pos) override;
void menu_show(const memoryview<String>& choices,
const DisplayCoord& anchor, MenuStyle style) override;
void menu_select(int selected) override;
void menu_hide() override;
void info_show(const String& content,
const DisplayCoord& anchor, MenuStyle style) override;
void info_hide() override;
void draw(const DisplayBuffer& display_buffer,
const String& mode_line) override;
bool is_key_available() override;
Key get_key() override;
DisplayCoord dimensions() override;
private:
int m_socket;
DisplayCoord m_dimensions;
};
RemoteUI::RemoteUI(int socket)
: m_socket(socket)
{
@ -260,11 +293,13 @@ DisplayCoord RemoteUI::dimensions()
return m_dimensions;
}
RemoteClient::RemoteClient(int socket, UserInterface* ui)
RemoteClient::RemoteClient(int socket, UserInterface* ui,
const String& init_command)
: m_socket(socket), m_ui(ui), m_dimensions(ui->dimensions())
{
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
Message msg(socket);
msg.write(init_command);
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
msg.write(key);
}
@ -331,4 +366,15 @@ void RemoteClient::write_next_key()
}
}
void handle_remote(int socket)
{
String init_command = read<String>(socket);
auto& buffer = *BufferManager::instance().begin();
RemoteUI* ui = new RemoteUI{socket};
EventManager::instance().unwatch(socket);
ClientManager::instance().create_client(
std::unique_ptr<UserInterface>{ui}, *buffer, socket, init_command);
}
}

View File

@ -9,39 +9,13 @@ namespace Kakoune
struct peer_disconnected {};
class RemoteUI : public UserInterface
{
public:
RemoteUI(int socket);
~RemoteUI();
void print_status(const String& status, CharCount cursor_pos) override;
void menu_show(const memoryview<String>& choices,
const DisplayCoord& anchor, MenuStyle style) override;
void menu_select(int selected) override;
void menu_hide() override;
void info_show(const String& content,
const DisplayCoord& anchor, MenuStyle style) override;
void info_hide() override;
void draw(const DisplayBuffer& display_buffer,
const String& mode_line) override;
bool is_key_available() override;
Key get_key() override;
DisplayCoord dimensions() override;
private:
int m_socket;
DisplayCoord m_dimensions;
};
void handle_remote(int socket);
class RemoteClient
{
public:
RemoteClient(int socket, UserInterface* ui);
RemoteClient(int socket, UserInterface* ui,
const String& init_command);
void process_next_message();
void write_next_key();