1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-23 06:23:02 +01:00

Merge branch 'mall0c-multiline'

This commit is contained in:
Jfreegman 2016-02-29 19:22:41 -05:00
commit f43f644451
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
20 changed files with 172 additions and 82 deletions

View File

@ -313,6 +313,11 @@ Key combination to scroll contacts list down\&.
.RS 4 .RS 4
Toggle the peer list on and off\&. Toggle the peer list on and off\&.
.RE .RE
.PP
\fBtoggle_paste_mode\fR
.RS 4
Toggle treating linebreaks as enter key press\&.
.RE
.RE .RE
.SH "FILES" .SH "FILES"
.PP .PP

View File

@ -201,6 +201,9 @@ OPTIONS
*toggle_peerlist*;; *toggle_peerlist*;;
Toggle the peer list on and off. Toggle the peer list on and off.
*toggle_paste_mode*;;
Toggle treating linebreaks as enter key press.
FILES FILES
----- -----

View File

@ -101,5 +101,6 @@ keys = {
peer_list_up="Ctrl+["; peer_list_up="Ctrl+[";
peer_list_down="Ctrl+]"; peer_list_down="Ctrl+]";
toggle_peerlist="Ctrl+b"; toggle_peerlist="Ctrl+b";
toggle_paste_mode="Ctrl+T";
}; };

View File

@ -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) static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{ {
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
StatusBar *statusbar = self->stb; StatusBar *statusbar = self->stb;
@ -893,12 +892,15 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (y2 <= 0 || x2 <= 0) if (y2 <= 0 || x2 <= 0)
return; return;
if (ctx->pastemode && key == '\r')
key = '\n';
if (self->help->active) { if (self->help->active) {
help_onKey(self, key); help_onKey(self, key);
return; return;
} }
if (ltr) { /* char is printable */ if (ltr || key == '\n') { /* char is printable */
input_new_char(self, key, x, y, x2, y2); input_new_char(self, key, x, y, x2, y2);
if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->connection != TOX_CONNECTION_NONE) if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->connection != TOX_CONNECTION_NONE)
@ -940,17 +942,20 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
sound_notify(self, notif_error, 0, NULL); sound_notify(self, notif_error, 0, NULL);
} }
} else if (key == '\n') { } else if (key == '\r') {
rm_trailing_spaces_buf(ctx); rm_trailing_spaces_buf(ctx);
char line[MAX_STR_SIZE]; if (!wstring_is_empty(ctx->line))
{
add_line_to_hist(ctx);
wstrsubst(ctx->line, L'', L'\n');
char line[MAX_STR_SIZE] = {0};
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
if (!string_is_empty(line))
add_line_to_hist(ctx);
if (line[0] == '/') { if (line[0] == '/') {
if (strcmp(line, "/close") == 0) { if (strcmp(line, "/close") == 0) {
kill_chat_window(self, m); kill_chat_window(self, m);
@ -960,7 +965,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} else { } else {
execute(ctx->history, self, m, line, CHAT_COMMAND_MODE); execute(ctx->history, self, m, line, CHAT_COMMAND_MODE);
} }
} else if (!string_is_empty(line)) { } else {
char selfname[TOX_MAX_NAME_LENGTH]; char selfname[TOX_MAX_NAME_LENGTH];
tox_self_get_name(m, (uint8_t *) selfname); tox_self_get_name(m, (uint8_t *) selfname);
@ -973,6 +978,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, "%s", line); 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); cqueue_add(ctx->cqueue, line, strlen(line), OUT_MSG, ctx->hst->line_end->id + 1);
} }
}
wclear(ctx->linewin); wclear(ctx->linewin);
wmove(self->window, y2 - CURS_Y_OFFSET, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0);

View File

