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,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
const ShellContext& shell_context)
|
||||
{
|
||||
auto& content = token.content();
|
||||
switch (token.type())
|
||||
|
@ -332,20 +331,20 @@ String expand_token(const Token& token, const Context& context,
|
|||
case Token::Type::ShellExpand:
|
||||
return ShellManager::instance().eval(content, context, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
shell_params, env_vars).first;
|
||||
shell_context).first;
|
||||
case Token::Type::RegisterExpand:
|
||||
return context.main_sel_register_value(content).str();
|
||||
case Token::Type::OptionExpand:
|
||||
return context.options()[content].get_as_string();
|
||||
case Token::Type::ValExpand:
|
||||
{
|
||||
auto it = env_vars.find(content);
|
||||
if (it != env_vars.end())
|
||||
auto it = shell_context.env_vars.find(content);
|
||||
if (it != shell_context.env_vars.end())
|
||||
return it->value;
|
||||
return ShellManager::instance().get_val(content, context);
|
||||
}
|
||||
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::RawQuoted:
|
||||
return content;
|
||||
|
@ -357,8 +356,7 @@ String expand_token(const Token& token, const Context& context,
|
|||
}
|
||||
|
||||
String expand(StringView str, const Context& context,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
const ShellContext& shell_context)
|
||||
{
|
||||
Reader reader{str};
|
||||
String res;
|
||||
|
@ -380,7 +378,7 @@ String expand(StringView str, const Context& context,
|
|||
{
|
||||
res += reader.substr_from(beg);
|
||||
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;
|
||||
}
|
||||
else
|
||||
|
@ -431,9 +429,7 @@ void CommandManager::execute_single_command(CommandParameters params,
|
|||
}
|
||||
|
||||
void CommandManager::execute(StringView command_line,
|
||||
Context& context,
|
||||
ConstArrayView<String> shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
Context& context, const ShellContext& shell_context)
|
||||
{
|
||||
TokenList tokens = parse<true>(command_line);
|
||||
if (tokens.empty())
|
||||
|
@ -455,8 +451,7 @@ void CommandManager::execute(StringView command_line,
|
|||
else if (it->type() == Token::Type::ShellExpand)
|
||||
{
|
||||
auto shell_tokens = parse<true>(expand_token(*it, context,
|
||||
shell_params,
|
||||
env_vars));
|
||||
shell_context));
|
||||
it = tokens.erase(it);
|
||||
for (Token& token : shell_tokens)
|
||||
it = ++tokens.emplace(it, std::move(token));
|
||||
|
@ -467,8 +462,7 @@ void CommandManager::execute(StringView command_line,
|
|||
it -= shell_tokens.size() + 1;
|
||||
}
|
||||
else
|
||||
params.push_back(expand_token(*it, context, shell_params,
|
||||
env_vars));
|
||||
params.push_back(expand_token(*it, context, shell_context));
|
||||
}
|
||||
execute_single_command(params, context, command_coord);
|
||||
}
|
||||
|
|
|
@ -61,8 +61,7 @@ class CommandManager : public Singleton<CommandManager>
|
|||
{
|
||||
public:
|
||||
void execute(StringView command_line, Context& context,
|
||||
ConstArrayView<String> shell_params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = {});
|
||||
|
||||
Completions complete(const Context& context, CompletionFlags flags,
|
||||
StringView command_line, ByteCount cursor_pos);
|
||||
|
@ -104,8 +103,7 @@ private:
|
|||
};
|
||||
|
||||
String expand(StringView str, const Context& context,
|
||||
ConstArrayView<String> shell_params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = {});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -675,8 +675,8 @@ const CommandDesc add_hook_cmd = {
|
|||
ScopedSetBool disable_history{context.history_disabled()};
|
||||
|
||||
if (regex_match(param.begin(), param.end(), regex))
|
||||
CommandManager::instance().execute(command, context, {},
|
||||
{ { "hook_param", param.str() } });
|
||||
CommandManager::instance().execute(command, context,
|
||||
{ {}, { { "hook_param", param.str() } } });
|
||||
};
|
||||
auto group = parser.get_switch("group").value_or(StringView{});
|
||||
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 };
|
||||
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
|
||||
|
@ -795,13 +795,15 @@ void define_command(const ParametersParser& parser, Context& context)
|
|||
{
|
||||
if (flags == CompletionFlags::Fast) // no shell on fast completion
|
||||
return Completions{};
|
||||
EnvVarMap vars = {
|
||||
{ "token_to_complete", to_string(token_to_complete) },
|
||||
{ "pos_in_token", to_string(pos_in_token) }
|
||||
|
||||
ShellContext shell_context{
|
||||
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, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
params, vars).first;
|
||||
shell_context).first;
|
||||
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,
|
||||
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)
|
||||
return;
|
||||
|
||||
|
@ -527,7 +527,7 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params)
|
|||
auto func = [=](const Context& context, HighlightFlags flags,
|
||||
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)
|
||||
return;
|
||||
|
||||
|
|
|
@ -381,8 +381,7 @@ void pipe(Context& context, NormalParams)
|
|||
in += '\n';
|
||||
auto out = ShellManager::instance().eval(
|
||||
real_cmd, context, in,
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
{}, EnvVarMap{}).first;
|
||||
ShellManager::Flags::WaitForStdout).first;
|
||||
|
||||
if ((insert_eol or sel.max() == buffer.back_coord()) and
|
||||
out.back() == '\n')
|
||||
|
@ -397,8 +396,7 @@ void pipe(Context& context, NormalParams)
|
|||
for (auto& sel : selections)
|
||||
ShellManager::instance().eval(real_cmd, context,
|
||||
content(buffer, sel),
|
||||
ShellManager::Flags::None,
|
||||
{}, EnvVarMap{});
|
||||
ShellManager::Flags::None);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -425,9 +423,8 @@ void insert_output(Context& context, NormalParams)
|
|||
if (real_cmd.empty())
|
||||
return;
|
||||
|
||||
auto str = ShellManager::instance().eval(real_cmd, context, {},
|
||||
ShellManager::Flags::WaitForStdout,
|
||||
{}, EnvVarMap{}).first;
|
||||
auto str = ShellManager::instance().eval(
|
||||
real_cmd, context, {}, ShellManager::Flags::WaitForStdout).first;
|
||||
ScopedEdition edition(context);
|
||||
context.selections().insert(str, mode);
|
||||
});
|
||||
|
@ -781,8 +778,7 @@ void keep_pipe(Context& context, NormalParams)
|
|||
for (auto& sel : context.selections())
|
||||
{
|
||||
if (shell_manager.eval(cmdline, context, content(buffer, sel),
|
||||
ShellManager::Flags::None,
|
||||
{}, EnvVarMap{}).second == 0)
|
||||
ShellManager::Flags::None).second == 0)
|
||||
keep.push_back(sel);
|
||||
}
|
||||
if (keep.empty())
|
||||
|
|
|
@ -83,7 +83,7 @@ pid_t spawn_process(StringView cmdline, ConstArrayView<String> params, ConstArra
|
|||
|
||||
std::pair<String, int> ShellManager::eval(
|
||||
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)");
|
||||
|
||||
|
@ -100,10 +100,10 @@ std::pair<String, int> ShellManager::eval(
|
|||
if (find_if(kak_env, match_name) != kak_env.end())
|
||||
continue;
|
||||
|
||||
auto var_it = env_vars.find(name);
|
||||
auto var_it = shell_context.env_vars.find(name);
|
||||
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);
|
||||
|
||||
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;
|
||||
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.close_read_fd();
|
||||
|
|
|
@ -14,6 +14,12 @@ class Context;
|
|||
|
||||
using EnvVarRetriever = std::function<String (StringView name, const Context&)>;
|
||||
|
||||
struct ShellContext
|
||||
{
|
||||
ConstArrayView<String> params;
|
||||
EnvVarMap env_vars;
|
||||
};
|
||||
|
||||
class ShellManager : public Singleton<ShellManager>
|
||||
{
|
||||
public:
|
||||
|
@ -28,8 +34,7 @@ public:
|
|||
std::pair<String, int> eval(StringView cmdline, const Context& context,
|
||||
StringView input = {},
|
||||
Flags flags = Flags::WaitForStdout,
|
||||
ConstArrayView<String> params = {},
|
||||
const EnvVarMap& env_vars = EnvVarMap{});
|
||||
const ShellContext& shell_context = {});
|
||||
|
||||
void register_env_var(StringView str, bool prefix, EnvVarRetriever retriever);
|
||||
String get_val(StringView name, const Context& context) const;
|
||||
|
|
Loading…
Reference in New Issue
Block a user