mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-10-31 18:56:51 +01:00 
			
		
		
		
	add buffer yanking, clean up input functions
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| TOXIC_VERSION = 0.4.4 | TOXIC_VERSION = 0.4.5 | ||||||
| REV = $(shell git rev-list HEAD --count) | REV = $(shell git rev-list HEAD --count) | ||||||
| VERSION = $(TOXIC_VERSION)_r$(REV) | VERSION = $(TOXIC_VERSION)_r$(REV) | ||||||
|  |  | ||||||
| @@ -15,7 +15,7 @@ MANFILES = toxic.1 toxic.conf.5 | |||||||
|  |  | ||||||
| LIBS = libtoxcore ncursesw | LIBS = libtoxcore ncursesw | ||||||
|  |  | ||||||
| CFLAGS = -std=gnu99 -pthread -Wall | CFLAGS = -std=gnu99 -pthread -Wall -g | ||||||
| CFLAGS += -DTOXICVER="\"$(VERSION)\"" -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED | CFLAGS += -DTOXICVER="\"$(VERSION)\"" -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED | ||||||
| CFLAGS += -DPACKAGE_DATADIR="\"$(abspath $(DATADIR))\"" | CFLAGS += -DPACKAGE_DATADIR="\"$(abspath $(DATADIR))\"" | ||||||
| CFLAGS += $(USER_CFLAGS) | CFLAGS += $(USER_CFLAGS) | ||||||
|   | |||||||
| @@ -20,6 +20,10 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #ifndef _GNU_SOURCE | ||||||
|  | #define _GNU_SOURCE    /* needed for wcswidth() */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| @@ -847,7 +851,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) | |||||||
|     int y, x; |     int y, x; | ||||||
|     getyx(self->window, y, x); |     getyx(self->window, y, x); | ||||||
|     (void) x; |     (void) x; | ||||||
|     int new_x = ctx->start ? x2 - 1 : ctx->pos; |     int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); | ||||||
|     wmove(self->window, y + 1, new_x); |     wmove(self->window, y + 1, new_x); | ||||||
|  |  | ||||||
|     wrefresh(self->window); |     wrefresh(self->window); | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #ifndef _GNU_SOURCE | #ifndef _GNU_SOURCE | ||||||
| #define _GNU_SOURCE    /* needed for strcasestr() */ | #define _GNU_SOURCE    /* needed for strcasestr() and wcswidth() */ | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| @@ -474,7 +474,7 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) | |||||||
|     int y, x; |     int y, x; | ||||||
|     getyx(self->window, y, x); |     getyx(self->window, y, x); | ||||||
|     (void) x; |     (void) x; | ||||||
|     int new_x = ctx->start ? x2 - 1 : ctx->pos; |     int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); | ||||||
|     wmove(self->window, y + 1, new_x); |     wmove(self->window, y + 1, new_x); | ||||||
|  |  | ||||||
|     wrefresh(self->window); |     wrefresh(self->window); | ||||||
|   | |||||||
							
								
								
									
										153
									
								
								src/input.c
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								src/input.c
									
									
									
									
									
								
							| @@ -37,99 +37,87 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_ | |||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     if (ctx->len >= MAX_STR_SIZE - 1) { |     int cur_len = wcwidth(key); | ||||||
|  |  | ||||||
|  |     /* this is the only place we need to do this check */ | ||||||
|  |     if (cur_len == -1) { | ||||||
|         beep(); |         beep(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int cur_len = wcwidth(key); |     if (add_char_to_buf(ctx, key) == -1) { | ||||||
|  |         beep(); | ||||||
|     /* this is the only place we need to do this check */ |  | ||||||
|     if (cur_len == -1) |  | ||||||
|         return; |         return; | ||||||
|  |     } | ||||||
|     add_char_to_buf(ctx, key); |  | ||||||
|  |  | ||||||
|     if (x + cur_len >= mx_x) { |     if (x + cur_len >= mx_x) { | ||||||
|         int s_len = wcwidth(ctx->line[ctx->start]); |         int s_len = wcwidth(ctx->line[ctx->start]); | ||||||
|         int cdiff = cur_len - s_len; |         ctx->start += 1 + MAX(0, cur_len - s_len); | ||||||
|         ctx->start += 1 + MAX(0, cdiff); |  | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |  | ||||||
|     } else { |  | ||||||
|         wmove(self->window, y, x + cur_len); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* delete a char via backspace key from input field and buffer */ | /* delete a char via backspace key from input field and buffer */ | ||||||
| static void input_backspace(ToxWindow *self, int x, int y, int mx_x, int mx_y) | static void input_backspace(ToxWindow *self, int x, int mx_x) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     if (ctx->pos <= 0) { |     if (del_char_buf_bck(ctx) == -1) { | ||||||
|         beep(); |         beep(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int cur_len = wcwidth(ctx->line[ctx->pos - 1]); |     int cur_len = wcwidth(ctx->line[ctx->pos - 1]); | ||||||
|  |  | ||||||
|     del_char_buf_bck(ctx); |  | ||||||
|  |  | ||||||
|     int s_len = wcwidth(ctx->line[ctx->start - 1]); |     int s_len = wcwidth(ctx->line[ctx->start - 1]); | ||||||
|     int cdiff = s_len - cur_len; |  | ||||||
|  |  | ||||||
|     if (ctx->start && (x >= mx_x - cur_len)) { |     if (ctx->start && (x >= mx_x - cur_len)) | ||||||
|         ctx->start = MAX(0, ctx->start - 1 + cdiff); |         ctx->start = MAX(0, ctx->start - 1 + (s_len - cur_len)); | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |     else if (ctx->start && (ctx->pos == ctx->len)) | ||||||
|     } else if (ctx->start && (ctx->pos == ctx->len)) { |  | ||||||
|         ctx->start = MAX(0, ctx->start - cur_len); |         ctx->start = MAX(0, ctx->start - cur_len); | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |     else if (ctx->start) | ||||||
|     } else if (ctx->start) { |  | ||||||
|         ctx->start = MAX(0, ctx->start - cur_len); |         ctx->start = MAX(0, ctx->start - cur_len); | ||||||
|     } else { |  | ||||||
|         wmove(self->window, y, x - cur_len); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* delete a char via delete key from input field and buffer */ | /* delete a char via delete key from input field and buffer */ | ||||||
| static void input_delete(ToxWindow *self) | static void input_delete(ToxWindow *self) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     if (del_char_buf_frnt(self->chatwin) == -1) | ||||||
|  |  | ||||||
|     if (ctx->pos >= ctx->len) { |  | ||||||
|         beep(); |         beep(); | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     del_char_buf_frnt(ctx); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* deletes entire line before cursor from input field and buffer */ | /* deletes entire line before cursor from input field and buffer */ | ||||||
| static void input_discard(ToxWindow *self, int mx_y) | static void input_discard(ToxWindow *self) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     if (discard_buf(self->chatwin) == -1) | ||||||
|  |  | ||||||
|     if (ctx->pos <= 0) { |  | ||||||
|         beep(); |         beep(); | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     discard_buf(ctx); |  | ||||||
|     wmove(self->window, mx_y - CURS_Y_OFFSET, 0); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* deletes entire line after cursor from input field and buffer */ | /* deletes entire line after cursor from input field and buffer */ | ||||||
| static void input_kill(ChatContext *ctx) | static void input_kill(ChatContext *ctx) | ||||||
| { | { | ||||||
|     if (ctx->pos != ctx->len) { |     if (kill_buf(ctx) == -1) | ||||||
|         kill_buf(ctx); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|         beep(); |         beep(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void input_yank(ToxWindow *self, int x, int mx_x) | ||||||
|  | { | ||||||
|  |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|  |     if (yank_buf(ctx) == -1) { | ||||||
|  |         beep(); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     int yank_cols = MAX(0, wcswidth(ctx->yank, ctx->yank_len)); | ||||||
|  |  | ||||||
|  |     if (x + yank_cols >= mx_x) { | ||||||
|  |         int rmdr = MAX(0, (x + yank_cols) - mx_x); | ||||||
|  |         int s_len = wcswidth(&ctx->line[ctx->start], rmdr); | ||||||
|  |         ctx->start += s_len + 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| /* moves cursor/line position to end of line in input field and buffer */ | /* moves cursor/line position to end of line in input field and buffer */ | ||||||
| static void input_mv_end(ToxWindow *self, int x, int y, int mx_x, int mx_y) | static void input_mv_end(ToxWindow *self, int y, int mx_x) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
| @@ -137,90 +125,67 @@ static void input_mv_end(ToxWindow *self, int x, int y, int mx_x, int mx_y) | |||||||
|  |  | ||||||
|     int wlen = wcswidth(ctx->line, sizeof(ctx->line)); |     int wlen = wcswidth(ctx->line, sizeof(ctx->line)); | ||||||
|     ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x)); |     ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x)); | ||||||
|  |  | ||||||
|     int llen = wcswidth(&ctx->line[ctx->start], mx_x); |  | ||||||
|     int new_x = wlen >= mx_x ? mx_x - 1 : llen; |  | ||||||
|  |  | ||||||
|     wmove(self->window, y, new_x); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* moves cursor/line position to start of line in input field and buffer */ | /* moves cursor/line position to start of line in input field and buffer */ | ||||||
| static void input_mv_home(ToxWindow *self, int mx_y) | static void input_mv_home(ToxWindow *self) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     if (ctx->pos <= 0) { |     if (ctx->pos <= 0) | ||||||
|         beep(); |  | ||||||
|         return; |         return; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ctx->pos = 0; |     ctx->pos = 0; | ||||||
|     ctx->start = 0; |     ctx->start = 0; | ||||||
|     wmove(self->window, mx_y - CURS_Y_OFFSET, 0); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* moves cursor/line position left in input field and buffer */ | /* moves cursor/line position left in input field and buffer */ | ||||||
| static void input_mv_left(ToxWindow *self, int x, int y, int mx_x, int mx_y) | static void input_mv_left(ToxWindow *self, int x, int mx_x) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     if (ctx->pos <= 0) { |     if (ctx->pos <= 0) | ||||||
|         beep(); |  | ||||||
|         return; |         return; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     int cur_len = wcwidth(ctx->line[ctx->pos - 1]); |     int cur_len = wcwidth(ctx->line[ctx->pos - 1]); | ||||||
|  |  | ||||||
|     --ctx->pos; |     --ctx->pos; | ||||||
|  |  | ||||||
|     int s_len = wcwidth(ctx->line[ctx->start - 1]); |     int s_len = wcwidth(ctx->line[ctx->start - 1]); | ||||||
|     int cdiff = s_len - cur_len; |  | ||||||
|  |  | ||||||
|     if (ctx->start && (x >= mx_x - cur_len)) { |     if (ctx->start && (x >= mx_x - cur_len)) | ||||||
|         ctx->start = MAX(0, ctx->start - 1 + cdiff); |         ctx->start = MAX(0, ctx->start - 1 + (s_len - cur_len)); | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |     else if (ctx->start && (ctx->pos == ctx->len)) | ||||||
|     } else if (ctx->start && (ctx->pos == ctx->len)) { |  | ||||||
|         ctx->start = MAX(0, ctx->start - cur_len); |         ctx->start = MAX(0, ctx->start - cur_len); | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |     else if (ctx->start) | ||||||
|     } else if (ctx->start) { |  | ||||||
|         ctx->start = MAX(0, ctx->start - cur_len); |         ctx->start = MAX(0, ctx->start - cur_len); | ||||||
|     } else { |  | ||||||
|         wmove(self->window, y, x - cur_len); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* moves cursor/line position right in input field and buffer */ | /* moves cursor/line position right in input field and buffer */ | ||||||
| static void input_mv_right(ToxWindow *self, int x, int y, int mx_x, int mx_y) | static void input_mv_right(ToxWindow *self, int x, int mx_x) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     if (ctx->pos >= ctx->len) { |     if (ctx->pos >= ctx->len) | ||||||
|         beep(); |  | ||||||
|         return; |         return; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     ++ctx->pos; |     ++ctx->pos; | ||||||
|  |  | ||||||
|     int cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1])); |     int cur_len = wcwidth(ctx->line[ctx->pos - 1]); | ||||||
|  |  | ||||||
|     if (x + cur_len >= mx_x) { |     if (x + cur_len >= mx_x) { | ||||||
|         int s_len = wcwidth(ctx->line[ctx->start]); |         int s_len = wcwidth(ctx->line[ctx->start]); | ||||||
|         int cdiff = cur_len - s_len; |         ctx->start += 1 + MAX(0, cur_len - s_len); | ||||||
|         ctx->start += 1 + MAX(0, cdiff); |  | ||||||
|         wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x)); |  | ||||||
|     } else { |  | ||||||
|         wmove(self->window, y, x + cur_len); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /* puts a line history item in input field and buffer */ | /* puts a line history item in input field and buffer */ | ||||||
| static void input_history(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y) | static void input_history(ToxWindow *self, wint_t key, int mx_x) | ||||||
| { | { | ||||||
|     ChatContext *ctx = self->chatwin; |     ChatContext *ctx = self->chatwin; | ||||||
|  |  | ||||||
|     fetch_hist_item(ctx, key); |     fetch_hist_item(ctx, key); | ||||||
|     ctx->start = mx_x * (ctx->len / mx_x); |     ctx->start = mx_x * (ctx->len / mx_x); | ||||||
|     input_mv_end(self, x, y, mx_x, mx_y); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Handles non-printable input keys that behave the same for all types of chat windows. | /* Handles non-printable input keys that behave the same for all types of chat windows. | ||||||
| @@ -232,7 +197,7 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y) | |||||||
|     switch (key) { |     switch (key) { | ||||||
|         case 0x7f: |         case 0x7f: | ||||||
|         case KEY_BACKSPACE: |         case KEY_BACKSPACE: | ||||||
|             input_backspace(self, x, y, mx_x, mx_y); |             input_backspace(self, x, mx_x); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case KEY_DC: |         case KEY_DC: | ||||||
| @@ -240,34 +205,38 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y) | |||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case T_KEY_DISCARD: |         case T_KEY_DISCARD: | ||||||
|             input_discard(self, mx_y); |             input_discard(self); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case T_KEY_KILL: |         case T_KEY_KILL: | ||||||
|             input_kill(self->chatwin); |             input_kill(self->chatwin); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|  |         case T_KEY_C_Y: | ||||||
|  |             input_yank(self, x, mx_x); | ||||||
|  |             break; | ||||||
|  |  | ||||||
|         case KEY_HOME: |         case KEY_HOME: | ||||||
|         case T_KEY_C_A: |         case T_KEY_C_A: | ||||||
|             input_mv_home(self, mx_y); |             input_mv_home(self); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case KEY_END: |         case KEY_END: | ||||||
|         case T_KEY_C_E: |         case T_KEY_C_E: | ||||||
|             input_mv_end(self, x, y, mx_x, mx_y); |             input_mv_end(self, y, mx_x); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case KEY_LEFT: |         case KEY_LEFT: | ||||||
|             input_mv_left(self, x, y, mx_x, mx_y); |             input_mv_left(self, x, mx_x); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case KEY_RIGHT: |         case KEY_RIGHT: | ||||||
|             input_mv_right(self, x, y, mx_x, mx_y); |             input_mv_right(self, x, mx_x); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case KEY_UP: |         case KEY_UP: | ||||||
|         case KEY_DOWN: |         case KEY_DOWN: | ||||||
|             input_history(self, key, x, y, mx_x, mx_y); |             input_history(self, key, mx_x); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         default: |         default: | ||||||
|   | |||||||
| @@ -20,6 +20,10 @@ | |||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | #ifndef _GNU_SOURCE | ||||||
|  | #define _GNU_SOURCE    /* needed for wcswidth() */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <wchar.h> | #include <wchar.h> | ||||||
| @@ -275,7 +279,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) | |||||||
|     getyx(self->window, y, x); |     getyx(self->window, y, x); | ||||||
|     (void) x; |     (void) x; | ||||||
|  |  | ||||||
|     int new_x = ctx->start ? x2 - 1 : ctx->pos; |     int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); | ||||||
|     wmove(self->window, y + 1, new_x); |     wmove(self->window, y + 1, new_x); | ||||||
|  |  | ||||||
|     wrefresh(self->window); |     wrefresh(self->window); | ||||||
|   | |||||||
| @@ -62,6 +62,7 @@ | |||||||
| #define T_KEY_C_V        0x16     /* ctrl-v */ | #define T_KEY_C_V        0x16     /* ctrl-v */ | ||||||
| #define T_KEY_C_F        0x06     /* ctrl-f */ | #define T_KEY_C_F        0x06     /* ctrl-f */ | ||||||
| #define T_KEY_C_H        0x08     /* ctrl-h */ | #define T_KEY_C_H        0x08     /* ctrl-h */ | ||||||
|  | #define T_KEY_C_Y        0x19     /* ctrl-y */ | ||||||
|  |  | ||||||
| typedef enum _FATAL_ERRS { | typedef enum _FATAL_ERRS { | ||||||
|     FATALERR_MEMORY = -1,           /* malloc() or calloc() failed */ |     FATALERR_MEMORY = -1,           /* malloc() or calloc() failed */ | ||||||
|   | |||||||
| @@ -29,59 +29,98 @@ | |||||||
| #include "misc_tools.h" | #include "misc_tools.h" | ||||||
| #include "toxic_strings.h" | #include "toxic_strings.h" | ||||||
|  |  | ||||||
| /* Adds char to line at pos */ | /* Adds char to line at pos. Return 0 on success, -1 if line buffer is full */ | ||||||
| void add_char_to_buf(ChatContext *ctx, wint_t ch) | int add_char_to_buf(ChatContext *ctx, wint_t ch) | ||||||
| { | { | ||||||
|     if (ctx->len >= MAX_STR_SIZE) |     if (ctx->len >= MAX_STR_SIZE - 1) | ||||||
|         return; |         return -1; | ||||||
|  |  | ||||||
|     wmemmove(&ctx->line[ctx->pos + 1], &ctx->line[ctx->pos], ctx->len - ctx->pos); |     wmemmove(&ctx->line[ctx->pos + 1], &ctx->line[ctx->pos], ctx->len - ctx->pos); | ||||||
|     ctx->line[ctx->pos++] = ch; |     ctx->line[ctx->pos++] = ch; | ||||||
|     ctx->line[++ctx->len] = L'\0'; |     ctx->line[++ctx->len] = L'\0'; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Deletes the character before pos */ | /* Deletes the character before pos. Return 0 on success, -1 if nothing to delete */ | ||||||
| void del_char_buf_bck(ChatContext *ctx) | int del_char_buf_bck(ChatContext *ctx) | ||||||
| { | { | ||||||
|     if (ctx->pos == 0) |     if (ctx->pos <= 0) | ||||||
|         return; |         return -1; | ||||||
|  |  | ||||||
|     wmemmove(&ctx->line[ctx->pos - 1], &ctx->line[ctx->pos], ctx->len - ctx->pos); |     wmemmove(&ctx->line[ctx->pos - 1], &ctx->line[ctx->pos], ctx->len - ctx->pos); | ||||||
|     --ctx->pos; |     --ctx->pos; | ||||||
|     ctx->line[--ctx->len] = L'\0'; |     ctx->line[--ctx->len] = L'\0'; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Deletes the character at pos */ | /* Deletes the character at pos. Return 0 on success, -1 if nothing to delete. */ | ||||||
| void del_char_buf_frnt(ChatContext *ctx) | int del_char_buf_frnt(ChatContext *ctx) | ||||||
| { | { | ||||||
|     if (ctx->pos >= ctx->len) |     if (ctx->pos >= ctx->len) | ||||||
|         return; |         return -1; | ||||||
|  |  | ||||||
|     wmemmove(&ctx->line[ctx->pos], &ctx->line[ctx->pos + 1], ctx->len - ctx->pos - 1); |     wmemmove(&ctx->line[ctx->pos], &ctx->line[ctx->pos + 1], ctx->len - ctx->pos - 1); | ||||||
|     ctx->line[--ctx->len] = L'\0'; |     ctx->line[--ctx->len] = L'\0'; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Deletes the line from beginning to pos */ | /* Deletes the line from beginning to pos and puts discarded portion in yank buffer. | ||||||
| void discard_buf(ChatContext *ctx) |    Return 0 on success, -1 if noting to discard. */ | ||||||
|  | int discard_buf(ChatContext *ctx) | ||||||
| { | { | ||||||
|     if (ctx->pos <= 0) |     if (ctx->pos <= 0) | ||||||
|         return; |         return -1; | ||||||
|  |  | ||||||
|  |     ctx->yank_len = ctx->pos; | ||||||
|  |     wmemcpy(ctx->yank, ctx->line, ctx->yank_len); | ||||||
|  |     ctx->yank[ctx->yank_len] = L'\0'; | ||||||
|  |  | ||||||
|     wmemmove(ctx->line, &ctx->line[ctx->pos], ctx->len - ctx->pos); |     wmemmove(ctx->line, &ctx->line[ctx->pos], ctx->len - ctx->pos); | ||||||
|     ctx->len -= ctx->pos; |     ctx->len -= ctx->pos; | ||||||
|     ctx->pos = 0; |     ctx->pos = 0; | ||||||
|     ctx->start = 0; |     ctx->start = 0; | ||||||
|     ctx->line[ctx->len] = L'\0'; |     ctx->line[ctx->len] = L'\0'; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Deletes the line from pos to len */ | /* Deletes the line from pos to len and puts killed portion in yank buffer. | ||||||
| void kill_buf(ChatContext *ctx) |    Return 0 on success, -1 if nothing to kill. */ | ||||||
|  | int kill_buf(ChatContext *ctx) | ||||||
| { | { | ||||||
|     if (ctx->len == ctx->pos) |     if (ctx->len <= ctx->pos) | ||||||
|         return; |         return -1; | ||||||
|  |  | ||||||
|  |     ctx->yank_len = ctx->len - ctx->pos; | ||||||
|  |     wmemcpy(ctx->yank, &ctx->line[ctx->pos], ctx->yank_len); | ||||||
|  |     ctx->yank[ctx->yank_len] = L'\0'; | ||||||
|  |  | ||||||
|     ctx->line[ctx->pos] = L'\0'; |     ctx->line[ctx->pos] = L'\0'; | ||||||
|     ctx->len = ctx->pos; |     ctx->len = ctx->pos; | ||||||
|  |  | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Inserts string in ctx->yank into line at pos. | ||||||
|  |    Return 0 on success, -1 if yank buffer is empty or too long */ | ||||||
|  | int yank_buf(ChatContext *ctx) | ||||||
|  | { | ||||||
|  |     if (!ctx->yank[0]) | ||||||
|  |         return -1; | ||||||
|  |  | ||||||
|  |     if (ctx->yank_len + ctx->len >= MAX_STR_SIZE - 1) | ||||||
|  |         return -1; | ||||||
|  |  | ||||||
|  |     wmemmove(&ctx->line[ctx->pos + ctx->yank_len], &ctx->line[ctx->pos], ctx->len - ctx->pos); | ||||||
|  |     wmemcpy(&ctx->line[ctx->pos], ctx->yank, ctx->yank_len); | ||||||
|  |  | ||||||
|  |     ctx->pos += ctx->yank_len; | ||||||
|  |     ctx->len += ctx->yank_len; | ||||||
|  |     ctx->line[ctx->len] = L'\0'; | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* nulls line and sets pos, len and start to 0 */ | /* nulls line and sets pos, len and start to 0 */ | ||||||
|   | |||||||
| @@ -25,24 +25,30 @@ | |||||||
|  |  | ||||||
| #include "windows.h" | #include "windows.h" | ||||||
|  |  | ||||||
| /* Adds char to line at pos */ | /* Adds char to line at pos. Return 0 on success, -1 if line buffer is full */ | ||||||
| void add_char_to_buf(ChatContext *ctx, wint_t ch); | int add_char_to_buf(ChatContext *ctx, wint_t ch); | ||||||
|  |  | ||||||
| /* Deletes the character before pos */ | /* Deletes the character before pos. Return 0 on success, -1 if nothing to delete */ | ||||||
| void del_char_buf_bck(ChatContext *ctx); | int del_char_buf_bck(ChatContext *ctx); | ||||||
|  |  | ||||||
| /* Deletes the character at pos */ | /* Deletes the character at pos. Return 0 on success, -1 if nothing to delete. */ | ||||||
| void del_char_buf_frnt(ChatContext *ctx); | int del_char_buf_frnt(ChatContext *ctx); | ||||||
|  |  | ||||||
| /* Deletes the line from beginning to pos */ | /* Deletes the line from beginning to pos and puts discarded portion in yank buffer. | ||||||
| void discard_buf(ChatContext *ctx); |    Return 0 on success, -1 if noting to discard */ | ||||||
|  | int discard_buf(ChatContext *ctx); | ||||||
|  |  | ||||||
| /* Deletes the line from pos to len */ | /* Deletes the line from pos to len and puts killed portion in yank buffer. | ||||||
| void kill_buf(ChatContext *ctx); |    Return 0 on success, -1 if nothing to kill. */ | ||||||
|  | int kill_buf(ChatContext *ctx); | ||||||
|  |  | ||||||
| /* nulls line and sets pos, len and start to 0 */ | /* nulls line and sets pos, len and start to 0 */ | ||||||
| void reset_buf(ChatContext *ctx); | void reset_buf(ChatContext *ctx); | ||||||
|  |  | ||||||
|  | /* Inserts string in ctx->yank into line at pos. | ||||||
|  |    Return 0 on success, -1 if yank buffer is empty or too long */ | ||||||
|  | int yank_buf(ChatContext *ctx); | ||||||
|  |  | ||||||
| /* Removes trailing spaces from line. */ | /* Removes trailing spaces from line. */ | ||||||
| void rm_trailing_spaces_buf(ChatContext *ctx); | void rm_trailing_spaces_buf(ChatContext *ctx); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -183,6 +183,9 @@ struct ChatContext { | |||||||
|     int hst_pos; |     int hst_pos; | ||||||
|     int hst_tot; |     int hst_tot; | ||||||
|  |  | ||||||
|  |     wchar_t yank[MAX_STR_SIZE];    /* contains last killed/discarded line */ | ||||||
|  |     int yank_len; | ||||||
|  |  | ||||||
|     struct history *hst; |     struct history *hst; | ||||||
|     struct chatlog *log; |     struct chatlog *log; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user