@ -757,7 +757,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
return; return;
switch (key) { switch (key) {
case '\n': case '\r':
if (blocklist_view) if (blocklist_view)
break; break;

View File

@ -36,6 +36,7 @@
#include "avatars.h" #include "avatars.h"
#include "name_lookup.h" #include "name_lookup.h"
#include "qr_code.h" #include "qr_code.h"
#include "toxic_strings.h"
extern char *DATA_FILE; extern char *DATA_FILE;
extern ToxWindow *prompt; extern ToxWindow *prompt;
@ -513,11 +514,12 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
return; return;
} }
/* remove opening and closing quotes */ /* remove opening and closing quotes and replace linebreaks with spaces */
char msg[MAX_STR_SIZE]; char msg[MAX_STR_SIZE];
snprintf(msg, sizeof(msg), "%s", &argv[1][1]); snprintf(msg, sizeof(msg), "%s", &argv[1][1]);
int len = strlen(msg) - 1; int len = strlen(msg) - 1;
msg[len] = '\0'; msg[len] = '\0';
strsubst(msg, '\n', ' ');
prompt_update_statusmessage(prompt, m, msg); prompt_update_statusmessage(prompt, m, msg);
} }

View File

@ -571,7 +571,10 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
return; return;
} }
if (ltr) { /* char is printable */ if (ctx->pastemode && key == '\r')
key = '\n';
if (ltr || key == '\n') { /* char is printable */
input_new_char(self, key, x, y, x2, y2); input_new_char(self, key, x, y, x2, y2);
return; return;
} }
@ -615,17 +618,20 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} else if (key == user_settings->key_peer_list_up) { } else if (key == user_settings->key_peer_list_up) {
if (groupchats[self->num].side_pos > 0) if (groupchats[self->num].side_pos > 0)
--groupchats[self->num].side_pos; --groupchats[self->num].side_pos;
} else if (key == '\n') { } else if (key == '\r') {
rm_trailing_spaces_buf(ctx); rm_trailing_spaces_buf(ctx);
if (!wstring_is_empty(ctx->line))
{
add_line_to_hist(ctx);
wstrsubst(ctx->line, L'', L'\n');
char line[MAX_STR_SIZE]; char line[MAX_STR_SIZE];
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
if (!string_is_empty(line))
add_line_to_hist(ctx);
if (line[0] == '/') { if (line[0] == '/') {
if (strcmp(line, "/close") == 0) { if (strcmp(line, "/close") == 0) {
close_groupchat(self, m, self->num); close_groupchat(self, m, self->num);
@ -635,12 +641,13 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} else { } else {
execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE); execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE);
} }
} else if (!string_is_empty(line)) { } else {
if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) { if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) {
const char *errmsg = " * Failed to send message."; const char *errmsg = " * Failed to send message.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
} }
} }
}
wclear(ctx->linewin); wclear(ctx->linewin);
wmove(self->window, y2 - CURS_Y_OFFSET, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0);

View File

@ -245,7 +245,9 @@ static void help_draw_keys(ToxWindow *self)
wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n"); wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n");
wprintw(win, " Ctrl+H : Move to the bottom of window history\n"); wprintw(win, " Ctrl+H : Move to the bottom of window history\n");
wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n"); wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n");
wprintw(win, " Ctrl+B : Toggle the groupchat peerlist\n\n"); wprintw(win, " Ctrl+B : Toggle the groupchat peerlist\n");
wprintw(win, " Ctrl+J : Insert new line\n");
wprintw(win, " Ctrl+T : Toggle paste mode\n\n");
wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n"); wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n");
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -335,7 +337,7 @@ void help_onKey(ToxWindow *self, wint_t key)
break; break;
case 'k': case 'k':
help_init_window(self, 13, 80); help_init_window(self, 15, 80);
self->help->type = HELP_KEYS; self->help->type = HELP_KEYS;
break; break;

View File

@ -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; 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); int cur_len = wcwidth(key);
/* this is the only place we need to do this check */
if (cur_len == -1) { if (cur_len == -1) {
sound_notify(self, notif_error, 0, NULL); sound_notify(self, notif_error, 0, NULL);
return; return;
@ -266,15 +269,19 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
/* TODO: this special case is ugly. /* TODO: this special case is ugly.
maybe convert entire function to if/else and make them all customizable keys? */ maybe convert entire function to if/else and make them all customizable keys? */
if (!match && key == user_settings->key_toggle_peerlist) { if (!match) {
if (key == user_settings->key_toggle_peerlist) {
if (self->is_groupchat) { if (self->is_groupchat) {
self->show_peerlist ^= 1; self->show_peerlist ^= 1;
redraw_groupchat_win(self); redraw_groupchat_win(self);
} }
match = true; match = true;
} }
else if (key == user_settings->key_toggle_pastemode) {
self->chatwin->pastemode ^= 1;
match = true;
}
}
return match; return match;
} }

