diff options
Diffstat (limited to 'src/gui/curses/gui-curses-key.c')
-rw-r--r-- | src/gui/curses/gui-curses-key.c | 351 |
1 files changed, 182 insertions, 169 deletions
diff --git a/src/gui/curses/gui-curses-key.c b/src/gui/curses/gui-curses-key.c index 1f06e8d33..b74c19f4f 100644 --- a/src/gui/curses/gui-curses-key.c +++ b/src/gui/curses/gui-curses-key.c @@ -290,202 +290,189 @@ gui_key_default_bindings (int context) */ void -gui_key_flush (int ignore_bracketed) +gui_key_flush (int paste) { - int i, j, key, insert_ok; + int i, key, last_key_used, insert_ok, undo_done; static char key_str[64] = { '\0' }; static int length_key_str = 0; char key_temp[2], *key_utf, *input_old, *ptr_char, *next_char, *ptr_error; char utf_partial_char[16]; + /* if paste pending or bracketed paste detected, just return */ + if (gui_key_paste_pending || gui_key_paste_bracketed) + return; + + /* if buffer is empty, just return */ + if (gui_key_buffer_size == 0) + return; + /* * if there's no paste pending, then we use buffer and do actions * according to keys */ - if (!gui_key_paste_pending) + gui_key_last_activity_time = time (NULL); + last_key_used = -1; + undo_done = 0; + for (i = 0; i < gui_key_buffer_size; i++) { - if (gui_key_buffer_size > 0) - gui_key_last_activity_time = time (NULL); + key = gui_key_buffer[i]; + insert_ok = 1; + utf_partial_char[0] = '\0'; - for (i = 0; i < gui_key_buffer_size; i++) + if (gui_mouse_event_pending || (key < 32) || (key == 127)) { - key = gui_key_buffer[i]; - insert_ok = 1; - utf_partial_char[0] = '\0'; - - if (gui_mouse_event_pending || (key < 32) || (key == 127)) + if (gui_mouse_event_pending) { - if (gui_mouse_event_pending) - { - insert_ok = 0; - key_str[0] = (char)key; - key_str[1] = '\0'; - length_key_str = 1; - } - else if (key < 32) - { - insert_ok = 0; - key_str[0] = '\x01'; - key_str[1] = (char)key + '@'; - key_str[2] = '\0'; - length_key_str = 2; - } - else if (key == 127) - { - key_str[0] = '\x01'; - key_str[1] = '?'; - key_str[2] = '\0'; - length_key_str = 2; - } + insert_ok = 0; + key_str[0] = (char)key; + key_str[1] = '\0'; + length_key_str = 1; } - else + else if (key < 32) { - if (local_utf8) + insert_ok = 0; + key_str[0] = '\x01'; + key_str[1] = (char)key + '@'; + key_str[2] = '\0'; + length_key_str = 2; + } + else if (key == 127) + { + key_str[0] = '\x01'; + key_str[1] = '?'; + key_str[2] = '\0'; + length_key_str = 2; + } + } + else + { + if (local_utf8) + { + key_str[length_key_str] = (char)key; + key_str[length_key_str + 1] = '\0'; + length_key_str++; + + /* + * replace invalid chars by "?", but NOT last char of + * string, if it is incomplete UTF-8 char (another char + * will be added to the string on next iteration) + */ + ptr_char = key_str; + while (ptr_char && ptr_char[0]) { - key_str[length_key_str] = (char)key; - key_str[length_key_str + 1] = '\0'; - length_key_str++; - - /* - * replace invalid chars by "?", but NOT last char of - * string, if it is incomplete UTF-8 char (another char - * will be added to the string on next iteration) - */ - ptr_char = key_str; - while (ptr_char && ptr_char[0]) + (void) utf8_is_valid (ptr_char, &ptr_error); + if (!ptr_error) + break; + next_char = utf8_next_char (ptr_error); + if (next_char && next_char[0]) { - (void) utf8_is_valid (ptr_char, &ptr_error); - if (!ptr_error) - break; - next_char = utf8_next_char (ptr_error); - if (next_char && next_char[0]) - { - ptr_char = ptr_error; - while (ptr_char < next_char) - { - ptr_char[0] = '?'; - ptr_char++; - } - } - else + ptr_char = ptr_error; + while (ptr_char < next_char) { - strcpy (utf_partial_char, ptr_char); - ptr_char[0] = '\0'; - break; + ptr_char[0] = '?'; + ptr_char++; } - ptr_char = next_char; } - } - else - { - /* convert input to UTF-8 */ - key_temp[0] = (char) key; - key_temp[1] = '\0'; - key_utf = string_iconv_to_internal (NULL, key_temp); - strcat (key_str, key_utf); + else + { + strcpy (utf_partial_char, ptr_char); + ptr_char[0] = '\0'; + break; + } + ptr_char = next_char; } } - - if (key_str[0]) + else { - hook_signal_send ("key_pressed", - WEECHAT_HOOK_SIGNAL_STRING, key_str); + /* convert input to UTF-8 */ + key_temp[0] = (char)key; + key_temp[1] = '\0'; + key_utf = string_iconv_to_internal (NULL, key_temp); + strcat (key_str, key_utf); + } + } - if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) - input_old = (gui_current_window->buffer->input_buffer) ? - strdup (gui_current_window->buffer->input_buffer) : strdup (""); - else - input_old = NULL; + if (key_str[0]) + { + hook_signal_send ("key_pressed", + WEECHAT_HOOK_SIGNAL_STRING, key_str); - if ((gui_key_pressed (key_str) != 0) && (insert_ok) - && (!gui_cursor_mode)) - { + if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) + input_old = (gui_current_window->buffer->input_buffer) ? + strdup (gui_current_window->buffer->input_buffer) : strdup (""); + else + input_old = NULL; + + if ((gui_key_pressed (key_str) != 0) && (insert_ok) + && (!gui_cursor_mode)) + { + if (!paste || !undo_done) gui_buffer_undo_snap (gui_current_window->buffer); - gui_input_insert_string (gui_current_window->buffer, - key_str, -1); - if (gui_current_window->buffer->completion) - gui_completion_stop (gui_current_window->buffer->completion, 0); - gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1); - } + gui_input_insert_string (gui_current_window->buffer, + key_str, -1); + if (gui_current_window->buffer->completion) + gui_completion_stop (gui_current_window->buffer->completion, 0); + gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, + (!paste || !undo_done) ? 1 : 0); + undo_done = 1; + } - /* incremental text search in buffer */ - if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) - && ((input_old == NULL) - || (gui_current_window->buffer->input_buffer == NULL) - || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0))) + /* incremental text search in buffer */ + if ((gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) + && ((input_old == NULL) + || (gui_current_window->buffer->input_buffer == NULL) + || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0))) + { + /* + * if current input is longer than old input, and that + * beginning of current input is exactly equal to old input, + * then do nothing (search will not find any result and can + * take some time on buffer with many lines..) + */ + if (!gui_current_window->buffer->text_search_found + && (input_old != NULL) + && (input_old[0]) + && (gui_current_window->buffer->input_buffer != NULL) + && (gui_current_window->buffer->input_buffer[0]) + && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old)) + && (strncmp (gui_current_window->buffer->input_buffer, input_old, + strlen (input_old)) == 0)) { /* - * if current input is longer than old input, and that - * beginning of current input is exactly equal to old input, - * then do nothing (search will not find any result and can - * take some time on buffer with many lines..) + * do not search text in buffer, just alert about text not + * found */ - if (!gui_current_window->buffer->text_search_found - && (input_old != NULL) - && (input_old[0]) - && (gui_current_window->buffer->input_buffer != NULL) - && (gui_current_window->buffer->input_buffer[0]) - && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old)) - && (strncmp (gui_current_window->buffer->input_buffer, input_old, - strlen (input_old)) == 0)) - { - /* - * do not search text in buffer, just alert about text not - * found - */ - if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert)) - printf ("\a"); - } - else - { - gui_window_search_restart (gui_current_window); - } + if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert)) + printf ("\a"); } - - if (input_old) - free (input_old); - } - - /* prepare incomplete UTF-8 char for next iteration */ - if (utf_partial_char[0]) - strcpy (key_str, utf_partial_char); - else - key_str[0] = '\0'; - length_key_str = strlen (key_str); - - /* - * bracketed paste detected (ESC[200~ + text + ESC[201~): - * the ESC[200~ has been found and will be removed immediately, - * the ESC[201~ should be found/removed later) - */ - if (gui_key_paste_bracketed) - { - gui_key_paste_bracketed = 0; - - if (!ignore_bracketed) + else { - /* check for large paste */ - if (gui_key_paste_check (1)) - { - /* - * paste mode has been enabled (ask to user what do to), - * then remove the ESC[200~ from beginning of buffer, - * stop reading buffer immediately and return - */ - i++; - for (j = 0; j < gui_key_buffer_size - i; j++) - { - gui_key_buffer[j] = gui_key_buffer[j + i]; - } - gui_key_buffer_size -= i; - return; - } + gui_window_search_restart (gui_current_window); } } + + if (input_old) + free (input_old); } - gui_key_buffer_reset (); + /* prepare incomplete UTF-8 char for next iteration */ + if (utf_partial_char[0]) + strcpy (key_str, utf_partial_char); + else + key_str[0] = '\0'; + length_key_str = strlen (key_str); + + /* set last key used in buffer if combo buffer is empty */ + if (!gui_key_combo_buffer[0]) + last_key_used = i; } + + if (last_key_used == gui_key_buffer_size - 1) + gui_key_buffer_reset (); + else if (last_key_used >= 0) + gui_key_buffer_remove (0, last_key_used + 1); + + gui_key_combo_buffer[0] = '\0'; } /* @@ -495,8 +482,7 @@ gui_key_flush (int ignore_bracketed) int gui_key_read_cb (void *data, int fd) { - int ret, i, accept_paste, cancel_paste, text_added_to_buffer; - int ignore_bracketed_paste; + int ret, i, accept_paste, cancel_paste, text_added_to_buffer, pos; unsigned char buffer[4096]; /* make C compiler happy */ @@ -506,7 +492,6 @@ gui_key_read_cb (void *data, int fd) accept_paste = 0; cancel_paste = 0; text_added_to_buffer = 0; - ignore_bracketed_paste = 0; ret = read (STDIN_FILENO, buffer, sizeof (buffer)); if (ret == 0) @@ -542,11 +527,6 @@ gui_key_read_cb (void *data, int fd) /* ctrl-N: cancel paste */ cancel_paste = 1; } - else - { - gui_key_buffer_add (buffer[i]); - text_added_to_buffer = 1; - } } else { @@ -562,7 +542,6 @@ gui_key_read_cb (void *data, int fd) { /* user is ok for pasting text, let's paste! */ gui_key_paste_accept (); - ignore_bracketed_paste = 1; } else if (cancel_paste) { @@ -576,9 +555,43 @@ gui_key_read_cb (void *data, int fd) } } else - gui_key_paste_check (0); + { + if (!gui_key_paste_bracketed) + { + pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_START); + if (pos >= 0) + { + gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH); + gui_key_paste_bracketed_start (); + } + } - gui_key_flush (ignore_bracketed_paste); + if (!gui_key_paste_bracketed) + gui_key_paste_check (0); + } + + gui_key_flush ((accept_paste) ? 1 : 0); + + if (gui_key_paste_bracketed) + { + pos = gui_key_buffer_search (0, -1, GUI_KEY_BRACKETED_PASTE_END); + if (pos >= 0) + { + /* remove the code for end of bracketed paste (ESC[201~) */ + gui_key_buffer_remove (pos, GUI_KEY_BRACKETED_PASTE_LENGTH); + + /* remove final newline (if needed) */ + gui_key_paste_remove_newline (); + + /* stop bracketed mode */ + gui_key_paste_bracketed_timer_remove (); + gui_key_paste_bracketed_stop (); + + /* if paste confirmation not displayed, flush buffer now */ + if (!gui_key_paste_pending) + gui_key_flush (1); + } + } return WEECHAT_RC_OK; } |