summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client_manager.cc2
-rw-r--r--src/main.cc54
-rw-r--r--src/remote.cc24
-rw-r--r--src/remote.hh6
4 files changed, 58 insertions, 28 deletions
diff --git a/src/client_manager.cc b/src/client_manager.cc
index c7246a82..0053ebf0 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -22,8 +22,10 @@ void ClientManager::clear()
// So that clients destructor find the client manager empty
// so that local UI does not fork.
ClientList clients = std::move(m_clients);
+ clients.clear();
m_client_trash.clear();
m_free_windows.clear();
+ m_window_trash.clear();
}
String ClientManager::generate_name() const
diff --git a/src/main.cc b/src/main.cc
index a0fa3f09..a41ebad1 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -454,12 +454,13 @@ void signal_handler(int signal)
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
{
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)
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,
- StringView init_cmds, BufferCoord init_coord,
+ StringView init_cmds, Optional<BufferCoord> init_coord,
bool ignore_kakrc, bool daemon, bool readonly, UIType ui_type,
ConstArrayView<StringView> files)
{
@@ -812,6 +813,28 @@ int main(int argc, char* argv[])
(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"))
{
for (auto opt : { "n", "s", "d", "ro" })
@@ -823,32 +846,13 @@ int main(int argc, char* argv[])
}
}
String new_files;
- for (auto name : parser)
+ for (auto name : files)
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
{
- 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{});
try
@@ -864,7 +868,7 @@ int main(int argc, char* argv[])
raise(SIGTSTP);
return run_client(convert.session,
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);
}
}
}
diff --git a/src/remote.cc b/src/remote.cc
index 016ba23c..6a436d5c 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -8,6 +8,7 @@
#include "event_manager.hh"
#include "file.hh"
#include "id_map.hh"
+#include "optional.hh"
#include "user_interface.hh"
#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)
{
write(color.color);
@@ -219,6 +228,14 @@ public:
return res;
}
+ template<typename T>
+ Optional<T> read_optional()
+ {
+ if (not read<bool>())
+ return {};
+ return read<T>();
+ }
+
void reset()
{
m_stream.resize(0);
@@ -511,7 +528,8 @@ bool check_session(StringView session)
}
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))
{
int sock = connect_to(session);
@@ -519,6 +537,7 @@ RemoteClient::RemoteClient(StringView session, std::unique_ptr<UserInterface>&&
{
MsgWriter msg{m_send_buffer, MessageType::Connect};
msg.write(init_command);
+ msg.write(init_coord);
msg.write(m_ui->dimensions());
msg.write(env_vars);
}
@@ -652,12 +671,13 @@ private:
case MessageType::Connect:
{
auto init_cmds = m_reader.read<String>();
+ auto init_coord = m_reader.read_optional<BufferCoord>();
auto dimensions = m_reader.read<DisplayCoord>();
auto env_vars = m_reader.read_idmap<String, MemoryDomain::EnvVars>();
auto* ui = new RemoteUI{sock, dimensions};
if (auto* client = ClientManager::instance().create_client(
std::unique_ptr<UserInterface>(ui),
- std::move(env_vars), init_cmds, {}))
+ std::move(env_vars), init_cmds, init_coord))
ui->set_client(client);
Server::instance().remove_accepter(this);
diff --git a/src/remote.hh b/src/remote.hh
index 111a4973..b0cad37c 100644
--- a/src/remote.hh
+++ b/src/remote.hh
@@ -22,6 +22,9 @@ struct disconnected : runtime_error
class FDWatcher;
class UserInterface;
+template<typename T> struct Optional;
+struct BufferCoord;
+
using RemoteBuffer = Vector<char, MemoryDomain::Remote>;
// A remote client handle communication between a client running on the server
@@ -30,7 +33,8 @@ class RemoteClient
{
public:
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:
std::unique_ptr<UserInterface> m_ui;