Support the +line syntax for clients as well.
Fix a crash on daemon quit as well.
This commit is contained in:
parent
c6a7924b80
commit
e8ee8c23d8
|
@ -22,8 +22,10 @@ void ClientManager::clear()
|
||||||
// So that clients destructor find the client manager empty
|
// So that clients destructor find the client manager empty
|
||||||
// so that local UI does not fork.
|
// so that local UI does not fork.
|
||||||
ClientList clients = std::move(m_clients);
|
ClientList clients = std::move(m_clients);
|
||||||
|
clients.clear();
|
||||||
m_client_trash.clear();
|
m_client_trash.clear();
|
||||||
m_free_windows.clear();
|
m_free_windows.clear();
|
||||||
|
m_window_trash.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
String ClientManager::generate_name() const
|
String ClientManager::generate_name() const
|
||||||
|
|
54
src/main.cc
54
src/main.cc
|
@ -454,12 +454,13 @@ void signal_handler(int signal)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_client(StringView session, StringView init_cmds, UIType ui_type)
|
int run_client(StringView session, StringView init_cmds,
|
||||||
|
Optional<BufferCoord> init_coord, UIType ui_type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
EventManager event_manager;
|
EventManager event_manager;
|
||||||
RemoteClient client{session, make_ui(ui_type), get_env_vars(), init_cmds};
|
RemoteClient client{session, make_ui(ui_type), get_env_vars(), init_cmds, init_coord};
|
||||||
while (true)
|
while (true)
|
||||||
event_manager.handle_next_events(EventMode::Normal);
|
event_manager.handle_next_events(EventMode::Normal);
|
||||||
}
|
}
|
||||||
|
@ -473,7 +474,7 @@ int run_client(StringView session, StringView init_cmds, UIType ui_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_server(StringView session,
|
int run_server(StringView session,
|
||||||
StringView init_cmds, BufferCoord init_coord,
|
StringView init_cmds, Optional<BufferCoord> init_coord,
|
||||||
bool ignore_kakrc, bool daemon, bool readonly, UIType ui_type,
|
bool ignore_kakrc, bool daemon, bool readonly, UIType ui_type,
|
||||||
ConstArrayView<StringView> files)
|
ConstArrayView<StringView> files)
|
||||||
{
|
{
|
||||||
|
@ -812,6 +813,28 @@ int main(int argc, char* argv[])
|
||||||
(bool)parser.get_switch("q"));
|
(bool)parser.get_switch("q"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<StringView> files;
|
||||||
|
Optional<BufferCoord> init_coord;
|
||||||
|
for (auto& name : parser)
|
||||||
|
{
|
||||||
|
if (not name.empty() and name[0_byte] == '+')
|
||||||
|
{
|
||||||
|
auto colon = find(name, ':');
|
||||||
|
if (auto line = str_to_int_ifp({name.begin()+1, colon}))
|
||||||
|
{
|
||||||
|
init_coord = BufferCoord{
|
||||||
|
*line - 1,
|
||||||
|
colon != name.end() ?
|
||||||
|
str_to_int_ifp({colon+1, name.end()}).value_or(1) - 1
|
||||||
|
: 0
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
files.emplace_back(name);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto server_session = parser.get_switch("c"))
|
if (auto server_session = parser.get_switch("c"))
|
||||||
{
|
{
|
||||||
for (auto opt : { "n", "s", "d", "ro" })
|
for (auto opt : { "n", "s", "d", "ro" })
|
||||||
|
@ -823,32 +846,13 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String new_files;
|
String new_files;
|
||||||
for (auto name : parser)
|
for (auto name : files)
|
||||||
new_files += format("edit '{}';", escape(real_path(name), "'", '\\'));
|
new_files += format("edit '{}';", escape(real_path(name), "'", '\\'));
|
||||||
|
|
||||||
return run_client(*server_session, new_files + init_cmds, ui_type);
|
return run_client(*server_session, new_files + init_cmds, init_coord, ui_type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BufferCoord init_coord;
|
|
||||||
Vector<StringView> files;
|
|
||||||
for (auto& name : parser)
|
|
||||||
{
|
|
||||||
if (not name.empty() and name[0_byte] == '+')
|
|
||||||
{
|
|
||||||
auto colon = find(name, ':');
|
|
||||||
if (auto line = str_to_int_ifp({name.begin()+1, colon}))
|
|
||||||
{
|
|
||||||
init_coord.line = *line - 1;
|
|
||||||
if (colon != name.end())
|
|
||||||
init_coord.column = str_to_int_ifp({colon+1, name.end()}).value_or(1) - 1;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
files.emplace_back(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringView session = parser.get_switch("s").value_or(StringView{});
|
StringView session = parser.get_switch("s").value_or(StringView{});
|
||||||
try
|
try
|
||||||
|
@ -864,7 +868,7 @@ int main(int argc, char* argv[])
|
||||||
raise(SIGTSTP);
|
raise(SIGTSTP);
|
||||||
return run_client(convert.session,
|
return run_client(convert.session,
|
||||||
format("try %^buffer '{}'; select '{}'^; echo converted to client only mode",
|
format("try %^buffer '{}'; select '{}'^; echo converted to client only mode",
|
||||||
escape(convert.buffer_name, "'^", '\\'), convert.selections), ui_type);
|
escape(convert.buffer_name, "'^", '\\'), convert.selections), {}, ui_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "event_manager.hh"
|
#include "event_manager.hh"
|
||||||
#include "file.hh"
|
#include "file.hh"
|
||||||
#include "id_map.hh"
|
#include "id_map.hh"
|
||||||
|
#include "optional.hh"
|
||||||
#include "user_interface.hh"
|
#include "user_interface.hh"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -102,6 +103,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void write(const Optional<T>& val)
|
||||||
|
{
|
||||||
|
write((bool)val);
|
||||||
|
if (val)
|
||||||
|
write(*val);
|
||||||
|
}
|
||||||
|
|
||||||
void write(Color color)
|
void write(Color color)
|
||||||
{
|
{
|
||||||
write(color.color);
|
write(color.color);
|
||||||
|
@ -219,6 +228,14 @@ public:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Optional<T> read_optional()
|
||||||
|
{
|
||||||
|
if (not read<bool>())
|
||||||
|
return {};
|
||||||
|
return read<T>();
|
||||||
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
m_stream.resize(0);
|
m_stream.resize(0);
|
||||||
|
@ -511,7 +528,8 @@ bool check_session(StringView session)
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
|
RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
|
||||||
const EnvVarMap& env_vars, StringView init_command)
|
const EnvVarMap& env_vars, StringView init_command,
|
||||||
|
Optional<BufferCoord> init_coord)
|
||||||
: m_ui(std::move(ui))
|
: m_ui(std::move(ui))
|
||||||
{
|
{
|
||||||
int sock = connect_to(session);
|
int sock = connect_to(session);
|
||||||
|
@ -519,6 +537,7 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
|
||||||
{
|
{
|
||||||
MsgWriter msg{m_send_buffer, MessageType::Connect};
|
MsgWriter msg{m_send_buffer, MessageType::Connect};
|
||||||
msg.write(init_command);
|
msg.write(init_command);
|
||||||
|
msg.write(init_coord);
|
||||||
msg.write(m_ui->dimensions());
|
msg.write(m_ui->dimensions());
|
||||||
msg.write(env_vars);
|
msg.write(env_vars);
|
||||||
}
|
}
|
||||||
|
@ -652,12 +671,13 @@ private:
|
||||||
case MessageType::Connect:
|
case MessageType::Connect:
|
||||||
{
|
{
|
||||||
auto init_cmds = m_reader.read<String>();
|
auto init_cmds = m_reader.read<String>();
|
||||||
|
auto init_coord = m_reader.read_optional<BufferCoord>();
|
||||||
auto dimensions = m_reader.read<DisplayCoord>();
|
auto dimensions = m_reader.read<DisplayCoord>();
|
||||||
auto env_vars = m_reader.read_idmap<String, MemoryDomain::EnvVars>();
|
auto env_vars = m_reader.read_idmap<String, MemoryDomain::EnvVars>();
|
||||||
auto* ui = new RemoteUI{sock, dimensions};
|
auto* ui = new RemoteUI{sock, dimensions};
|
||||||
if (auto* client = ClientManager::instance().create_client(
|
if (auto* client = ClientManager::instance().create_client(
|
||||||
std::unique_ptr<UserInterface>(ui),
|
std::unique_ptr<UserInterface>(ui),
|
||||||
std::move(env_vars), init_cmds, {}))
|
std::move(env_vars), init_cmds, init_coord))
|
||||||
ui->set_client(client);
|
ui->set_client(client);
|
||||||
|
|
||||||
Server::instance().remove_accepter(this);
|
Server::instance().remove_accepter(this);
|
||||||
|
|
|
@ -22,6 +22,9 @@ struct disconnected : runtime_error
|
||||||
class FDWatcher;
|
class FDWatcher;
|
||||||
class UserInterface;
|
class UserInterface;
|
||||||
|
|
||||||
|
template<typename T> struct Optional;
|
||||||
|
struct BufferCoord;
|
||||||
|
|
||||||
using RemoteBuffer = Vector<char, MemoryDomain::Remote>;
|
using RemoteBuffer = Vector<char, MemoryDomain::Remote>;
|
||||||
|
|
||||||
// A remote client handle communication between a client running on the server
|
// A remote client handle communication between a client running on the server
|
||||||
|
@ -30,7 +33,8 @@ class RemoteClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
|
RemoteClient(StringView session, std::unique_ptr<UserInterface>&& ui,
|
||||||
const EnvVarMap& env_vars, StringView init_command);
|
const EnvVarMap& env_vars, StringView init_command,
|
||||||
|
Optional<BufferCoord> init_coord);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<UserInterface> m_ui;
|
std::unique_ptr<UserInterface> m_ui;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user