View File

@ -323,18 +323,28 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s %s: ", user_settings->line_normal, line->name1); wprintw(win, "%s %s: ", user_settings->line_normal, line->name1);
wattroff(win, COLOR_PAIR(nameclr)); wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == '>') char* msg = line->msg;
while (msg)
{
char* line = strsep(&msg, "\n");
if (line[0] == '>')
wattron(win, COLOR_PAIR(GREEN)); wattron(win, COLOR_PAIR(GREEN));
else if (line->msg[0] == '<') else if (line[0] == '<')
wattron(win, COLOR_PAIR(RED)); wattron(win, COLOR_PAIR(RED));
wprintw(win, "%s", line->msg); wprintw(win, "%s%c", line, msg ? '\n' : '\0');
if (line->msg[0] == '>') if (line[0] == '>')
wattroff(win, COLOR_PAIR(GREEN)); wattroff(win, COLOR_PAIR(GREEN));
else if (line->msg[0] == '<') else if (line[0] == '<')
wattroff(win, COLOR_PAIR(RED)); wattroff(win, COLOR_PAIR(RED));
// change the \0 set by strsep back to \n
if (msg)
msg[-1] = '\n';
}
if (type == OUT_MSG && timed_out(line->timestamp, NOREAD_FLAG_TIMEOUT)) { if (type == OUT_MSG && timed_out(line->timestamp, NOREAD_FLAG_TIMEOUT)) {
wattron(win, COLOR_PAIR(RED)); wattron(win, COLOR_PAIR(RED));
wprintw(win, " x", line->msg); wprintw(win, " x", line->msg);

View File

@ -176,6 +176,15 @@ int string_is_empty(const char *string)
return string[0] == '\0'; 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. */ /* 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) int mbs_to_wcs_buf(wchar_t *buf, const char *string, size_t n)
{ {

View File

@ -78,6 +78,9 @@ void update_unix_time(void);
/* Returns 1 if the string is empty, 0 otherwise */ /* Returns 1 if the string is empty, 0 otherwise */
int string_is_empty(const char *string); 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) */ /* 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); int char_to_wcs_buf(wchar_t *buf, const char *string, size_t n);

View File

@ -189,13 +189,16 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (x2 <= 0 || y2 <= 0) if (x2 <= 0 || y2 <= 0)
return; return;
if (ctx->pastemode && key == '\r')
key = '\n';
/* ignore non-menu related input if active */ /* ignore non-menu related input if active */
if (self->help->active) { if (self->help->active) {
help_onKey(self, key); help_onKey(self, key);
return; return;
} }
if (ltr) { /* char is printable */ if (ltr || key == '\n') { /* char is printable */
input_new_char(self, key, x, y, x2, y2); input_new_char(self, key, x, y, x2, y2);
return; return;
} }
@ -232,19 +235,22 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} else { } else {
sound_notify(self, notif_error, 0, NULL); sound_notify(self, notif_error, 0, NULL);
} }
} else if (key == '\n') { } else if (key == '\r') {
rm_trailing_spaces_buf(ctx); rm_trailing_spaces_buf(ctx);
if (!wstring_is_empty(ctx->line))
{
add_line_to_hist(ctx);
wstrsubst(ctx->line, L'', L'\n');
char line[MAX_STR_SIZE] = {0}; char line[MAX_STR_SIZE] = {0};
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
if (!string_is_empty(line))
add_line_to_hist(ctx);
line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line); line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line);
execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
}
wclear(ctx->linewin); wclear(ctx->linewin);
wmove(self->window, y2 - CURS_Y_OFFSET, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0);

View File

