Wrap the shell params en env vars in a ShellContext struct
This commit is contained in:
parent
7346220e38
commit
e51ef6c3c2
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user