Add '$' for keeping selections that passes a shell command

'$' pipes each selections through a given shell command, and
only keeps the one that have an exit code of 0

Fixes #36
This commit is contained in:
Maxime Coste 2014-05-05 18:00:24 +01:00
parent e6bda60ca4
commit 24f6471431
5 changed files with 45 additions and 7 deletions

View File

@ -303,6 +303,9 @@ _alt-k_ allows you to enter a regex and keep only the selections that
contains a match for this regex. using _alt-K_ you can keep the selections contains a match for this regex. using _alt-K_ you can keep the selections
not containing a match. not containing a match.
_$_ allows you to enter a shell command and pipe each selections to it.
Selections whose shell command returns 0 will be kept, other will be dropped.
Object Selection Object Selection
---------------- ----------------

View File

@ -1,5 +1,5 @@
┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┲━━━━━━━━━━━━━━┓ ┌───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┬───────┲━━━━━━━━━━━━━━┓
│ upper│ │convtab│ │ │sel all│ │ align│pattern│ │ │ │ ┃ ⇤ ┃ │ upper│ │convtab│ │selpipe│sel all│ │ align│pattern│ │ │ │ ┃ ⇤ ┃
├┄┄CASE┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┨ ┃ ├┄┄CASE┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┼┄┄┄┄┄┄┄┨ ┃
│ lower│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ │ ┃ ┃ │ lower│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ │ ┃ ┃
┢━━━━━━━┷━━━┱───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┺━━━┳━━━━━━━━━━┫ ┢━━━━━━━┷━━━┱───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┴───┬───┺━━━┳━━━━━━━━━━┫

View File

@ -791,6 +791,29 @@ void keep(Context& context, int)
}); });
} }
void keep_pipe(Context& context, int)
{
context.input_handler().prompt(
"keep pipe:", "", get_color("Prompt"), shell_complete,
[](const String& cmdline, PromptEvent event, Context& context) {
if (event != PromptEvent::Validate)
return;
const Buffer& buffer = context.buffer();
auto& shell_manager = ShellManager::instance();
SelectionList keep;
for (auto& sel : context.selections())
{
int status = 0;
shell_manager.pipe(content(buffer, sel), cmdline, context,
{}, EnvVarMap{}, &status);
if (status == 0)
keep.push_back(sel);
}
if (keep.empty())
throw runtime_error("no selections remaining");
context.selections() = std::move(keep);
});
}
template<bool indent_empty = false> template<bool indent_empty = false>
void indent(Context& context, int) void indent(Context& context, int)
{ {
@ -1405,6 +1428,7 @@ KeyMap keymap =
{ alt('k'), keep<true> }, { alt('k'), keep<true> },
{ alt('K'), keep<false> }, { alt('K'), keep<false> },
{ '$', keep_pipe },
{ '<', deindent<true> }, { '<', deindent<true> },
{ '>', indent<false> }, { '>', indent<false> },

View File

@ -18,15 +18,17 @@ ShellManager::ShellManager()
String ShellManager::eval(StringView cmdline, const Context& context, String ShellManager::eval(StringView cmdline, const Context& context,
memoryview<String> params, memoryview<String> params,
const EnvVarMap& env_vars) const EnvVarMap& env_vars,
int* exit_status)
{ {
return pipe("", cmdline, context, params, env_vars); return pipe("", cmdline, context, params, env_vars, exit_status);
} }
String ShellManager::pipe(StringView input, String ShellManager::pipe(StringView input,
StringView cmdline, const Context& context, StringView cmdline, const Context& context,
memoryview<String> params, memoryview<String> params,
const EnvVarMap& env_vars) const EnvVarMap& env_vars,
int* exit_status)
{ {
int write_pipe[2]; // child stdin int write_pipe[2]; // child stdin
int read_pipe[2]; // child stdout int read_pipe[2]; // child stdout
@ -66,7 +68,14 @@ String ShellManager::pipe(StringView input,
if (not errorout.empty()) if (not errorout.empty())
write_debug("shell stderr: <<<\n" + errorout + ">>>"); write_debug("shell stderr: <<<\n" + errorout + ">>>");
waitpid(pid, nullptr, 0); waitpid(pid, exit_status, 0);
if (exit_status)
{
if (WIFEXITED(*exit_status))
*exit_status = WEXITSTATUS(*exit_status);
else
*exit_status = -1;
}
} }
else try else try
{ {

View File

@ -18,12 +18,14 @@ public:
String eval(StringView cmdline, const Context& context, String eval(StringView cmdline, const Context& context,
memoryview<String> params, memoryview<String> params,
const EnvVarMap& env_vars); const EnvVarMap& env_vars,
int* exit_status = nullptr);
String pipe(StringView input, String pipe(StringView input,
StringView cmdline, const Context& context, StringView cmdline, const Context& context,
memoryview<String> params, memoryview<String> params,
const EnvVarMap& env_vars); const EnvVarMap& env_vars,
int* exit_status = nullptr);
void register_env_var(StringView regex, EnvVarRetriever retriever); void register_env_var(StringView regex, EnvVarRetriever retriever);