@ -127,6 +127,7 @@ static const struct keys_strings {
const char* peer_list_up; const char* peer_list_up;
const char* peer_list_down; const char* peer_list_down;
const char* toggle_peerlist; const char* toggle_peerlist;
const char* toggle_pastemode;
} key_strings = { } key_strings = {
"keys", "keys",
"next_tab", "next_tab",
@ -139,6 +140,7 @@ static const struct keys_strings {
"peer_list_up", "peer_list_up",
"peer_list_down", "peer_list_down",
"toggle_peerlist", "toggle_peerlist",
"toggle_paste_mode",
}; };
/* defines from toxic.h */ /* defines from toxic.h */
@ -154,6 +156,7 @@ static void key_defaults(struct user_settings* settings)
settings->key_peer_list_up = T_KEY_C_LB; settings->key_peer_list_up = T_KEY_C_LB;
settings->key_peer_list_down = T_KEY_C_RB; settings->key_peer_list_down = T_KEY_C_RB;
settings->key_toggle_peerlist = T_KEY_C_B; settings->key_toggle_peerlist = T_KEY_C_B;
settings->key_toggle_pastemode = T_KEY_C_T;
} }
static const struct tox_strings { static const struct tox_strings {
@ -399,6 +402,8 @@ int settings_load(struct user_settings *s, const char *patharg)
s->key_peer_list_down = key_parse(&tmp); s->key_peer_list_down = key_parse(&tmp);
if (config_setting_lookup_string(setting, key_strings.toggle_peerlist, &tmp)) if (config_setting_lookup_string(setting, key_strings.toggle_peerlist, &tmp))
s->key_toggle_peerlist = key_parse(&tmp); s->key_toggle_peerlist = key_parse(&tmp);
if (config_setting_lookup_string(setting, key_strings.toggle_pastemode, &tmp))
s->key_toggle_pastemode = key_parse(&tmp);
} }
#ifdef AUDIO #ifdef AUDIO

View File

@ -68,6 +68,7 @@ struct user_settings {
int key_peer_list_up; int key_peer_list_up;
int key_peer_list_down; int key_peer_list_down;
int key_toggle_peerlist; int key_toggle_peerlist;
int key_toggle_pastemode;
int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */ int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */
char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH]; char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH];

View File

@ -200,6 +200,7 @@ static void init_term(void)
cbreak(); cbreak();
keypad(stdscr, 1); keypad(stdscr, 1);
noecho(); noecho();
nonl();
timeout(100); timeout(100);
if (has_colors()) { if (has_colors()) {

View File

@ -70,6 +70,7 @@
#define T_KEY_C_L 0x0C /* ctrl-l */ #define T_KEY_C_L 0x0C /* ctrl-l */
#define T_KEY_C_W 0x17 /* ctrl-w */ #define T_KEY_C_W 0x17 /* ctrl-w */
#define T_KEY_C_B 0x02 /* ctrl-b */ #define T_KEY_C_B 0x02 /* ctrl-b */
#define T_KEY_C_T 0x14 /* ctrl-t */
#define T_KEY_TAB 0x09 /* TAB key */ #define T_KEY_TAB 0x09 /* TAB key */
#define ONLINE_CHAR "*" #define ONLINE_CHAR "*"

View File

@ -166,19 +166,19 @@ void reset_buf(ChatContext *ctx)
ctx->start = 0; ctx->start = 0;
} }
/* Removes trailing spaces from line. */ /* Removes trailing spaces and newlines from line. */
void rm_trailing_spaces_buf(ChatContext *ctx) void rm_trailing_spaces_buf(ChatContext *ctx)
{ {
if (ctx->len <= 0) if (ctx->len <= 0)
return; return;
if (ctx->line[ctx->len - 1] != ' ') if (ctx->line[ctx->len - 1] != ' ' && ctx->line[ctx->len - 1] != L'')
return; return;
int i; int i;
for (i = ctx->len - 1; i >= 0; --i) { for (i = ctx->len - 1; i >= 0; --i) {
if (ctx->line[i] != ' ') if (ctx->line[i] != ' ' && ctx->line[i] != L'')
break; break;
} }
@ -242,3 +242,19 @@ void fetch_hist_item(ChatContext *ctx, int key_dir)
ctx->pos = h_len; ctx->pos = h_len;
ctx->len = 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;
}

View File

@ -66,4 +66,8 @@ void add_line_to_hist(ChatContext *ctx);
resets line if at end of history */ resets line if at end of history */
void fetch_hist_item(ChatContext *ctx, int key_dir); 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 */ #endif /* #define TOXIC_STRINGS_H */

View File

@ -237,6 +237,7 @@ struct ChatContext {
#endif #endif
uint8_t self_is_typing; uint8_t self_is_typing;
uint8_t pastemode; /* whether to translate \r to \n */
WINDOW *history; WINDOW *history;
WINDOW *linewin; WINDOW *linewin;