Wrap the shell params en env vars in a ShellContext struct

This commit is contained in:
Maxime Coste 2015-10-22 13:48:57 +01:00
parent 7346220e38
commit e51ef6c3c2
7 changed files with 39 additions and 44 deletions

View File

@ -323,8 +323,7 @@ TokenList parse(StringView line)
} }
String expand_token(const Token& token, const Context& context, String expand_token(const Token& token, const Context& context,
ConstArrayView<String> shell_params, const ShellContext& shell_context)
const EnvVarMap& env_vars)
{ {
auto& content = token.content(); auto& content = token.content();
switch (token.type()) switch (token.type())
@ -332,20 +331,20 @@ String expand_token(const Token& token, const Context& context,
case Token::Type::ShellExpand: case Token::Type::ShellExpand:
return ShellManager::instance().eval(content, context, {}, return ShellManager::instance().eval(content, context, {},
ShellManager::Flags::WaitForStdout, ShellManager::Flags::WaitForStdout,
shell_params, env_vars).first; shell_context).first;
case Token::Type::RegisterExpand: case Token::Type::RegisterExpand:
return context.main_sel_register_value(content).str(); return context.main_sel_register_value(content).str();
case Token::Type::OptionExpand: case Token::Type::OptionExpand:
return context.options()[content].get_as_string(); return context.options()[content].get_as_string();
case Token::Type::ValExpand: case Token::Type::ValExpand:
{ {
auto it = env_vars.find(content); auto it = shell_context.env_vars.find(content);
if (it != env_vars.end()) if (it != shell_context.env_vars.end())
return it->value; return it->value;
return ShellManager::instance().get_val(content, context); return ShellManager::instance().get_val(content, context);
} }
case Token::Type::RawEval: case Token::Type::RawEval:
return expand(content, context, shell_params, env_vars); return expand(content, context, shell_context);
case Token::Type::Raw: case Token::Type::Raw:
case Token::Type::RawQuoted: case Token::Type::RawQuoted:
return content; return content;
@ -357,8 +356,7 @@ String expand_token(const Token& token, const Context& context,
} }
String expand(StringView str, const Context& context, String expand(StringView str, const Context& context,
ConstArrayView<String> shell_params, const ShellContext& shell_context)
const EnvVarMap& env_vars)
{ {
Reader reader{str}; Reader reader{str};
String res; String res;
@ -380,7 +378,7 @@ String expand(StringView str, const Context& context,
{ {
res += reader.substr_from(beg); res += reader.substr_from(beg);
Token token = parse_percent_token<true>(reader); Token token = parse_percent_token<true>(reader);
res += expand_token(token, context, shell_params, env_vars); res += expand_token(token, context, shell_context);
beg = (++reader).pos; beg = (++reader).pos;
} }
else else
@ -431,9 +429,7 @@ void CommandManager::execute_single_command(CommandParameters params,
} }
void CommandManager::execute(StringView command_line, void CommandManager::execute(StringView command_line,
Context& context, Context& context, const ShellContext& shell_context)
ConstArrayView<String> shell_params,
const EnvVarMap& env_vars)
{ {
TokenList tokens = parse<true>(command_line); TokenList tokens = parse<true>(command_line);
if (tokens.empty()) if (tokens.empty())
@ -455,8 +451,7 @@ void CommandManager::execute(StringView command_line,
else if (it->type() == Token::Type::ShellExpand) else if (it->type() == Token::Type::ShellExpand)
{ {
auto shell_tokens = parse<true>(expand_token(*it, context, auto shell_tokens = parse<true>(expand_token(*it, context,
shell_params, shell_context));
env_vars));
it = tokens.erase(it); it = tokens.erase(it);
for (Token& token : shell_tokens) for (Token& token : shell_tokens)
it = ++tokens.emplace(it, std::move(token)); it = ++tokens.emplace(it, std::move(token));
@ -467,8 +462,7 @@ void CommandManager::execute(StringView command_line,
it -= shell_tokens.size() + 1; it -= shell_tokens.size() + 1;
} }
else else
params.push_back(expand_token(*it, context, shell_params, params.push_back(expand_token(*it, context, shell_context));
env_vars));
} }
execute_single_command(params, context, command_coord); execute_single_command(params, context, command_coord);
} }

View File

@ -61,8 +61,7 @@ class CommandManager : public Singleton<CommandManager>
{ {
public: public:
void execute(StringView command_line, Context& context, void execute(StringView command_line, Context& context,
ConstArrayView<String> shell_params = {}, const ShellContext& shell_context = {});
const EnvVarMap& env_vars = EnvVarMap{});
Completions complete(const Context& context, CompletionFlags flags, Completions complete(const Context& context, CompletionFlags flags,
StringView command_line, ByteCount cursor_pos); StringView command_line, ByteCount cursor_pos);
@ -104,8 +103,7 @@ private:
}; };
String expand(StringView str, const Context& context, String expand(StringView str, const Context& context,
ConstArrayView<String> shell_params = {}, const ShellContext& shell_context = {});
const EnvVarMap& env_vars = EnvVarMap{});
} }

View File

@ -675,8 +675,8 @@ const CommandDesc add_hook_cmd = {
ScopedSetBool disable_history{context.history_disabled()}; ScopedSetBool disable_history{context.history_disabled()};
if (regex_match(param.begin(), param.end(), regex)) if (regex_match(param.begin(), param.end(), regex))
CommandManager::instance().execute(command, context, {}, CommandManager::instance().execute(command, context,
{ { "hook_param", param.str() } }); { {}, { { "hook_param", param.str() } } });
}; };
auto group = parser.get_switch("group").value_or(StringView{}); auto group = parser.get_switch("group").value_or(StringView{});
get_scope(parser[0], context).hooks().add_hook(parser[1], group.str(), hook_func); get_scope(parser[0], context).hooks().add_hook(parser[1], group.str(), hook_func);
@ -738,7 +738,7 @@ void define_command(const ParametersParser& parser, Context& context)
{ {
desc = ParameterDesc{ {}, ParameterDesc::Flags::SwitchesAsPositional }; desc = ParameterDesc{ {}, ParameterDesc::Flags::SwitchesAsPositional };
cmd = [=](const ParametersParser& parser, Context& context) { cmd = [=](const ParametersParser& parser, Context& context) {
CommandManager::instance().execute(commands, context, params_to_shell(parser)); CommandManager::instance().execute(commands, context, { params_to_shell(parser) });
}; };
} }
else else
@ -795,13 +795,15 @@ void define_command(const ParametersParser& parser, Context& context)
{ {
if (flags == CompletionFlags::Fast) // no shell on fast completion if (flags == CompletionFlags::Fast) // no shell on fast completion
return Completions{}; return Completions{};
EnvVarMap vars = {
{ "token_to_complete", to_string(token_to_complete) }, ShellContext shell_context{
{ "pos_in_token", to_string(pos_in_token) } params,
{ { "token_to_complete", to_string(token_to_complete) },
{ "pos_in_token", to_string(pos_in_token) } }
}; };
String output = ShellManager::instance().eval(shell_cmd, context, {}, String output = ShellManager::instance().eval(shell_cmd, context, {},
ShellManager::Flags::WaitForStdout, ShellManager::Flags::WaitForStdout,
params, vars).first; shell_context).first;
return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) }; return Completions{ 0_byte, pos_in_token, split(output, '\n', 0) };
}; };
} }

