diff --git a/src/chat.c b/src/chat.c index dbf8949..a6c1044 100644 --- a/src/chat.c +++ b/src/chat.c @@ -882,7 +882,6 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action) static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { - ChatContext *ctx = self->chatwin; StatusBar *statusbar = self->stb; @@ -898,7 +897,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) return; } - if (ltr) { /* char is printable */ + if (ltr || key == '\n') { /* char is printable */ input_new_char(self, key, x, y, x2, y2); if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->connection != TOX_CONNECTION_NONE) @@ -940,38 +939,42 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) sound_notify(self, notif_error, 0, NULL); } - } else if (key == '\n') { + } else if (key == '\r') { rm_trailing_spaces_buf(ctx); - char line[MAX_STR_SIZE]; - - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); - - if (!string_is_empty(line)) + if (!wstring_is_empty(ctx->line)) + { add_line_to_hist(ctx); - if (line[0] == '/') { - if (strcmp(line, "/close") == 0) { - kill_chat_window(self, m); - return; - } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { - send_action(self, ctx, m, line + strlen("/me ")); + wstrsubst(ctx->line, L'¶', L'\n'); + + char line[MAX_STR_SIZE] = {0}; + + if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) + memset(&line, 0, sizeof(line)); + + if (line[0] == '/') { + if (strcmp(line, "/close") == 0) { + kill_chat_window(self, m); + return; + } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { + send_action(self, ctx, m, line + strlen("/me ")); + } else { + execute(ctx->history, self, m, line, CHAT_COMMAND_MODE); + } } else { - execute(ctx->history, self, m, line, CHAT_COMMAND_MODE); + char selfname[TOX_MAX_NAME_LENGTH]; + tox_self_get_name(m, (uint8_t *) selfname); + + size_t len = tox_self_get_name_size(m); + selfname[len] = '\0'; + + char timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt, sizeof(timefrmt)); + + line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, "%s", line); + cqueue_add(ctx->cqueue, line, strlen(line), OUT_MSG, ctx->hst->line_end->id + 1); } - } else if (!string_is_empty(line)) { - char selfname[TOX_MAX_NAME_LENGTH]; - tox_self_get_name(m, (uint8_t *) selfname); - - size_t len = tox_self_get_name_size(m); - selfname[len] = '\0'; - - char timefrmt[TIME_STR_SIZE]; - get_time_str(timefrmt, sizeof(timefrmt)); - - line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, "%s", line); - cqueue_add(ctx->cqueue, line, strlen(line), OUT_MSG, ctx->hst->line_end->id + 1); } wclear(ctx->linewin); diff --git a/src/friendlist.c b/src/friendlist.c index a254750..08b06de 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -757,7 +757,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) return; switch (key) { - case '\n': + case '\r': if (blocklist_view) break; diff --git a/src/global_commands.c b/src/global_commands.c index 1cc2340..29ba6e4 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -36,6 +36,7 @@ #include "avatars.h" #include "name_lookup.h" #include "qr_code.h" +#include "toxic_strings.h" extern char *DATA_FILE; extern ToxWindow *prompt; @@ -513,11 +514,12 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA return; } - /* remove opening and closing quotes */ + /* remove opening and closing quotes and replace linebreaks with spaces */ char msg[MAX_STR_SIZE]; snprintf(msg, sizeof(msg), "%s", &argv[1][1]); int len = strlen(msg) - 1; msg[len] = '\0'; + strsubst(msg, '\n', ' '); prompt_update_statusmessage(prompt, m, msg); } diff --git a/src/groupchat.c b/src/groupchat.c index 1e9bcb4..dd8178a 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -571,7 +571,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) return; } - if (ltr) { /* char is printable */ + if (ltr || key == '\n') { /* char is printable */ input_new_char(self, key, x, y, x2, y2); return; } @@ -615,30 +615,34 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) } else if (key == user_settings->key_peer_list_up) { if (groupchats[self->num].side_pos > 0) --groupchats[self->num].side_pos; - } else if (key == '\n') { + } else if (key == '\r') { rm_trailing_spaces_buf(ctx); - char line[MAX_STR_SIZE]; - - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); - - if (!string_is_empty(line)) + if (!wstring_is_empty(ctx->line)) + { add_line_to_hist(ctx); - if (line[0] == '/') { - if (strcmp(line, "/close") == 0) { - close_groupchat(self, m, self->num); - return; - } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { - send_group_action(self, ctx, m, line + strlen("/me ")); + wstrsubst(ctx->line, L'¶', L'\n'); + + char line[MAX_STR_SIZE]; + + if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) + memset(&line, 0, sizeof(line)); + + if (line[0] == '/') { + if (strcmp(line, "/close") == 0) { + close_groupchat(self, m, self->num); + return; + } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { + send_group_action(self, ctx, m, line + strlen("/me ")); + } else { + execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE); + } } else { - execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE); - } - } else if (!string_is_empty(line)) { - if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) { - const char *errmsg = " * Failed to send message."; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); + if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) { + const char *errmsg = " * Failed to send message."; + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); + } } } diff --git a/src/input.c b/src/input.c index 4186c4d..b1b95a8 100644 --- a/src/input.c +++ b/src/input.c @@ -42,9 +42,12 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_ { ChatContext *ctx = self->chatwin; + /* this is the only place we need to do this check */ + if (key == '\n') + key = L'¶'; + int cur_len = wcwidth(key); - /* this is the only place we need to do this check */ if (cur_len == -1) { sound_notify(self, notif_error, 0, NULL); return; diff --git a/src/misc_tools.c b/src/misc_tools.c index d86c338..b737a7c 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -176,6 +176,15 @@ int string_is_empty(const char *string) return string[0] == '\0'; } +/* Returns 1 if the string is empty, 0 otherwise */ +int wstring_is_empty(const wchar_t *string) +{ + if (!string) + return true; + + return string[0] == L'\0'; +} + /* convert a multibyte string to a wide character string and puts in buf. */ int mbs_to_wcs_buf(wchar_t *buf, const char *string, size_t n) { diff --git a/src/misc_tools.h b/src/misc_tools.h index d49a288..f4875b8 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -78,6 +78,9 @@ void update_unix_time(void); /* Returns 1 if the string is empty, 0 otherwise */ int string_is_empty(const char *string); +/* Same as above but for wide character strings */ +int wstring_is_empty(const wchar_t *string); + /* convert a multibyte string to a wide character string (must provide buffer) */ int char_to_wcs_buf(wchar_t *buf, const char *string, size_t n); diff --git a/src/prompt.c b/src/prompt.c index d921a57..2488d94 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -195,7 +195,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) return; } - if (ltr) { /* char is printable */ + if (ltr || key == '\n') { /* char is printable */ input_new_char(self, key, x, y, x2, y2); return; } @@ -232,19 +232,22 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) } else { sound_notify(self, notif_error, 0, NULL); } - } else if (key == '\n') { + } else if (key == '\r') { rm_trailing_spaces_buf(ctx); - char line[MAX_STR_SIZE] = {0}; - - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); - - if (!string_is_empty(line)) + if (!wstring_is_empty(ctx->line)) + { add_line_to_hist(ctx); + wstrsubst(ctx->line, L'¶', L'\n'); - line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line); - execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); + char line[MAX_STR_SIZE] = {0}; + + if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) + memset(&line, 0, sizeof(line)); + + line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line); + execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); + } wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); diff --git a/src/toxic.c b/src/toxic.c index 4fb533a..07a4ed8 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -200,6 +200,7 @@ static void init_term(void) cbreak(); keypad(stdscr, 1); noecho(); + nonl(); timeout(100); if (has_colors()) { diff --git a/src/toxic_strings.c b/src/toxic_strings.c index e2417ba..e17c5bb 100644 --- a/src/toxic_strings.c +++ b/src/toxic_strings.c @@ -166,19 +166,19 @@ void reset_buf(ChatContext *ctx) ctx->start = 0; } -/* Removes trailing spaces from line. */ +/* Removes trailing spaces and newlines from line. */ void rm_trailing_spaces_buf(ChatContext *ctx) { if (ctx->len <= 0) return; - if (ctx->line[ctx->len - 1] != ' ') + if (ctx->line[ctx->len - 1] != ' ' && ctx->line[ctx->len - 1] != L'¶') return; int i; for (i = ctx->len - 1; i >= 0; --i) { - if (ctx->line[i] != ' ') + if (ctx->line[i] != ' ' && ctx->line[i] != L'¶') break; } @@ -242,3 +242,19 @@ void fetch_hist_item(ChatContext *ctx, int key_dir) ctx->pos = h_len; ctx->len = h_len; } + +void strsubst(char* str, char old, char new) +{ + int i; + for (i = 0; str[i] != '\0'; ++i) + if (str[i] == old) + str[i] = new; +} + +void wstrsubst(wchar_t* str, wchar_t old, wchar_t new) +{ + int i; + for (i = 0; str[i] != L'\0'; ++i) + if (str[i] == old) + str[i] = new; +} diff --git a/src/toxic_strings.h b/src/toxic_strings.h index 3c957ef..c9e402c 100644 --- a/src/toxic_strings.h +++ b/src/toxic_strings.h @@ -66,4 +66,8 @@ void add_line_to_hist(ChatContext *ctx); resets line if at end of history */ void fetch_hist_item(ChatContext *ctx, int key_dir); +/* Substitutes all occurrences of old with new. */ +void strsubst(char *str, char old, char new); +void wstrsubst(wchar_t *str, wchar_t old, wchar_t new); + #endif /* #define TOXIC_STRINGS_H */