Support initial command passing when a client is connecting
This commit is contained in:
parent
9ca69820ac
commit
26632726ad
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
13
src/main.cc
13
src/main.cc
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user