View File

@ -485,7 +485,7 @@ HighlighterAndId create_line_highlighter(HighlighterParameters params)
auto func = [=](const Context& context, HighlightFlags flags, auto func = [=](const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer, BufferRange) DisplayBuffer& display_buffer, BufferRange)
{ {
const LineCount line = str_to_int_ifp(expand(option_name, context, {}, EnvVarMap{})).value_or(0) - 1; const LineCount line = str_to_int_ifp(expand(option_name, context)).value_or(0) - 1;
if (line < 0) if (line < 0)
return; return;
@ -527,7 +527,7 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
auto func = [=](const Context& context, HighlightFlags flags, auto func = [=](const Context& context, HighlightFlags flags,
DisplayBuffer& display_buffer, BufferRange) DisplayBuffer& display_buffer, BufferRange)
{ {
const CharCount column = str_to_int_ifp(expand(option_name, context, {}, EnvVarMap{})).value_or(0) - 1; const CharCount column = str_to_int_ifp(expand(option_name, context)).value_or(0) - 1;
if (column < 0) if (column < 0)
return; return;

View File

@ -381,8 +381,7 @@ void pipe(Context& context, NormalParams)
in += '\n'; in += '\n';
auto out = ShellManager::instance().eval( auto out = ShellManager::instance().eval(
real_cmd, context, in, real_cmd, context, in,
ShellManager::Flags::WaitForStdout, ShellManager::Flags::WaitForStdout).first;
{}, EnvVarMap{}).first;
if ((insert_eol or sel.max() == buffer.back_coord()) and if ((insert_eol or sel.max() == buffer.back_coord()) and
out.back() == '\n') out.back() == '\n')
@ -397,8 +396,7 @@ void pipe(Context& context, NormalParams)
for (auto& sel : selections) for (auto& sel : selections)
ShellManager::instance().eval(real_cmd, context, ShellManager::instance().eval(real_cmd, context,
content(buffer, sel), content(buffer, sel),
ShellManager::Flags::None, ShellManager::Flags::None);
{}, EnvVarMap{});
} }
}); });
} }
@ -425,9 +423,8 @@ void insert_output(Context& context, NormalParams)
if (real_cmd.empty()) if (real_cmd.empty())
return; return;
auto str = ShellManager::instance().eval(real_cmd, context, {}, auto str = ShellManager::instance().eval(
ShellManager::Flags::WaitForStdout, real_cmd, context, {}, ShellManager::Flags::WaitForStdout).first;
{}, EnvVarMap{}).first;
ScopedEdition edition(context); ScopedEdition edition(context);
context.selections().insert(str, mode); context.selections().insert(str, mode);
}); });
@ -781,8 +778,7 @@ void keep_pipe(Context& context, NormalParams)
for (auto& sel : context.selections()) for (auto& sel : context.selections())
{ {
if (shell_manager.eval(cmdline, context, content(buffer, sel), if (shell_manager.eval(cmdline, context, content(buffer, sel),
ShellManager::Flags::None, ShellManager::Flags::None).second == 0)
{}, EnvVarMap{}).second == 0)
keep.push_back(sel); keep.push_back(sel);
} }
if (keep.empty()) if (keep.empty())

