diff options
| -rw-r--r-- | config.def.h | 1 | ||||
| -rw-r--r-- | vis.c | 29 |
2 files changed, 30 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h index d3c0e88..8d5d605 100644 --- a/config.def.h +++ b/config.def.h @@ -199,6 +199,7 @@ static KeyBinding vis_operators[] = { { { NONE('y') }, operator, { .i = OP_YANK } }, { { NONE('p') }, operator, { .i = OP_PUT } }, { { NONE('>') }, operator, { .i = OP_SHIFT_RIGHT } }, + { { NONE('<') }, operator, { .i = OP_SHIFT_LEFT } }, { /* empty last element, array terminator */ }, }; @@ -152,6 +152,7 @@ static void op_yank(OperatorContext *c); static void op_put(OperatorContext *c); static void op_delete(OperatorContext *c); static void op_shift_right(OperatorContext *c); +static void op_shift_left(OperatorContext *c); /* these can be passed as int argument to operator(&(const Arg){ .i = OP_*}) */ enum { @@ -160,6 +161,7 @@ enum { OP_YANK, OP_PUT, OP_SHIFT_RIGHT, + OP_SHIFT_LEFT, }; static Operator ops[] = { @@ -168,6 +170,7 @@ static Operator ops[] = { [OP_YANK] = { op_yank, false }, [OP_PUT] = { op_put, true }, [OP_SHIFT_RIGHT] = { op_shift_right, false }, + [OP_SHIFT_LEFT] = { op_shift_left, false }, }; #define PAGE INT_MAX @@ -490,6 +493,32 @@ static void op_shift_right(OperatorContext *c) { editor_draw(vis); } +static void op_shift_left(OperatorContext *c) { + Text *txt = vis->win->text; + size_t pos = text_line_begin(txt, c->range.end), prev_pos; + size_t tabwidth = 8; // TODO: make configurable + + /* if range ends at the begin of a line, skip line break */ + if (pos == c->range.end) + pos = text_line_prev(txt, pos); + + do { + char c; + size_t len = 0; + prev_pos = pos = text_line_begin(txt, pos); + Iterator it = text_iterator_get(txt, pos); + if (text_iterator_byte_get(&it, &c) && c == '\t') { + len = 1; + } else { + for (len = 0; text_iterator_byte_get(&it, &c) && c == ' '; len++) + text_iterator_byte_next(&it, NULL); + } + text_delete(txt, pos, MIN(len, tabwidth)); + pos = text_line_prev(txt, pos); + } while (pos >= c->range.start && pos != prev_pos); + editor_draw(vis); +} + /** movement implementations of type: size_t (*move)(const Arg*) */ static size_t search_forward(const Arg *arg) { |
