aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c9
-rw-r--r--vis-operators.c3
-rw-r--r--vis.c24
-rw-r--r--vis.h6
4 files changed, 34 insertions, 8 deletions
diff --git a/main.c b/main.c
index 35d2f41..70216df 100644
--- a/main.c
+++ b/main.c
@@ -62,6 +62,8 @@ static const char *gotoline(Vis*, const char *keys, const Arg *arg);
static const char *motiontype(Vis*, const char *keys, const Arg *arg);
/* make the current action use the operator indicated by arg->i */
static const char *operator(Vis*, const char *keys, const Arg *arg);
+/* use arg->s as command for the filter operator */
+static const char *operator_filter(Vis*, const char *keys, const Arg *arg);
/* blocks to read a key and performs movement indicated by arg->i which
* should be one of VIS_MOVE_{RIGHT,LEFT}_{TO,TILL} */
static const char *movement_key(Vis*, const char *keys, const Arg *arg);
@@ -708,7 +710,7 @@ static KeyAction vis_action[] = {
[VIS_ACTION_OPERATOR_FILTER] = {
"vis-operator-filter",
"Filter operator",
- operator, { .i = VIS_OP_FILTER }
+ operator_filter,
},
[VIS_ACTION_COUNT] = {
"vis-count",
@@ -1256,6 +1258,11 @@ static const char *operator(Vis *vis, const char *keys, const Arg *arg) {
return keys;
}
+static const char *operator_filter(Vis *vis, const char *keys, const Arg *arg) {
+ vis_operator(vis, VIS_OP_FILTER, arg->s);
+ return keys;
+}
+
static const char *movement_key(Vis *vis, const char *keys, const Arg *arg) {
if (!keys[0])
return NULL;
diff --git a/vis-operators.c b/vis-operators.c
index e93f946..7148b8c 100644
--- a/vis-operators.c
+++ b/vis-operators.c
@@ -205,7 +205,8 @@ static size_t op_replace(Vis *vis, Text *txt, OperatorContext *c) {
}
static size_t op_filter(Vis *vis, Text *txt, OperatorContext *c) {
- macro_operator_record(vis);
+ if (!c->arg->s)
+ macro_operator_record(vis);
return text_size(txt) + 1; /* do not change cursor position, would destroy selection */
}
diff --git a/vis.c b/vis.c
index 73e6ba3..1ab6e4e 100644
--- a/vis.c
+++ b/vis.c
@@ -670,8 +670,13 @@ static void action_do(Vis *vis, Action *a) {
} else if (a->op == &ops[VIS_OP_REPLACE]) {
vis_mode_switch(vis, VIS_MODE_REPLACE);
} else if (a->op == &ops[VIS_OP_FILTER]) {
- vis_prompt_show(vis, ":", "'<,'>!");
- vis_mode_switch(vis, VIS_MODE_PROMPT);
+ if (a->arg.s) {
+ if (vis_cmd(vis, a->arg.s))
+ vis_mode_switch(vis, VIS_MODE_NORMAL);
+ } else {
+ vis_prompt_show(vis, ":", "'<,'>!");
+ vis_mode_switch(vis, VIS_MODE_PROMPT);
+ }
} else if (vis->mode == &vis_modes[VIS_MODE_OPERATOR]) {
mode_set(vis, vis->mode_prev);
} else if (vis->mode->visual) {
@@ -993,7 +998,10 @@ int vis_run(Vis *vis, int argc, char *argv[]) {
return vis->exit_status;
}
-bool vis_operator(Vis *vis, enum VisOperator id) {
+bool vis_operator(Vis *vis, enum VisOperator id, ...) {
+ va_list ap;
+ va_start(ap, id);
+
switch (id) {
case VIS_OP_CASE_LOWER:
case VIS_OP_CASE_UPPER:
@@ -1015,17 +1023,18 @@ bool vis_operator(Vis *vis, enum VisOperator id) {
break;
case VIS_OP_FILTER:
vis->action.type = LINEWISE;
+ vis->action.arg.s = va_arg(ap, char*);
break;
default:
break;
}
if (id >= LENGTH(ops))
- return false;
+ goto err;
Operator *op = &ops[id];
if (vis->mode->visual) {
vis->action.op = op;
action_do(vis, &vis->action);
- return true;
+ goto out;
}
/* switch to operator mode inorder to make operator options and
@@ -1044,7 +1053,12 @@ bool vis_operator(Vis *vis, enum VisOperator id) {
if (id == VIS_OP_PUT_AFTER)
vis_motion(vis, VIS_MOVE_NOP);
+out:
+ va_end(ap);
return true;
+err:
+ va_end(ap);
+ return false;
}
void vis_mode_switch(Vis *vis, enum VisMode mode) {
diff --git a/vis.h b/vis.h
index bf1aab9..2e8d584 100644
--- a/vis.h
+++ b/vis.h
@@ -168,8 +168,12 @@ enum VisOperator {
* otherwise waits until a range is determinded i.e.
* - a motion is provided (see vis_motion)
* - a text object is provided (vis_textobject)
+ *
+ * the expected varying arguments are as follows:
+ *
+ * - VIS_OP_FILTER a char pointer referring to the command to run
*/
-bool vis_operator(Vis*, enum VisOperator);
+bool vis_operator(Vis*, enum VisOperator, ...);
enum VisMotion {
VIS_MOVE_LINE_DOWN,