diff options
| -rw-r--r-- | config.def.h | 1 | ||||
| -rw-r--r-- | main.c | 6 | ||||
| -rw-r--r-- | vis-modes.c | 2 | ||||
| -rw-r--r-- | vis-operators.c | 6 | ||||
| -rw-r--r-- | vis.c | 22 | ||||
| -rw-r--r-- | vis.h | 1 |
6 files changed, 33 insertions, 5 deletions
diff --git a/config.def.h b/config.def.h index 5ccce5b..5296ce4 100644 --- a/config.def.h +++ b/config.def.h @@ -187,6 +187,7 @@ static KeyBinding vis_operators[] = { { "~", ACTION(OPERATOR_CASE_SWAP) }, { "g~", ACTION(OPERATOR_CASE_SWAP) }, { "gu", ACTION(OPERATOR_CASE_LOWER) }, + { "!", ACTION(OPERATOR_FILTER) }, { "\"", ACTION(REGISTER) }, { /* empty last element, array terminator */ }, }; @@ -196,6 +196,7 @@ enum { VIS_ACTION_OPERATOR_CASE_LOWER, VIS_ACTION_OPERATOR_CASE_UPPER, VIS_ACTION_OPERATOR_CASE_SWAP, + VIS_ACTION_OPERATOR_FILTER, VIS_ACTION_COUNT, VIS_ACTION_INSERT_NEWLINE, VIS_ACTION_INSERT_TAB, @@ -704,6 +705,11 @@ static KeyAction vis_action[] = { "Swap case operator", operator, { .i = VIS_OP_CASE_SWAP } }, + [VIS_ACTION_OPERATOR_FILTER] = { + "vis-operator-filter", + "Filter operator", + operator, { .i = VIS_OP_FILTER } + }, [VIS_ACTION_COUNT] = { "vis-count", "Count specifier", diff --git a/vis-modes.c b/vis-modes.c index 7ded3ba..9da5009 100644 --- a/vis-modes.c +++ b/vis-modes.c @@ -115,6 +115,8 @@ static void vis_mode_prompt_leave(Vis *vis, Mode *new) { Register tmp = vis->registers[VIS_REG_DEFAULT]; vis->registers[VIS_REG_DEFAULT] = vis->registers[VIS_REG_PROMPT]; vis->registers[VIS_REG_PROMPT] = tmp; + if (vis->action_prev.op == &ops[VIS_OP_FILTER]) + macro_operator_stop(vis); } } diff --git a/vis-operators.c b/vis-operators.c index 981922b..e93f946 100644 --- a/vis-operators.c +++ b/vis-operators.c @@ -204,6 +204,11 @@ static size_t op_replace(Vis *vis, Text *txt, OperatorContext *c) { return c->newpos != EPOS ? c->newpos : c->pos; } +static size_t op_filter(Vis *vis, Text *txt, OperatorContext *c) { + macro_operator_record(vis); + return text_size(txt) + 1; /* do not change cursor position, would destroy selection */ +} + Operator ops[] = { [VIS_OP_DELETE] = { op_delete }, [VIS_OP_CHANGE] = { op_change }, @@ -216,4 +221,5 @@ Operator ops[] = { [VIS_OP_INSERT] = { op_insert }, [VIS_OP_REPLACE] = { op_replace }, [VIS_OP_CURSOR_SOL] = { op_cursor }, + [VIS_OP_FILTER] = { op_filter }, }; @@ -542,6 +542,10 @@ static void action_do(Vis *vis, Action *a) { Win *win = vis->win; Text *txt = win->file->text; View *view = win->view; + + if (a->op == &ops[VIS_OP_FILTER] && !vis->mode->visual) + vis_mode_switch(vis, VIS_MODE_VISUAL); + if (a->count < 1) a->count = 1; bool repeatable = a->op && !vis->macro_operator; @@ -661,14 +665,18 @@ static void action_do(Vis *vis, Action *a) { /* operator implementations must not change the mode, * they might get called multiple times (once for every cursor) */ - if (a->op == &ops[VIS_OP_INSERT] || a->op == &ops[VIS_OP_CHANGE]) + if (a->op == &ops[VIS_OP_INSERT] || a->op == &ops[VIS_OP_CHANGE]) { vis_mode_switch(vis, VIS_MODE_INSERT); - else if (a->op == &ops[VIS_OP_REPLACE]) + } else if (a->op == &ops[VIS_OP_REPLACE]) { vis_mode_switch(vis, VIS_MODE_REPLACE); - else if (vis->mode == &vis_modes[VIS_MODE_OPERATOR]) + } else if (a->op == &ops[VIS_OP_FILTER]) { + 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) + } else if (vis->mode->visual) { vis_mode_switch(vis, VIS_MODE_NORMAL); + } text_snapshot(txt); vis_draw(vis); } @@ -1005,6 +1013,9 @@ bool vis_operator(Vis *vis, enum VisOperator id) { vis->action.arg.i = id; id = VIS_OP_PUT_AFTER; break; + case VIS_OP_FILTER: + vis->action.type = LINEWISE; + break; default: break; } @@ -1016,6 +1027,7 @@ bool vis_operator(Vis *vis, enum VisOperator id) { action_do(vis, &vis->action); return true; } + /* switch to operator mode inorder to make operator options and * text-object available */ vis_mode_switch(vis, VIS_MODE_OPERATOR); @@ -1214,7 +1226,7 @@ void vis_repeat(Vis *vis) { Mode *mode = vis->mode; Action action_prev = vis->action_prev; count = action_prev.count; - if (count < 1 || action_prev.op == &ops[VIS_OP_CHANGE]) + if (count < 1 || action_prev.op == &ops[VIS_OP_CHANGE] || action_prev.op == &ops[VIS_OP_FILTER]) count = 1; for (int i = 0; i < count; i++) { mode_set(vis, mode); @@ -151,6 +151,7 @@ enum VisOperator { VIS_OP_REPLACE, VIS_OP_CURSOR_SOL, VIS_OP_CASE_SWAP, + VIS_OP_FILTER, VIS_OP_INVALID, /* denotes the end of the "real" operators */ /* pseudo operators: keep them at the end to save space in array definition */ VIS_OP_CASE_LOWER, |
