diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-24 10:23:51 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-24 10:39:05 +0200 |
| commit | 1b1cedc6666d99f6e9886439dca93278c47d131c (patch) | |
| tree | 937b472f5e5f6323188c202b192836603dcfd65c | |
| parent | 0c581075c55fe3c7839fdc293282a9544280bfab (diff) | |
| download | vis-1b1cedc6666d99f6e9886439dca93278c47d131c.tar.gz vis-1b1cedc6666d99f6e9886439dca93278c47d131c.tar.xz | |
Implement 'gU' and 'gu'
This obviously only works for ascii characters.
| -rw-r--r-- | config.def.h | 2 | ||||
| -rw-r--r-- | vis.c | 33 |
2 files changed, 35 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h index 993f2a0..ba0c290 100644 --- a/config.def.h +++ b/config.def.h @@ -204,6 +204,8 @@ static KeyBinding vis_operators[] = { { { NONE('P') }, put, { .i = -1 } }, { { NONE('>') }, operator, { .i = OP_SHIFT_RIGHT } }, { { NONE('<') }, operator, { .i = OP_SHIFT_LEFT } }, + { { NONE('g'), NONE('U') }, changecase, { .i = +1 } }, + { { NONE('g'), NONE('u') }, changecase, { .i = -1 } }, { /* empty last element, array terminator */ }, }; @@ -25,6 +25,7 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> +#include <ctype.h> #include <sys/select.h> #include <sys/types.h> #include <sys/stat.h> @@ -158,6 +159,7 @@ 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); +static void op_case_change(OperatorContext *c); /* these can be passed as int argument to operator(&(const Arg){ .i = OP_*}) */ enum { @@ -167,6 +169,7 @@ enum { OP_PUT, OP_SHIFT_RIGHT, OP_SHIFT_LEFT, + OP_CASE_CHANGE, }; static Operator ops[] = { @@ -176,6 +179,7 @@ static Operator ops[] = { [OP_PUT] = { op_put }, [OP_SHIFT_RIGHT] = { op_shift_right }, [OP_SHIFT_LEFT] = { op_shift_left }, + [OP_CASE_CHANGE] = { op_case_change }, }; #define PAGE INT_MAX @@ -370,6 +374,8 @@ static void linewise(const Arg *arg); static void operator(const Arg *arg); /* execute operator twice useful for synonyms (e.g. 'cc') */ static void operator_twice(const Arg *arg); +/* change case of a file range to upper (arg->i > 0) or lowercase (arg->i < 0) */ +static void changecase(const Arg *arg); /* blocks to read a key and performs movement indicated by arg->i which * should be one of MOVE_{RIGHT,LEFT}_{TO,TILL} */ static void movement_key(const Arg *arg); @@ -552,6 +558,28 @@ static void op_shift_left(OperatorContext *c) { editor_draw(vis); } +static void op_case_change(OperatorContext *c) { + size_t len = c->range.end - c->range.start; + char *buf = malloc(len+1); + if (!buf) + return; + len = text_bytes_get(vis->win->text, c->range.start, len, buf); + size_t rem = len; + for (char *cur = buf; rem > 0; cur++, rem--) { + if (isascii((unsigned char)*cur)) { + if (c->arg->i > 0) + *cur = toupper((unsigned char)*cur); + else + *cur = tolower((unsigned char)*cur); + } + } + + text_delete(vis->win->text, c->range.start, len); + text_insert(vis->win->text, c->range.start, buf, len); + editor_draw(vis); + free(buf); +} + /** movement implementations of type: size_t (*move)(const Arg*) */ static size_t search_forward(const Arg *arg) { @@ -673,6 +701,11 @@ static void operator_twice(const Arg *arg) { operator(arg); } +static void changecase(const Arg *arg) { + action.arg = *arg; + operator(&(const Arg){ .i = OP_CASE_CHANGE }); +} + static void movement_key(const Arg *arg) { Key k = getkey(); if (!k.str[0]) { |
