diff --git a/src/chat.c b/src/chat.c index 872213e..e98cc4d 100644 --- a/src/chat.c +++ b/src/chat.c @@ -296,6 +296,18 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len); } + else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */ + if (ctx->pos > 0) { + discard_buf(ctx->line, &ctx->pos, &ctx->len); + wmove(self->window, y2 - CURS_Y_OFFSET, 0); + } + } + + else if (key == T_KEY_KILL) { /* CTRL-K: Delete entire line in front of pos */ + if (ctx->pos != ctx->len) + kill_buf(ctx->line, &ctx->pos, &ctx->len); + } + else if (key == KEY_HOME) { /* HOME key: Move cursor to beginning of line */ if (ctx->pos > 0) { ctx->pos = 0; diff --git a/src/groupchat.c b/src/groupchat.c index e33018a..5105261 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -239,6 +239,18 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len); } + else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */ + if (ctx->pos > 0) { + discard_buf(ctx->line, &ctx->pos, &ctx->len); + wmove(self->window, y2 - CURS_Y_OFFSET, 0); + } + } + + else if (key == T_KEY_KILL) { /* CTRL-K: Delete entire line in front of pos */ + if (ctx->pos != ctx->len) + kill_buf(ctx->line, &ctx->pos, &ctx->len); + } + else if (key == KEY_HOME) { /* HOME key: Move cursor to beginning of line */ if (ctx->pos > 0) { ctx->pos = 0; diff --git a/src/main.c b/src/main.c index 1222401..8ab8d8e 100644 --- a/src/main.c +++ b/src/main.c @@ -439,6 +439,7 @@ void exit_toxic(Tox *m) free(DATA_FILE); free(SRVLIST_FILE); free(prompt->stb); + free(prompt->promptbuf); tox_kill(m); endwin(); exit(EXIT_SUCCESS); diff --git a/src/misc_tools.c b/src/misc_tools.c index 797caf4..8ad5d5d 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -211,6 +211,32 @@ void del_char_buf_frnt(wchar_t *buf, size_t *pos, size_t *len) --(*len); } +/* Deletes the entire line before pos */ +void discard_buf(wchar_t *buf, size_t *pos, size_t *len) +{ + if (*pos <= 0) + return; + + int i; + int c = 0; + + for (i = *pos; i <= *len; ++i) + buf[c++] = buf[i]; + + *pos = 0; + *len = c - 1; +} + +/* Deletes the entire line in front of pos */ +void kill_buf(wchar_t *buf, size_t *pos, size_t *len) +{ + if (*len == *pos) + return; + + buf[*pos] = L'\0'; + *len = *pos; +} + /* nulls buf and sets pos and len to 0 */ void reset_buf(wchar_t *buf, size_t *pos, size_t *len) { diff --git a/src/prompt.c b/src/prompt.c index 815daa5..47fc736 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -93,6 +93,16 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) } } + else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */ + if (prt->pos > 0) + discard_buf(prt->line, &prt->pos, &prt->len); + } + + else if (key == T_KEY_KILL) { /* CTRL-K: Delete entire line in front of pos */ + if (prt->len != prt->pos) + kill_buf(prt->line, &prt->pos, &prt->len); + } + else if (key == KEY_HOME) { /* HOME key: Move cursor to beginning of line */ if (prt->pos != 0) prt->pos = 0; @@ -125,7 +135,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) } /* RETURN key: execute command */ else if (key == '\n') { - wprintw(self->window, "\n"); + wprintw(self->window, "\n"); uint8_t *line = wcs_to_char(prt->line); execute(self->window, self, m, line, GLOBAL_COMMAND_MODE); reset_buf(prt->line, &prt->pos, &prt->len); @@ -153,9 +163,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) if (prt->len > 0) { mvwprintw(self->window, prt->orig_y, X_OFST, wcs_to_char(prt->line)); - /* y distance between pos and len */ - int d = prt->pos < (prt->len - px2) ? (y2 - y - 1) : 0; + int d = y2 - y - 1; /* 1 if end of line is touching bottom of window, 0 otherwise */ int bot = prt->orig_y + ((prt->len + p_ofst) / px2) == y2; @@ -166,14 +175,14 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) prt->scroll = false; } - } else { - prt->orig_y = y; /* Mark point of origin for new line */ - - wattron(self->window, COLOR_PAIR(GREEN)); - mvwprintw(self->window, y, 0, "$ "); - wattroff(self->window, COLOR_PAIR(GREEN)); + } else { /* Mark point of origin for new line */ + prt->orig_y = y; } + wattron(self->window, COLOR_PAIR(GREEN)); + mvwprintw(self->window, prt->orig_y, 0, "$ "); + wattroff(self->window, COLOR_PAIR(GREEN)); + StatusBar *statusbar = self->stb; werase(statusbar->topline); mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2); @@ -216,8 +225,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) wattroff(statusbar->topline, A_BOLD); /* put cursor back in correct spot */ - int y_m = prt->pos <= 0 ? prt->orig_y : prt->orig_y + ((prt->pos + p_ofst) / px2); - int x_m = prt->pos > 0 ? (prt->pos + X_OFST) % x2 : X_OFST; + int y_m = prt->orig_y + ((prt->pos + p_ofst) / px2); + int x_m = (prt->pos + X_OFST) % x2; wmove(self->window, y_m, x_m); } @@ -256,7 +265,6 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int friendnum , u wprintw(self->window, "has gone offline\n"); wattroff(self->window, COLOR_PAIR(RED)); } - } static void prompt_onFriendRequest(ToxWindow *self, uint8_t *key, uint8_t *data, uint16_t length) diff --git a/src/prompt.h b/src/prompt.h index a2a4234..0bac30f 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -5,7 +5,7 @@ #ifndef PROMPT_H_UZYGWFFL #define PROMPT_H_UZYGWFFL -#define X_OFST 2 /* offset to account for prompt "# " */ +#define X_OFST 2 /* offset to account for prompt char */ ToxWindow new_prompt(void); void prompt_init_statusbar(ToxWindow *self, Tox *m); diff --git a/src/toxic_windows.h b/src/toxic_windows.h index 79f5435..6ac1b06 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -29,6 +29,9 @@ #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 +#define T_KEY_KILL 0xB /* ASCII code for ctrl-k */ +#define T_KEY_DISCARD 0x15 /* ASCII code for ctrl-u */ + /* Curses foreground colours (background is black) */ enum { WHITE, @@ -114,7 +117,7 @@ struct PromptBuf { wchar_t line[MAX_STR_SIZE]; size_t pos; size_t len; - int orig_y; + int orig_y; /* y axis point of origin for line */ bool scroll; /* used for prompt window hack to determine when to scroll down */ WINDOW *linewin; };