diff options
Diffstat (limited to 'src/gui/gui-key.c')
-rw-r--r-- | src/gui/gui-key.c | 172 |
1 files changed, 145 insertions, 27 deletions
diff --git a/src/gui/gui-key.c b/src/gui/gui-key.c index 4882860b4..e505e868c 100644 --- a/src/gui/gui-key.c +++ b/src/gui/gui-key.c @@ -85,6 +85,8 @@ int gui_key_buffer_size = 0; /* input buffer size in bytes */ int gui_key_paste_pending = 0; /* 1 is big paste was detected and */ /* WeeChat is asking user what to do */ int gui_key_paste_bracketed = 0; /* bracketed paste mode detected */ +struct t_hook *gui_key_paste_bracketed_timer = NULL; + /* timer for bracketed paste */ int gui_key_paste_lines = 0; /* number of lines for pending paste */ time_t gui_key_last_activity_time = 0; /* last activity time (key) */ @@ -1399,25 +1401,75 @@ gui_key_buffer_add (unsigned char key) } /* - * gui_key_paste_start: start paste of text + * gui_key_buffer_search: search a string in gui_key_buffer (array of integers) + * start_index must be >= 0 + * if max_index is negative, the search is until end of buffer + * return index for string found in gui_key_buffer + * (not from "start_index" but from beginning of gui_key_buffer) + * or -1 if string is not found + */ + +int +gui_key_buffer_search (int start_index, int max_index, const char *string) +{ + int i, j, length, found; + + if ((gui_key_buffer_size == 0) || !string || !string[0]) + return -1; + + length = strlen (string); + + if (gui_key_buffer_size < length) + return -1; + + if (max_index < 0) + max_index = gui_key_buffer_size - length; + else if (max_index > gui_key_buffer_size - length) + max_index = gui_key_buffer_size - length; + + for (i = start_index; i <= max_index; i++) + { + found = 1; + for (j = 0; j < length; j++) + { + if (gui_key_buffer[i + j] != string[j]) + { + found = 0; + break; + } + } + if (found) + return i; + } + + /* string not found */ + return -1; +} + +/* + * gui_key_buffer_remove: remove some chars from gui_key_buffer */ void -gui_key_paste_start () +gui_key_buffer_remove (int index, int number) { - /* remove the "ESC[201~" at the end of buffer (end of bracketed paste) */ - if ((gui_key_buffer_size >= 6) - && (gui_key_buffer[gui_key_buffer_size - 6] == '\x1B') - && (gui_key_buffer[gui_key_buffer_size- 5] == '[') - && (gui_key_buffer[gui_key_buffer_size - 4] == '2') - && (gui_key_buffer[gui_key_buffer_size - 3] == '0') - && (gui_key_buffer[gui_key_buffer_size - 2] == '1') - && (gui_key_buffer[gui_key_buffer_size - 1] == '~')) + int i; + + for (i = index; i < gui_key_buffer_size - number; i++) { - gui_key_buffer_size -= 6; + gui_key_buffer[i] = gui_key_buffer[i + number]; } + gui_key_buffer_size -= number; +} - /* remove final newline if there is only one line to paste */ +/* + * gui_key_paste_remove_newline: remove final newline at enf of paste if there + * is only one line to paste + */ + +void +gui_key_paste_remove_newline () +{ if ((gui_key_paste_lines <= 1) && (gui_key_buffer_size > 0) && ((gui_key_buffer[gui_key_buffer_size - 1] == '\r') @@ -1426,20 +1478,18 @@ gui_key_paste_start () gui_key_buffer_size--; gui_key_paste_lines = 0; } - - gui_key_paste_pending = 1; - gui_input_paste_pending_signal (); } /* - * gui_key_paste_bracket_start: start bracketed paste of text - * (ESC[200~ detected) + * gui_key_paste_start: start paste of text */ void -gui_key_paste_bracketed_start () +gui_key_paste_start () { - gui_key_paste_bracketed = 1; + gui_key_paste_remove_newline (); + gui_key_paste_pending = 1; + gui_input_paste_pending_signal (); } /* @@ -1455,15 +1505,11 @@ gui_key_get_paste_lines () length = gui_key_buffer_size; - if ((length >= 6) - && (gui_key_buffer[length - 6] == '\x1B') - && (gui_key_buffer[length- 5] == '[') - && (gui_key_buffer[length - 4] == '2') - && (gui_key_buffer[length - 3] == '0') - && (gui_key_buffer[length - 2] == '1') - && (gui_key_buffer[length - 1] == '~')) + if (length >= GUI_KEY_BRACKETED_PASTE_LENGTH) { - length -= 6; + if (gui_key_buffer_search (length - GUI_KEY_BRACKETED_PASTE_LENGTH, -1, + GUI_KEY_BRACKETED_PASTE_END) >= 0) + length -= GUI_KEY_BRACKETED_PASTE_LENGTH; } if ((length > 0) @@ -1506,6 +1552,78 @@ gui_key_paste_check (int bracketed_paste) } /* + * gui_key_paste_bracketed_timer_cb: callback for bracketed paste timer + */ + +int +gui_key_paste_bracketed_timer_cb (void *data, int remaining_calls) +{ + /* make C compiler happy */ + (void) data; + (void) remaining_calls; + + gui_key_paste_bracketed_timer = NULL; + + if (gui_key_paste_bracketed) + gui_key_paste_bracketed_stop (); + + return WEECHAT_RC_OK; +} + +/* + * gui_key_paste_bracketed_timer_remove: remove timer for bracketed paste + */ + +void +gui_key_paste_bracketed_timer_remove () +{ + if (gui_key_paste_bracketed_timer) + { + unhook (gui_key_paste_bracketed_timer); + gui_key_paste_bracketed_timer = NULL; + } +} + +/* + * gui_key_paste_bracketed_timer_add: add timer for bracketed paste + */ + +void +gui_key_paste_bracketed_timer_add () +{ + gui_key_paste_bracketed_timer_remove (); + gui_key_paste_bracketed_timer = hook_timer (NULL, + CONFIG_INTEGER(config_look_paste_bracketed_timer_delay) * 1000, + 0, 1, + &gui_key_paste_bracketed_timer_cb, NULL); +} + +/* + * gui_key_paste_bracketed_start: start bracketed paste of text + * (ESC[200~ detected) + */ + +void +gui_key_paste_bracketed_start () +{ + gui_key_paste_bracketed = 1; + gui_key_paste_bracketed_timer_add (); +} + +/* + * gui_key_paste_bracketed_stop: stop bracketed paste of text + * (ESC[201~ detected or timeout while waiting for + * this code) + */ + +void +gui_key_paste_bracketed_stop () +{ + gui_key_paste_check (1); + gui_key_paste_bracketed = 0; +} + +/* * gui_key_paste_accept: accept paste from user */ |