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:
Maxime Coste 2012-09-09 17:10:53 +02:00
parent 46565723b1
commit ae76b7dddc
6 changed files with 31 additions and 10 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);
});

View File

@ -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); }

View File

@ -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);