ShellManager: init from a static list of env vars

No need to go through a static list and then copy them one by
one in a vector.
This commit is contained in:
Maxime Coste 2018-02-18 14:52:29 +11:00
parent d9cddf41f2
commit 5924694bda
3 changed files with 134 additions and 146 deletions

View File

@ -77,135 +77,124 @@ String config_directory()
return format("{}/kak", config_home); return format("{}/kak", config_home);
} }
void register_env_vars() static const EnvVarDesc builtin_env_vars[] = { {
{ "bufname", false,
static const struct { [](StringView name, const Context& context) -> String
const char* name; { return context.buffer().display_name(); }
bool prefix; }, {
String (*func)(StringView, const Context&); "buffile", false,
} env_vars[] = { { [](StringView name, const Context& context) -> String
"bufname", false, { return context.buffer().name(); }
[](StringView name, const Context& context) -> String }, {
{ return context.buffer().display_name(); } "buflist", false,
}, { [](StringView name, const Context& context)
"buffile", false, { return join(BufferManager::instance() |
[](StringView name, const Context& context) -> String transform(std::mem_fn(&Buffer::display_name)), ':'); }
{ return context.buffer().name(); } }, {
}, { "buf_line_count", false,
"buflist", false, [](StringView name, const Context& context) -> String
[](StringView name, const Context& context) { return to_string(context.buffer().line_count()); }
{ return join(BufferManager::instance() | }, {
transform(std::mem_fn(&Buffer::display_name)), ':'); } "timestamp", false,
}, { [](StringView name, const Context& context) -> String
"buf_line_count", false, { return to_string(context.buffer().timestamp()); }
[](StringView name, const Context& context) -> String }, {
{ return to_string(context.buffer().line_count()); } "history_id", false,
}, { [](StringView name, const Context& context) -> String
"timestamp", false, { return to_string(context.buffer().current_history_id()); }
[](StringView name, const Context& context) -> String }, {
{ return to_string(context.buffer().timestamp()); } "selection", false,
}, { [](StringView name, const Context& context)
"history_id", false, { const Selection& sel = context.selections().main();
[](StringView name, const Context& context) -> String return content(context.buffer(), sel); }
{ return to_string(context.buffer().current_history_id()); } }, {
}, { "selections", false,
"selection", false, [](StringView name, const Context& context)
[](StringView name, const Context& context) { return join(context.selections_content(), ':'); }
{ const Selection& sel = context.selections().main(); }, {
return content(context.buffer(), sel); } "runtime", false,
}, { [](StringView name, const Context& context)
"selections", false, { return runtime_directory(); }
[](StringView name, const Context& context) }, {
{ return join(context.selections_content(), ':'); } "config", false,
}, { [](StringView name, const Context& context)
"runtime", false, { return config_directory(); }
[](StringView name, const Context& context) }, {
{ return runtime_directory(); } "opt_", true,
}, { [](StringView name, const Context& context)
"config", false, { return context.options()[name.substr(4_byte)].get_as_string(); }
[](StringView name, const Context& context) }, {
{ return config_directory(); } "reg_", true,
}, { [](StringView name, const Context& context)
"opt_", true, { return context.main_sel_register_value(name.substr(4_byte)).str(); }
[](StringView name, const Context& context) }, {
{ return context.options()[name.substr(4_byte)].get_as_string(); } "client_env_", true,
}, { [](StringView name, const Context& context)
"reg_", true, { return context.client().get_env_var(name.substr(11_byte)).str(); }
[](StringView name, const Context& context) }, {
{ return context.main_sel_register_value(name.substr(4_byte)).str(); } "session", false,
}, { [](StringView name, const Context& context) -> String
"client_env_", true, { return Server::instance().session(); }
[](StringView name, const Context& context) }, {
{ return context.client().get_env_var(name.substr(11_byte)).str(); } "client", false,
}, { [](StringView name, const Context& context) -> String
"session", false, { return context.name(); }
[](StringView name, const Context& context) -> String }, {
{ return Server::instance().session(); } "client_pid", false,
}, { [](StringView name, const Context& context) -> String
"client", false, { return to_string(context.client().pid()); }
[](StringView name, const Context& context) -> String }, {
{ return context.name(); } "client_list", false,
}, { [](StringView name, const Context& context) -> String
"client_pid", false, { return join(ClientManager::instance() |
[](StringView name, const Context& context) -> String transform([](const std::unique_ptr<Client>& c) -> const String&
{ return to_string(context.client().pid()); } { return c->context().name(); }), ':'); }
}, { }, {
"client_list", false, "modified", false,
[](StringView name, const Context& context) -> String [](StringView name, const Context& context) -> String
{ return join(ClientManager::instance() | { return context.buffer().is_modified() ? "true" : "false"; }
transform([](const std::unique_ptr<Client>& c) -> const String& }, {
{ return c->context().name(); }), ':'); } "cursor_line", false,
}, { [](StringView name, const Context& context) -> String
"modified", false, { return to_string(context.selections().main().cursor().line + 1); }
[](StringView name, const Context& context) -> String }, {
{ return context.buffer().is_modified() ? "true" : "false"; } "cursor_column", false,
}, { [](StringView name, const Context& context) -> String
"cursor_line", false, { return to_string(context.selections().main().cursor().column + 1); }
[](StringView name, const Context& context) -> String }, {
{ return to_string(context.selections().main().cursor().line + 1); } "cursor_char_value", false,
}, { [](StringView name, const Context& context) -> String
"cursor_column", false, { auto coord = context.selections().main().cursor();
[](StringView name, const Context& context) -> String auto& buffer = context.buffer();
{ return to_string(context.selections().main().cursor().column + 1); } return to_string((size_t)utf8::codepoint(buffer.iterator_at(coord), buffer.end())); }
}, { }, {
"cursor_char_value", false, "cursor_char_column", false,
[](StringView name, const Context& context) -> String [](StringView name, const Context& context) -> String
{ auto coord = context.selections().main().cursor(); { auto coord = context.selections().main().cursor();
auto& buffer = context.buffer(); return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); }
return to_string((size_t)utf8::codepoint(buffer.iterator_at(coord), buffer.end())); } }, {
}, { "cursor_byte_offset", false,
"cursor_char_column", false, [](StringView name, const Context& context) -> String
[](StringView name, const Context& context) -> String { auto cursor = context.selections().main().cursor();
{ auto coord = context.selections().main().cursor(); return to_string(context.buffer().distance({0,0}, cursor)); }
return to_string(context.buffer()[coord.line].char_count_to(coord.column) + 1); } }, {
}, { "selection_desc", false,
"cursor_byte_offset", false, [](StringView name, const Context& context)
[](StringView name, const Context& context) -> String { return selection_to_string(context.selections().main()); }
{ auto cursor = context.selections().main().cursor(); }, {
return to_string(context.buffer().distance({0,0}, cursor)); } "selections_desc", false,
}, { [](StringView name, const Context& context)
"selection_desc", false, { return selection_list_to_string(context.selections()); }
[](StringView name, const Context& context) }, {
{ return selection_to_string(context.selections().main()); } "window_width", false,
}, { [](StringView name, const Context& context) -> String
"selections_desc", false, { return to_string(context.window().dimensions().column); }
[](StringView name, const Context& context) }, {
{ return selection_list_to_string(context.selections()); } "window_height", false,
}, { [](StringView name, const Context& context) -> String
"window_width", false, { return to_string(context.window().dimensions().line); }
[](StringView name, const Context& context) -> String }
{ return to_string(context.window().dimensions().column); } };
}, {
"window_height", false,
[](StringView name, const Context& context) -> String
{ return to_string(context.window().dimensions().line); }
}
};
ShellManager& shell_manager = ShellManager::instance();
for (auto& env_var : env_vars)
shell_manager.register_env_var(env_var.name, env_var.prefix, env_var.func);
}
void register_registers() void register_registers()
{ {
@ -584,7 +573,7 @@ int run_server(StringView session, StringView server_init,
StringRegistry string_registry; StringRegistry string_registry;
GlobalScope global_scope; GlobalScope global_scope;
ShellManager shell_manager; ShellManager shell_manager{builtin_env_vars};
CommandManager command_manager; CommandManager command_manager;
RegisterManager register_manager; RegisterManager register_manager;
HighlighterRegistry highlighter_registry; HighlighterRegistry highlighter_registry;
@ -594,7 +583,6 @@ int run_server(StringView session, StringView server_init,
BufferManager buffer_manager; BufferManager buffer_manager;
register_options(); register_options();
register_env_vars();
register_registers(); register_registers();
register_commands(); register_commands();
register_highlighters(); register_highlighters();
@ -731,14 +719,13 @@ int run_filter(StringView keystr, StringView commands, ConstArrayView<StringView
StringRegistry string_registry; StringRegistry string_registry;
GlobalScope global_scope; GlobalScope global_scope;
EventManager event_manager; EventManager event_manager;
ShellManager shell_manager; ShellManager shell_manager{builtin_env_vars};
CommandManager command_manager; CommandManager command_manager;
RegisterManager register_manager; RegisterManager register_manager;
ClientManager client_manager; ClientManager client_manager;
BufferManager buffer_manager; BufferManager buffer_manager;
register_options(); register_options();
register_env_vars();
register_registers(); register_registers();
register_commands(); register_commands();

View File

@ -23,7 +23,8 @@ extern char **environ;
namespace Kakoune namespace Kakoune
{ {
ShellManager::ShellManager() ShellManager::ShellManager(ConstArrayView<EnvVarDesc> builtin_env_vars)
: m_env_vars{builtin_env_vars}
{ {
// Get a guaranteed to be POSIX shell binary // Get a guaranteed to be POSIX shell binary
{ {
@ -293,12 +294,6 @@ std::pair<String, int> ShellManager::eval(
return { std::move(stdout_contents), WIFEXITED(status) ? WEXITSTATUS(status) : -1 }; return { std::move(stdout_contents), WIFEXITED(status) ? WEXITSTATUS(status) : -1 };
} }
void ShellManager::register_env_var(StringView str, bool prefix,
EnvVarRetriever retriever)
{
m_env_vars.push_back({ str.str(), prefix, std::move(retriever) });
}
String ShellManager::get_val(StringView name, const Context& context) const String ShellManager::get_val(StringView name, const Context& context) const
{ {
auto env_var = find_if(m_env_vars, [name](const EnvVarDesc& desc) { auto env_var = find_if(m_env_vars, [name](const EnvVarDesc& desc) {

View File

@ -12,18 +12,26 @@ namespace Kakoune
class Context; class Context;
using EnvVarRetriever = std::function<String (StringView name, const Context&)>;
struct ShellContext struct ShellContext
{ {
ConstArrayView<String> params; ConstArrayView<String> params;
EnvVarMap env_vars; EnvVarMap env_vars;
}; };
struct EnvVarDesc
{
using Retriever = String (*)(StringView name, const Context&);
StringView str;
bool prefix;
Retriever func;
};
class ShellManager : public Singleton<ShellManager> class ShellManager : public Singleton<ShellManager>
{ {
public: public:
ShellManager(); ShellManager(ConstArrayView<EnvVarDesc> builtin_env_vars);
enum class Flags enum class Flags
{ {
@ -37,7 +45,6 @@ public:
Flags flags = Flags::WaitForStdout, Flags flags = Flags::WaitForStdout,
const ShellContext& shell_context = {}); const ShellContext& shell_context = {});
void register_env_var(StringView str, bool prefix, EnvVarRetriever retriever);
String get_val(StringView name, const Context& context) const; String get_val(StringView name, const Context& context) const;
CandidateList complete_env_var(StringView prefix, ByteCount cursor_pos) const; CandidateList complete_env_var(StringView prefix, ByteCount cursor_pos) const;
@ -45,8 +52,7 @@ public:
private: private:
String m_shell; String m_shell;
struct EnvVarDesc { String str; bool prefix; EnvVarRetriever func; }; ConstArrayView<EnvVarDesc> m_env_vars;
Vector<EnvVarDesc, MemoryDomain::EnvVars> m_env_vars;
}; };
} }