summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.cc16
-rw-r--r--src/client.hh9
-rw-r--r--src/client_manager.cc4
-rw-r--r--src/client_manager.hh2
-rw-r--r--src/env_vars.cc20
-rw-r--r--src/env_vars.hh18
-rw-r--r--src/main.cc7
-rw-r--r--src/remote.cc32
-rw-r--r--src/remote.hh4
-rw-r--r--src/shell_manager.hh4
10 files changed, 106 insertions, 10 deletions
diff --git a/src/client.cc b/src/client.cc
index 4f8dfbdf..cda0ef5c 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -14,10 +14,13 @@ namespace Kakoune
Client::Client(std::unique_ptr<UserInterface>&& ui,
std::unique_ptr<Window>&& window,
- SelectionList selections, String name)
+ SelectionList selections,
+ EnvVarMap env_vars,
+ String name)
: m_ui{std::move(ui)}, m_window{std::move(window)},
m_input_handler{m_window->buffer(), std::move(selections),
- std::move(name)}
+ std::move(name)},
+ m_env_vars(env_vars)
{
context().set_client(*this);
context().set_window(*m_window);
@@ -151,4 +154,13 @@ void Client::check_buffer_fs_timestamp()
reload_buffer(context(), filename);
}
+const String& Client::get_env_var(const String& name) const
+{
+ auto it = m_env_vars.find(name);
+ static String empty{};
+ if (it == m_env_vars.end())
+ return empty;
+ return it->second;
+}
+
}
diff --git a/src/client.hh b/src/client.hh
index ac191542..56b8504b 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -5,6 +5,7 @@
#include "utils.hh"
#include "display_buffer.hh"
#include "input_handler.hh"
+#include "env_vars.hh"
namespace Kakoune
{
@@ -17,7 +18,9 @@ class Client : public SafeCountable
public:
Client(std::unique_ptr<UserInterface>&& ui,
std::unique_ptr<Window>&& window,
- SelectionList selections, String name);
+ SelectionList selections,
+ EnvVarMap env_vars,
+ String name);
~Client();
// handle all the keys currently available in the user interface
@@ -37,12 +40,16 @@ public:
void change_buffer(Buffer& buffer);
+ const String& get_env_var(const String& name) const;
+
private:
DisplayLine generate_mode_line() const;
std::unique_ptr<UserInterface> m_ui;
std::unique_ptr<Window> m_window;
+ EnvVarMap m_env_vars;
+
InputHandler m_input_handler;
DisplayLine m_status_line;
diff --git a/src/client_manager.cc b/src/client_manager.cc
index f818e226..9fe18ea7 100644
--- a/src/client_manager.cc
+++ b/src/client_manager.cc
@@ -25,12 +25,14 @@ String ClientManager::generate_name() const
}
Client* ClientManager::create_client(std::unique_ptr<UserInterface>&& ui,
+ EnvVarMap env_vars,
const String& init_commands)
{
Buffer& buffer = **BufferManager::instance().begin();
WindowAndSelections ws = get_free_window(buffer);
Client* client = new Client{std::move(ui), std::move(ws.window),
- std::move(ws.selections), generate_name()};
+ std::move(ws.selections), std::move(env_vars),
+ generate_name()};
m_clients.emplace_back(client);
try
{
diff --git a/src/client_manager.hh b/src/client_manager.hh
index cc5c6c0c..b25fe525 100644
--- a/src/client_manager.hh
+++ b/src/client_manager.hh
@@ -22,7 +22,7 @@ public:
~ClientManager();
Client* create_client(std::unique_ptr<UserInterface>&& ui,
- const String& init_cmd);
+ EnvVarMap env_vars, const String& init_cmd);
bool empty() const { return m_clients.empty(); }
size_t count() const { return m_clients.size(); }
diff --git a/src/env_vars.cc b/src/env_vars.cc
new file mode 100644
index 00000000..d6c04fa3
--- /dev/null
+++ b/src/env_vars.cc
@@ -0,0 +1,20 @@
+#include "env_vars.hh"
+
+namespace Kakoune
+{
+
+EnvVarMap get_env_vars()
+{
+ EnvVarMap env_vars;
+ for (char** it = environ; *it; ++it)
+ {
+ const char* name = *it;
+ const char* value = name;
+ while (*value != 0 and *value != '=')
+ ++value;
+ env_vars[String{name, value}] = (*value == '=') ? value+1 : value;
+ }
+ return env_vars;
+}
+
+}
diff --git a/src/env_vars.hh b/src/env_vars.hh
new file mode 100644
index 00000000..087d51a7
--- /dev/null
+++ b/src/env_vars.hh
@@ -0,0 +1,18 @@
+#ifndef env_vars_hh_INCLUDED
+#define env_vars_hh_INCLUDED
+
+#include "string.hh"
+
+#include <unordered_map>
+
+namespace Kakoune
+{
+
+using EnvVarMap = std::unordered_map<String, String>;
+
+EnvVarMap get_env_vars();
+
+}
+
+#endif // env_vars_hh_INCLUDED
+
diff --git a/src/main.cc b/src/main.cc
index a026f664..43b9675a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -102,6 +102,10 @@ void register_env_vars()
[](const String& name, const Context& context) -> String
{ return RegisterManager::instance()[name[4]].values(context)[0]; }
}, {
+ "client_env_.+",
+ [](const String& name, const Context& context) -> String
+ { return context.client().get_env_var(name.substr(11_byte)); }
+ }, {
"session",
[](const String& name, const Context& context) -> String
{ return Server::instance().session(); }
@@ -189,7 +193,7 @@ void create_local_client(const String& init_command)
UserInterface* ui = new LocalNCursesUI{};
static Client* client = ClientManager::instance().create_client(
- std::unique_ptr<UserInterface>{ui}, init_command);
+ std::unique_ptr<UserInterface>{ui}, get_env_vars(), init_command);
signal(SIGHUP, [](int) {
if (client)
ClientManager::instance().remove_client(*client);
@@ -221,6 +225,7 @@ int run_client(const String& session, const String& init_command)
EventManager event_manager;
auto client = connect_to(session,
std::unique_ptr<UserInterface>{new NCursesUI{}},
+ get_env_vars(),
init_command);
while (true)
event_manager.handle_next_events();
diff --git a/src/remote.cc b/src/remote.cc
index 2d71a888..72e3425f 100644
--- a/src/remote.cc
+++ b/src/remote.cc
@@ -74,6 +74,17 @@ public:
write(memoryview<T>(vec));
}
+ template<typename Key, typename Val>
+ void write(const std::unordered_map<Key, Val>& map)
+ {
+ write<uint32_t>(map.size());
+ for (auto& val : map)
+ {
+ write(val.first);
+ write(val.second);
+ }
+ }
+
void write(Color color)
{
write(color.color);
@@ -210,6 +221,20 @@ DisplayBuffer read<DisplayBuffer>(int socket)
return db;
}
+template<typename Key, typename Val>
+std::unordered_map<Key, Val> read_map(int socket)
+{
+ uint32_t size = read<uint32_t>(socket);
+ std::unordered_map<Key, Val> res;
+ while (size--)
+ {
+ auto key = read<Key>(socket);
+ auto val = read<Val>(socket);
+ res.insert({std::move(key), std::move(val)});
+ }
+ return res;
+}
+
class RemoteUI : public UserInterface
{
public:
@@ -368,12 +393,15 @@ void RemoteUI::set_input_callback(InputCallback callback)
}
RemoteClient::RemoteClient(int socket, std::unique_ptr<UserInterface>&& ui,
+ const EnvVarMap& env_vars,
const String& init_command)
: m_ui(std::move(ui)), m_dimensions(m_ui->dimensions()),
m_socket_watcher{socket, [this](FDWatcher&){ process_next_message(); }}
{
Message msg(socket);
msg.write(init_command.c_str(), (int)init_command.length()+1);
+ msg.write(env_vars);
+
Key key{ resize_modifier, Codepoint(((int)m_dimensions.line << 16) |
(int)m_dimensions.column) };
msg.write(key);
@@ -446,6 +474,7 @@ void RemoteClient::write_next_key()
std::unique_ptr<RemoteClient> connect_to(const String& session,
std::unique_ptr<UserInterface>&& ui,
+ const EnvVarMap& env_vars,
const String& init_command)
{
auto filename = "/tmp/kak-" + session;
@@ -459,6 +488,7 @@ std::unique_ptr<RemoteClient> connect_to(const String& session,
throw connection_failed(filename);
return std::unique_ptr<RemoteClient>{new RemoteClient{sock, std::move(ui),
+ env_vars,
init_command}};
}
@@ -525,8 +555,10 @@ private:
}
if (c == 0) // end of initial command stream, go to interactive ui
{
+ EnvVarMap env_vars = read_map<String, String>(socket);
std::unique_ptr<UserInterface> ui{new RemoteUI{socket}};
ClientManager::instance().create_client(std::move(ui),
+ std::move(env_vars),
m_buffer);
Server::instance().remove_accepter(this);
return;
diff --git a/src/remote.hh b/src/remote.hh
index 22259930..cebd56cf 100644
--- a/src/remote.hh
+++ b/src/remote.hh
@@ -4,6 +4,7 @@
#include "display_buffer.hh"
#include "event_manager.hh"
#include "user_interface.hh"
+#include "env_vars.hh"
namespace Kakoune
{
@@ -23,7 +24,7 @@ class RemoteClient
{
public:
RemoteClient(int socket, std::unique_ptr<UserInterface>&& ui,
- const String& init_command);
+ const EnvVarMap& env_vars, const String& init_command);
private:
void process_next_message();
@@ -35,6 +36,7 @@ private:
};
std::unique_ptr<RemoteClient> connect_to(const String& session,
std::unique_ptr<UserInterface>&& ui,
+ const EnvVarMap& env_vars,
const String& init_command);
void send_command(const String& session, const String& command);
diff --git a/src/shell_manager.hh b/src/shell_manager.hh
index 0774fdf2..a6fe38fd 100644
--- a/src/shell_manager.hh
+++ b/src/shell_manager.hh
@@ -3,15 +3,13 @@
#include "string.hh"
#include "utils.hh"
-
-#include <unordered_map>
+#include "env_vars.hh"
namespace Kakoune
{
class Context;
using EnvVarRetriever = std::function<String (const String& name, const Context&)>;
-using EnvVarMap = std::unordered_map<String, String>;
class ShellManager : public Singleton<ShellManager>
{