diff --git a/src/command_manager.cc b/src/command_manager.cc index a554d35d..8c3a6454 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -323,8 +323,7 @@ TokenList parse(StringView line) } String expand_token(const Token& token, const Context& context, - ConstArrayView 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 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(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 shell_params, - const EnvVarMap& env_vars) + Context& context, const ShellContext& shell_context) { TokenList tokens = parse(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(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); } diff --git a/src/command_manager.hh b/src/command_manager.hh index 9592bce6..d47dbdbc 100644 --- a/src/command_manager.hh +++ b/src/command_manager.hh @@ -61,8 +61,7 @@ class CommandManager : public Singleton { public: void execute(StringView command_line, Context& context, - ConstArrayView 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 shell_params = {}, - const EnvVarMap& env_vars = EnvVarMap{}); + const ShellContext& shell_context = {}); } diff --git a/src/commands.cc b/src/commands.cc index 8d91acbd..863170ee 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -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) }; }; } diff --git a/src/highlighters.cc b/src/highlighters.cc index 648e6072..17f32cf4 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -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; diff --git a/src/normal.cc b/src/normal.cc index db878909..2ec36d10 100644 --- a/src/normal.cc +++ b/src/normal.cc @@ -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()) diff --git a/src/shell_manager.cc b/src/shell_manager.cc index e6fb068c..6ac02d65 100644 --- a/src/shell_manager.cc +++ b/src/shell_manager.cc @@ -83,7 +83,7 @@ pid_t spawn_process(StringView cmdline, ConstArrayView params, ConstArra std::pair ShellManager::eval( StringView cmdline, const Context& context, StringView input, - Flags flags, ConstArrayView 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 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 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(); diff --git a/src/shell_manager.hh b/src/shell_manager.hh index 6394f5e3..b7e462e7 100644 --- a/src/shell_manager.hh +++ b/src/shell_manager.hh @@ -14,6 +14,12 @@ class Context; using EnvVarRetriever = std::function; +struct ShellContext +{ + ConstArrayView params; + EnvVarMap env_vars; +}; + class ShellManager : public Singleton { public: @@ -28,8 +34,7 @@ public: std::pair eval(StringView cmdline, const Context& context, StringView input = {}, Flags flags = Flags::WaitForStdout, - ConstArrayView 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;