Add support for shell script parameters
Now %sh{ ... } can access positional parameters through standard shell construct, allowing simple handling of variable parameters. def command accepts -shell-params flag to use this facility.
This commit is contained in:
parent
46565723b1
commit
ae76b7dddc
|
@ -211,6 +211,7 @@ void CommandManager::execute_single_command(const CommandParameters& params,
|
|||
|
||||
void CommandManager::execute(const String& command_line,
|
||||
Context& context,
|
||||
const memoryview<String>& shell_params,
|
||||
const EnvVarMap& env_vars)
|
||||
{
|
||||
TokenList tokens = parse(command_line);
|
||||
|
@ -223,7 +224,8 @@ void CommandManager::execute(const String& command_line,
|
|||
if (it->type() == Token::Type::ShellExpand)
|
||||
{
|
||||
String output = ShellManager::instance().eval(it->content(),
|
||||
context, env_vars);
|
||||
context, shell_params,
|
||||
env_vars);
|
||||
TokenList shell_tokens = parse(output);
|
||||
it = tokens.erase(it);
|
||||
for (auto& token : shell_tokens)
|
||||
|
|
|
@ -53,7 +53,8 @@ class CommandManager : public Singleton<CommandManager>
|
|||
{
|
||||
public:
|
||||
void execute(const String& command_line, Context& context,
|
||||
const EnvVarMap& env_vars = EnvVarMap());
|
||||
const memoryview<String>& shell_params = {},
|
||||
const EnvVarMap& env_vars = {});
|
||||
|
||||
Completions complete(const Context& context,
|
||||
const String& command_line, CharCount cursor_pos);
|
||||
|
|
|
@ -534,6 +534,7 @@ void define_command(const CommandParameters& params, Context& context)
|
|||
{
|
||||
ParametersParser parser(params,
|
||||
{ { "env-params", false },
|
||||
{ "shell-params", false },
|
||||
{ "allow-override", false },
|
||||
{ "shell-completion", true } });
|
||||
|
||||
|
@ -552,10 +553,16 @@ void define_command(const CommandParameters& params, Context& context)
|
|||
if (parser.has_option("env-params"))
|
||||
{
|
||||
cmd = [=](const CommandParameters& params, Context& context) {
|
||||
CommandManager::instance().execute(commands, context,
|
||||
CommandManager::instance().execute(commands, context, {},
|
||||
params_to_env_var_map(params));
|
||||
};
|
||||
}
|
||||
if (parser.has_option("shell-params"))
|
||||
{
|
||||
cmd = [=](const CommandParameters& params, Context& context) {
|
||||
CommandManager::instance().execute(commands, context, params, {});
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = [=](const CommandParameters& params, Context& context) {
|
||||
|
@ -571,10 +578,11 @@ void define_command(const CommandParameters& params, Context& context)
|
|||
auto completer = [=](const Context& context, const CommandParameters& params,
|
||||
size_t token_to_complete, CharCount pos_in_token)
|
||||
{
|
||||
EnvVarMap vars = params_to_env_var_map(params);
|
||||
vars["token_to_complete"] = int_to_str(token_to_complete);
|
||||
vars["pos_in_token"] = int_to_str((int)pos_in_token);
|
||||
String output = ShellManager::instance().eval(shell_cmd, context, vars);
|
||||
EnvVarMap vars = {
|
||||
{"token_to_complete", int_to_str(token_to_complete) },
|
||||
{ "pos_in_token", int_to_str((int)pos_in_token) }
|
||||
};
|
||||
String output = ShellManager::instance().eval(shell_cmd, context, params, vars);
|
||||
return split(output, '\n');
|
||||
};
|
||||
CommandManager::instance().register_command(cmd_name, cmd, completer);
|
||||
|
|
|
@ -102,7 +102,7 @@ void do_pipe(Context& context)
|
|||
std::vector<String> strings;
|
||||
for (auto& sel : const_cast<const Editor&>(context.editor()).selections())
|
||||
strings.push_back(ShellManager::instance().pipe(String(sel.begin(), sel.end()),
|
||||
cmdline, context, {}));
|
||||
cmdline, context, {}, {}));
|
||||
editor.replace(strings);
|
||||
});
|
||||
|
||||
|
|
|
@ -16,13 +16,15 @@ ShellManager::ShellManager()
|
|||
}
|
||||
|
||||
String ShellManager::eval(const String& cmdline, const Context& context,
|
||||
const memoryview<String>& params,
|
||||
const EnvVarMap& env_vars)
|
||||
{
|
||||
return pipe("", cmdline, context, env_vars);
|
||||
return pipe("", cmdline, context, params, env_vars);
|
||||
}
|
||||
|
||||
String ShellManager::pipe(const String& input,
|
||||
const String& cmdline, const Context& context,
|
||||
const memoryview<String>& params,
|
||||
const EnvVarMap& env_vars)
|
||||
{
|
||||
int write_pipe[2]; // child stdin
|
||||
|
@ -114,8 +116,14 @@ String ShellManager::pipe(const String& input,
|
|||
|
||||
++it;
|
||||
}
|
||||
std::vector<const char*> execparams = { "sh", "-c", cmdline.c_str() };
|
||||
if (not params.empty())
|
||||
execparams.push_back("sh");
|
||||
for (auto& param : params)
|
||||
execparams.push_back(param.c_str());
|
||||
execparams.push_back(NULL);
|
||||
|
||||
execlp("sh", "sh", "-c", cmdline.c_str(), NULL);
|
||||
execvp("sh", (char* const*)execparams.data());
|
||||
exit(-1);
|
||||
}
|
||||
catch (...) { exit(-1); }
|
||||
|
|
|
@ -19,10 +19,12 @@ public:
|
|||
ShellManager();
|
||||
|
||||
String eval(const String& cmdline, const Context& context,
|
||||
const memoryview<String>& params,
|
||||
const EnvVarMap& env_vars);
|
||||
|
||||
String pipe(const String& input,
|
||||
const String& cmdline, const Context& context,
|
||||
const memoryview<String>& params,
|
||||
const EnvVarMap& env_vars);
|
||||
|
||||
void register_env_var(const String& regex, EnvVarRetriever retriever);
|
||||
|
|
Loading…
Reference in New Issue
Block a user