aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-11-27 07:23:36 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-11-27 07:23:36 +0100
commit7ce4e0cc1423bb55f798031014462fd192d23fc3 (patch)
treef0eb89dbf2b92c92eba0458f5344fc0a3f6eb68b
parente063464c7cdeb41796282d0efe13cc907928f3f8 (diff)
downloadvis-7ce4e0cc1423bb55f798031014462fd192d23fc3.tar.gz
vis-7ce4e0cc1423bb55f798031014462fd192d23fc3.tar.xz
vis: implement filter operator !
It currently works by switching to visual mode and then opening the command prompt with a default range which refers to the currently active selection.
-rw-r--r--config.def.h1
-rw-r--r--main.c6
-rw-r--r--vis-modes.c2
-rw-r--r--vis-operators.c6
-rw-r--r--vis.c22
-rw-r--r--vis.h1
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 */ },
};
diff --git a/main.c b/main.c
index 509e7bb..b0ec8d9 100644
--- a/main.c
+++ b/main.c
@@ -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 },
};
diff --git a/vis.c b/vis.c
index 3398c6c..73e6ba3 100644
--- a/vis.c
+++ b/vis.c
@@ -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);
diff --git a/vis.h b/vis.h
index 0399d3c..bf1aab9 100644
--- a/vis.h
+++ b/vis.h
@@ -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,