View File

@ -83,7 +83,7 @@ pid_t spawn_process(StringView cmdline, ConstArrayView<String> params, ConstArra
std::pair<String, int> ShellManager::eval( std::pair<String, int> ShellManager::eval(
StringView cmdline, const Context& context, StringView input, StringView cmdline, const Context& context, StringView input,
Flags flags, ConstArrayView<String> params, const EnvVarMap& env_vars) Flags flags, const ShellContext& shell_context)
{ {
static const Regex re(R"(\bkak_(\w+)\b)"); static const Regex re(R"(\bkak_(\w+)\b)");
@ -100,10 +100,10 @@ std::pair<String, int> ShellManager::eval(
if (find_if(kak_env, match_name) != kak_env.end()) if (find_if(kak_env, match_name) != kak_env.end())
continue; continue;
auto var_it = env_vars.find(name); auto var_it = shell_context.env_vars.find(name);
try try
{ {
const String& value = var_it != env_vars.end() ? const String& value = var_it != shell_context.env_vars.end() ?
var_it->value : get_val(name, context); var_it->value : get_val(name, context);
kak_env.push_back(format("kak_{}={}", name, value)); kak_env.push_back(format("kak_{}={}", name, value));
@ -111,7 +111,7 @@ std::pair<String, int> ShellManager::eval(
} }
Pipe child_stdin, child_stdout, child_stderr; Pipe child_stdin, child_stdout, child_stderr;
pid_t pid = spawn_process(cmdline, params, kak_env, pid_t pid = spawn_process(cmdline, shell_context.params, kak_env,
child_stdin, child_stdout, child_stderr); child_stdin, child_stdout, child_stderr);
child_stdin.close_read_fd(); child_stdin.close_read_fd();

View File

@ -14,6 +14,12 @@ class Context;
using EnvVarRetriever = std::function<String (StringView name, const Context&)>; using EnvVarRetriever = std::function<String (StringView name, const Context&)>;
struct ShellContext
{
ConstArrayView<String> params;
EnvVarMap env_vars;
};
class ShellManager : public Singleton<ShellManager> class ShellManager : public Singleton<ShellManager>
{ {
public: public:
@ -28,8 +34,7 @@ public:
std::pair<String, int> eval(StringView cmdline, const Context& context, std::pair<String, int> eval(StringView cmdline, const Context& context,
StringView input = {}, StringView input = {},
Flags flags = Flags::WaitForStdout, Flags flags = Flags::WaitForStdout,
ConstArrayView<String> params = {}, const ShellContext& shell_context = {});
const EnvVarMap& env_vars = EnvVarMap{});
void register_env_var(StringView str, bool prefix, EnvVarRetriever retriever); 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;