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

View File

@ -13,7 +13,8 @@ class ClientManager : public Singleton<ClientManager>
{ {
public: public:
void create_client(std::unique_ptr<UserInterface>&& ui, 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(); } bool empty() const { return m_clients.empty(); }
size_t count() const { return m_clients.size(); } size_t count() const { return m_clients.size(); }

View File

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

View File

@ -2,6 +2,9 @@
#include "display_buffer.hh" #include "display_buffer.hh"
#include "debug.hh" #include "debug.hh"
#include "client_manager.hh"
#include "buffer_manager.hh"
#include "event_manager.hh"
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -161,6 +164,36 @@ DisplayBuffer read<DisplayBuffer>(int socket)
return db; 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) RemoteUI::RemoteUI(int socket)
: m_socket(socket) : m_socket(socket)
{ {
@ -260,11 +293,13 @@ DisplayCoord RemoteUI::dimensions()
return m_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()) : 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); Message msg(socket);
msg.write(init_command);
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) | (int)m_dimensions.column) };
msg.write(key); 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 {}; struct peer_disconnected {};
class RemoteUI : public UserInterface void handle_remote(int socket);
{
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;
};
class RemoteClient class RemoteClient
{ {
public: public:
RemoteClient(int socket, UserInterface* ui); RemoteClient(int socket, UserInterface* ui,
const String& init_command);
void process_next_message(); void process_next_message();
void write_next_key(); void write_next_key();