summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-09-09 17:10:53 +0200
committerMaxime Coste <frrrwww@gmail.com>2012-09-09 17:10:53 +0200
commitae76b7dddc2973b809109329aabf15fdd676b7d6 (patch)
tree0ad185f833f8efaa8a0c72b75248a9e8882b9863 /src
parent46565723b1f146af461f93dd45a9c25d43ac553d (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/command_manager.cc4
-rw-r--r--src/command_manager.hh3
-rw-r--r--src/commands.cc18
-rw-r--r--src/main.cc2
-rw-r--r--src/shell_manager.cc14
-rw-r--r--src/shell_manager.hh2
6 files changed, 32 insertions, 11 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 1110583f..df23ca6e 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -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)
diff --git a/src/command_manager.hh b/src/command_manager.hh
index cbc6a2c7..84f764ee 100644
--- a/src/command_manager.hh
+++ b/src/command_manager.hh
@@ -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);
diff --git a/src/commands.cc b/src/commands.cc
index 60a9f5f2..07a62c69 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -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);
diff --git a/src/main.cc b/src/main.cc
index 5574327e..8dd9e30b 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -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);
});
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index cb6e94c7..f35b3ddc 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -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;
}
-
- execlp("sh", "sh", "-c", cmdline.c_str(), NULL);
+ 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);
+
+ execvp("sh", (char* const*)execparams.data());
exit(-1);
}
catch (...) { exit(-1); }
diff --git a/src/shell_manager.hh b/src/shell_manager.hh
index 6ce3aada..615b19ec 100644
--- a/src/shell_manager.hh
+++ b/src/shell_manager.hh
@@ -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);