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,
|
void CommandManager::execute(const String& command_line,
|
||||||
Context& context,
|
Context& context,
|
||||||
|
const memoryview<String>& shell_params,
|
||||||
const EnvVarMap& env_vars)
|
const EnvVarMap& env_vars)
|
||||||
{
|
{
|
||||||
TokenList tokens = parse(command_line);
|
TokenList tokens = parse(command_line);
|
||||||
|
@ -223,7 +224,8 @@ void CommandManager::execute(const String& command_line,
|
||||||
if (it->type() == Token::Type::ShellExpand)
|
if (it->type() == Token::Type::ShellExpand)
|
||||||
{
|
{
|
||||||
String output = ShellManager::instance().eval(it->content(),
|
String output = ShellManager::instance().eval(it->content(),
|
||||||
context, env_vars);
|
context, shell_params,
|
||||||
|
env_vars);
|
||||||
TokenList shell_tokens = parse(output);
|
TokenList shell_tokens = parse(output);
|
||||||
it = tokens.erase(it);
|
it = tokens.erase(it);
|
||||||
for (auto& token : shell_tokens)
|
for (auto& token : shell_tokens)
|
||||||
|
|
|
@ -53,7 +53,8 @@ class CommandManager : public Singleton<CommandManager>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void execute(const String& command_line, Context& context,
|
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,
|
Completions complete(const Context& context,
|
||||||
const String& command_line, CharCount cursor_pos);
|
const String& command_line, CharCount cursor_pos);
|
||||||
|
|
|
@ -534,6 +534,7 @@ void define_command(const CommandParameters& params, Context& context)
|
||||||
{
|
{
|
||||||
ParametersParser parser(params,
|
ParametersParser parser(params,
|
||||||
{ { "env-params", false },
|
{ { "env-params", false },
|
||||||
|
{ "shell-params", false },
|
||||||
{ "allow-override", false },
|
{ "allow-override", false },
|
||||||
{ "shell-completion", true } });
|
{ "shell-completion", true } });
|
||||||
|
|
||||||
|
@ -552,10 +553,16 @@ void define_command(const CommandParameters& params, Context& context)
|
||||||
if (parser.has_option("env-params"))
|
if (parser.has_option("env-params"))
|
||||||
{
|
{
|
||||||
cmd = [=](const CommandParameters& params, Context& context) {
|
cmd = [=](const CommandParameters& params, Context& context) {
|
||||||
CommandManager::instance().execute(commands, context,
|
CommandManager::instance().execute(commands, context, {},
|
||||||
params_to_env_var_map(params));
|
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
|
else
|
||||||
{
|
{
|
||||||
cmd = [=](const CommandParameters& params, Context& context) {
|
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,
|
auto completer = [=](const Context& context, const CommandParameters& params,
|
||||||
size_t token_to_complete, CharCount pos_in_token)
|
size_t token_to_complete, CharCount pos_in_token)
|
||||||
{
|
{
|
||||||
EnvVarMap vars = params_to_env_var_map(params);
|
EnvVarMap vars = {
|
||||||
vars["token_to_complete"] = int_to_str(token_to_complete);
|
{"token_to_complete", int_to_str(token_to_complete) },
|
||||||
vars["pos_in_token"] = int_to_str((int)pos_in_token);
|
{ "pos_in_token", int_to_str((int)pos_in_token) }
|
||||||
String output = ShellManager::instance().eval(shell_cmd, context, vars);
|
};
|
||||||
|
String output = ShellManager::instance().eval(shell_cmd, context, params, vars);
|
||||||
return split(output, '\n');
|
return split(output, '\n');
|
||||||
};
|
};
|
||||||
CommandManager::instance().register_command(cmd_name, cmd, completer);
|
CommandManager::instance().register_command(cmd_name, cmd, completer);
|
||||||
|
|
|
@ -102,7 +102,7 @@ void do_pipe(Context& context)
|
||||||
std::vector<String> strings;
|
std::vector<String> strings;
|
||||||
for (auto& sel : const_cast<const Editor&>(context.editor()).selections())
|
for (auto& sel : const_cast<const Editor&>(context.editor()).selections())
|
||||||
strings.push_back(ShellManager::instance().pipe(String(sel.begin(), sel.end()),
|
strings.push_back(ShellManager::instance().pipe(String(sel.begin(), sel.end()),
|
||||||
cmdline, context, {}));
|
cmdline, context, {}, {}));
|
||||||
editor.replace(strings);
|
editor.replace(strings);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,15 @@ ShellManager::ShellManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
String ShellManager::eval(const String& cmdline, const Context& context,
|
String ShellManager::eval(const String& cmdline, const Context& context,
|
||||||
|
const memoryview<String>& params,
|
||||||
const EnvVarMap& env_vars)
|
const EnvVarMap& env_vars)
|
||||||
{
|
{
|
||||||
return pipe("", cmdline, context, env_vars);
|
return pipe("", cmdline, context, params, env_vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
String ShellManager::pipe(const String& input,
|
String ShellManager::pipe(const String& input,
|
||||||
const String& cmdline, const Context& context,
|
const String& cmdline, const Context& context,
|
||||||
|
const memoryview<String>& params,
|
||||||
const EnvVarMap& env_vars)
|
const EnvVarMap& env_vars)
|
||||||
{
|
{
|
||||||
int write_pipe[2]; // child stdin
|
int write_pipe[2]; // child stdin
|
||||||
|
@ -114,8 +116,14 @@ String ShellManager::pipe(const String& input,
|
||||||
|
|
||||||
++it;
|
++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);
|
exit(-1);
|
||||||
}
|
}
|
||||||
catch (...) { exit(-1); }
|
catch (...) { exit(-1); }
|
||||||
|
|
|
@ -19,10 +19,12 @@ public:
|
||||||
ShellManager();
|
ShellManager();
|
||||||
|
|
||||||
String eval(const String& cmdline, const Context& context,
|
String eval(const String& cmdline, const Context& context,
|
||||||
|
const memoryview<String>& params,
|
||||||
const EnvVarMap& env_vars);
|
const EnvVarMap& env_vars);
|
||||||
|
|
||||||
String pipe(const String& input,
|
String pipe(const String& input,
|
||||||
const String& cmdline, const Context& context,
|
const String& cmdline, const Context& context,
|
||||||
|
const memoryview<String>& params,
|
||||||
const EnvVarMap& env_vars);
|
const EnvVarMap& env_vars);
|
||||||
|
|
||||||
void register_env_var(const String& regex, EnvVarRetriever retriever);
|
void register_env_var(const String& regex, EnvVarRetriever retriever);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user