From 9c06ad608be1a8bc840e8bf0583bfce36b6c813c Mon Sep 17 00:00:00 2001 From: jfreegman Date: Sat, 10 Oct 2020 11:21:15 -0400 Subject: [PATCH] Add ability to skip words in input field with ctrl-left/right arrow --- src/input.c | 62 +++++++++++++++++++++++++++++++++++++++++++++---- src/osx_video.m | 2 +- src/toxic.h | 2 ++ 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/input.c b/src/input.c index 677cf8d..845f138 100644 --- a/src/input.c +++ b/src/input.c @@ -100,7 +100,6 @@ static void input_del_word(ToxWindow *self) if (del_word_buf(ctx) == -1) { sound_notify(self, notif_error, 0, NULL); - return; } } @@ -172,17 +171,41 @@ static void input_mv_left(ToxWindow *self, int x, int mx_x) } int cur_len = ctx->pos > 0 ? wcwidth(ctx->line[ctx->pos - 1]) : 0; - int s_len = ctx->start > 0 ? wcwidth(ctx->line[ctx->start - 1]) : 0; --ctx->pos; - if (ctx->start && (x >= mx_x - cur_len)) { + if (ctx->start > 0 && (x >= mx_x - cur_len)) { + int s_len = wcwidth(ctx->line[ctx->start - 1]); ctx->start = MAX(0, ctx->start - 1 + (s_len - cur_len)); - } else if (ctx->start) { + } else if (ctx->start > 0) { ctx->start = MAX(0, ctx->start - cur_len); } } +/* moves the cursor to the beginning of the previous word in input field and buffer */ +static void input_skip_left(ToxWindow *self, int x, int mx_x) +{ + ChatContext *ctx = self->chatwin; + + if (ctx->pos <= 0) { + return; + } + + int count = 0; + + do { + --ctx->pos; + count += wcwidth(ctx->line[ctx->pos]); + } while (ctx->pos > 0 && (ctx->line[ctx->pos - 1] != L' ' || ctx->line[ctx->pos] == L' ')); + + if (ctx->start > 0 && (x >= mx_x - count)) { + int s_len = wcwidth(ctx->line[ctx->start - 1]); + ctx->start = MAX(0, ctx->start - 1 + (s_len - count)); + } else if (ctx->start > 0) { + ctx->start = MAX(0, ctx->start - count); + } +} + /* moves cursor/line position right in input field and buffer */ static void input_mv_right(ToxWindow *self, int x, int mx_x) { @@ -202,6 +225,29 @@ static void input_mv_right(ToxWindow *self, int x, int mx_x) } } +/* moves the cursor to the end of the next word in input field and buffer */ +static void input_skip_right(ToxWindow *self, int x, int mx_x) +{ + ChatContext *ctx = self->chatwin; + + if (ctx->pos >= ctx->len) { + return; + } + + int count = 0; + + do { + count += wcwidth(ctx->line[ctx->pos]); + ++ctx->pos; + } while (ctx->pos < ctx->len && !(ctx->line[ctx->pos] == L' ' && ctx->line[ctx->pos - 1] != L' ')); + + int newpos = x + count; + + if (newpos >= mx_x) { + ctx->start += (1 + (newpos - mx_x)); + } +} + /* puts a line history item in input field and buffer */ static void input_history(ToxWindow *self, wint_t key, int mx_x) { @@ -271,6 +317,14 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int mx_x) force_refresh(self->chatwin->history); break; + case T_KEY_C_LEFT: + input_skip_left(self, x, mx_x); + break; + + case T_KEY_C_RIGHT: + input_skip_right(self, x, mx_x); + break; + default: match = false; break; diff --git a/src/osx_video.m b/src/osx_video.m index 379e394..457e905 100644 --- a/src/osx_video.m +++ b/src/osx_video.m @@ -343,4 +343,4 @@ int osx_video_read_device(uint8_t *y, uint8_t *u, uint8_t *v, uint16_t *width, u * End of C-interface for OSXVideo */ -#endif /* __OBJC__ */ \ No newline at end of file +#endif /* __OBJC__ */ diff --git a/src/toxic.h b/src/toxic.h index 82c6cc9..569401b 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -71,6 +71,8 @@ #define T_KEY_C_W 0x17 /* ctrl-w */ #define T_KEY_C_B 0x02 /* ctrl-b */ #define T_KEY_C_T 0x14 /* ctrl-t */ +#define T_KEY_C_LEFT 0x221 /* ctrl-left arrow */ +#define T_KEY_C_RIGHT 0x230 /* ctrl-right arrow */ #define T_KEY_TAB 0x09 /* TAB key */ #define ONLINE_CHAR "*"