/* * Copyright (c) 2003-2009 by FlashCode * See README for License detail, AUTHORS for developers list. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* gui-input.c: input functions, used by all GUI */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "../core/weechat.h" #include "../core/wee-config.h" #include "../core/wee-hook.h" #include "../core/wee-input.h" #include "../core/wee-string.h" #include "../core/wee-utf8.h" #include "../plugins/plugin.h" #include "gui-input.h" #include "gui-buffer.h" #include "gui-completion.h" #include "gui-history.h" #include "gui-hotlist.h" #include "gui-keyboard.h" #include "gui-line.h" #include "gui-window.h" char *gui_input_clipboard = NULL; /* clipboard content */ /* * gui_input_optimize_size: optimize input buffer size by adding * or deleting data block (predefined size) */ void gui_input_optimize_size (struct t_gui_buffer *buffer) { int optimal_size; if (buffer->input) { optimal_size = ((buffer->input_buffer_size / GUI_BUFFER_INPUT_BLOCK_SIZE) * GUI_BUFFER_INPUT_BLOCK_SIZE) + GUI_BUFFER_INPUT_BLOCK_SIZE; if (buffer->input_buffer_alloc != optimal_size) { buffer->input_buffer_alloc = optimal_size; buffer->input_buffer = realloc (buffer->input_buffer, optimal_size); } } } /* * gui_input_replace_input: replace full input by another string, trying to * keep cursor position is new string is long enough */ void gui_input_replace_input (struct t_gui_buffer *buffer, const char *new_input) { int size, length; size = strlen (new_input); length = utf8_strlen (new_input); /* compute new buffer size */ buffer->input_buffer_size = size; buffer->input_buffer_length = length; gui_input_optimize_size (buffer); /* copy new string to input */ strcpy (buffer->input_buffer, new_input); /* move cursor to the end of new input if it is now after the end */ if (buffer->input_buffer_pos > buffer->input_buffer_length) buffer->input_buffer_pos = buffer->input_buffer_length; } /* * gui_input_paste_pending_signal: send signal "input_paste_pending" */ void gui_input_paste_pending_signal () { hook_signal_send ("input_paste_pending", WEECHAT_HOOK_SIGNAL_STRING, NULL); } /* * gui_input_text_changed_modifier_and_signal: send modifier and signal * "input_text_changed" */ void gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer) { char str_buffer[128], *new_input; /* send modifier, and change input if needed */ snprintf (str_buffer, sizeof (str_buffer), "0x%lx", (long unsigned int)buffer); new_input = hook_modifier_exec (NULL, "input_text_content", str_buffer, (buffer->input_buffer) ? buffer->input_buffer : ""); if (new_input) { if (strcmp (new_input, buffer->input_buffer) != 0) { /* input has been changed by modifier, use it */ gui_input_replace_input (buffer, new_input); } free (new_input); } /* send signal */ hook_signal_send ("input_text_changed", WEECHAT_HOOK_SIGNAL_STRING, NULL); } /* * gui_input_text_cursor_moved_signal: send signal "input_text_cursor_moved" */ void gui_input_text_cursor_moved_signal () { hook_signal_send ("input_text_cursor_moved", WEECHAT_HOOK_SIGNAL_STRING, NULL); } /* * gui_input_search_signal: send signal "input_search" */ void gui_input_search_signal () { hook_signal_send ("input_search", WEECHAT_HOOK_SIGNAL_STRING, NULL); } /* * gui_input_move: move data in input buffer */ void gui_input_move (struct t_gui_buffer *buffer, char *target, const char *source, int size) { int pos_source, pos_target; pos_target = target - buffer->input_buffer; pos_source = source - buffer->input_buffer; memmove (target, source, size); } /* * gui_input_insert_string: insert a string into the input buffer * if pos == -1, string is inserted at cursor position * return: number of chars inserted * (may be different of strlen if UTF-8 string) */ int gui_input_insert_string (struct t_gui_buffer *buffer, const char *string, int pos) { int pos_start, size, length; char *ptr_start; if (buffer->input) { if (pos == -1) pos = buffer->input_buffer_pos; size = strlen (string); length = utf8_strlen (string); /* increase buffer size */ buffer->input_buffer_size += size; buffer->input_buffer_length += length; gui_input_optimize_size (buffer); buffer->input_buffer[buffer->input_buffer_size] = '\0'; /* move end of string to the right */ ptr_start = utf8_add_offset (buffer->input_buffer, pos); pos_start = ptr_start - buffer->input_buffer; memmove (ptr_start + size, ptr_start, strlen (ptr_start)); /* insert new string */ ptr_start = utf8_add_offset (buffer->input_buffer, pos); pos_start = ptr_start - buffer->input_buffer; strncpy (ptr_start, string, size); buffer->input_buffer_pos += length; return length; } return 0; } /* * gui_input_clipboard_copy: copy string into clipboard */ void gui_input_clipboard_copy (const char *buffer, int size) { if (size <= 0) return; if (gui_input_clipboard != NULL) free (gui_input_clipboard); gui_input_clipboard = malloc((size + 1) * sizeof(*gui_input_clipboard)); if (gui_input_clipboard) { memcpy (gui_input_clipboard, buffer, size); gui_input_clipboard[size] = '\0'; } } /* * gui_action_clipboard_paste: paste clipboard at cursor pos in input line */ void gui_input_clipboard_paste () { if ((gui_current_window->buffer->input) && gui_input_clipboard) { gui_input_insert_string (gui_current_window->buffer, gui_input_clipboard, -1); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_input_return: terminate line */ void gui_input_return () { char *command; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) { gui_window_search_stop (gui_current_window); gui_input_search_signal (); } else if (gui_current_window->buffer->input_buffer_size > 0) { gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; command = strdup (gui_current_window->buffer->input_buffer); if (!command) return; gui_history_buffer_add (gui_current_window->buffer, gui_current_window->buffer->input_buffer); gui_history_global_add (gui_current_window->buffer->input_buffer); gui_current_window->buffer->input_buffer[0] = '\0'; gui_current_window->buffer->input_buffer_size = 0; gui_current_window->buffer->input_buffer_length = 0; gui_current_window->buffer->input_buffer_pos = 0; gui_current_window->buffer->input_buffer_1st_display = 0; gui_completion_stop (gui_current_window->buffer->completion, 1); gui_current_window->buffer->ptr_history = NULL; gui_input_optimize_size (gui_current_window->buffer); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); input_data (gui_current_window->buffer, command); free (command); } } } /* * gui_input_complete: complete a word in input buffer */ void gui_input_complete (struct t_gui_buffer *buffer) { int i; if (!buffer->completion) return; if (buffer->completion->word_found) { /* replace word with new completed word into input buffer */ if (buffer->completion->diff_size > 0) { buffer->input_buffer_size += buffer->completion->diff_size; buffer->input_buffer_length += buffer->completion->diff_length; gui_input_optimize_size (buffer); buffer->input_buffer[buffer->input_buffer_size] = '\0'; for (i = buffer->input_buffer_size - 1; i >= buffer->completion->position_replace + (int)strlen (buffer->completion->word_found); i--) { buffer->input_buffer[i] = buffer->input_buffer[i - buffer->completion->diff_size]; } } else { for (i = buffer->completion->position_replace + strlen (buffer->completion->word_found); i < buffer->input_buffer_size; i++) { buffer->input_buffer[i] = buffer->input_buffer[i - buffer->completion->diff_size]; } buffer->input_buffer_size += buffer->completion->diff_size; buffer->input_buffer_length += buffer->completion->diff_length; gui_input_optimize_size (buffer); buffer->input_buffer[buffer->input_buffer_size] = '\0'; } strncpy (buffer->input_buffer + buffer->completion->position_replace, buffer->completion->word_found, strlen (buffer->completion->word_found)); buffer->input_buffer_pos = utf8_pos (buffer->input_buffer, buffer->completion->position_replace) + utf8_strlen (buffer->completion->word_found); /* position is < 0 this means only one word was found to complete, so reinit to stop completion */ if (buffer->completion->position >= 0) buffer->completion->position = utf8_real_pos (buffer->input_buffer, buffer->input_buffer_pos); /* add space if needed after completion */ if (buffer->completion->add_space) { if (buffer->input_buffer[utf8_real_pos (buffer->input_buffer, buffer->input_buffer_pos)] != ' ') gui_input_insert_string (buffer, " ", buffer->input_buffer_pos); else buffer->input_buffer_pos++; if (buffer->completion->position >= 0) buffer->completion->position++; } gui_input_text_changed_modifier_and_signal (buffer); } } /* * gui_input_complete_next: complete with next word (default key: tab) */ void gui_input_complete_next () { if ((gui_current_window->buffer->input) && (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { gui_completion_search (gui_current_window->buffer->completion, 1, gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_size, utf8_real_pos (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos)); gui_input_complete (gui_current_window->buffer); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_complete_previous: complete with previous word (default key: shift-tab) */ void gui_input_complete_previous () { if ((gui_current_window->buffer->input) && (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { gui_completion_search (gui_current_window->buffer->completion, -1, gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_size, utf8_real_pos (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos)); gui_input_complete (gui_current_window->buffer); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_input_search_text: search text in buffer history (default key: ctrl-r) */ void gui_input_search_text () { if (gui_current_window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) { /* toggle search */ if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) gui_window_search_start (gui_current_window); else { gui_current_window->buffer->text_search_exact ^= 1; gui_window_search_restart (gui_current_window); } gui_input_search_signal (); } } /* * gui_input_delete_previous_char: delete previous char (default key: backspace) */ void gui_input_delete_previous_char () { char *pos, *pos_last; int char_size, size_to_move; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_last = utf8_prev_char (gui_current_window->buffer->input_buffer, pos); char_size = pos - pos_last; size_to_move = strlen (pos); gui_input_move (gui_current_window->buffer, pos_last, pos, size_to_move); gui_current_window->buffer->input_buffer_size -= char_size; gui_current_window->buffer->input_buffer_length--; gui_current_window->buffer->input_buffer_pos--; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_delete_next_char: delete next char (default key: del) */ void gui_input_delete_next_char () { char *pos, *pos_next; int char_size, size_to_move; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_next = utf8_next_char (pos); char_size = pos_next - pos; size_to_move = strlen (pos_next); gui_input_move (gui_current_window->buffer, pos, pos_next, size_to_move); gui_current_window->buffer->input_buffer_size -= char_size; gui_current_window->buffer->input_buffer_length--; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_delete_previous_word: delete previous word (default key: ctrl-w) */ void gui_input_delete_previous_word () { int length_deleted, size_deleted; char *start, *string; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos - 1); string = start; while (string && (string[0] == ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } if (string) { while (string && (string[0] != ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } if (string) { while (string && (string[0] == ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } } } if (string) string = utf8_next_char (utf8_next_char (string)); else string = gui_current_window->buffer->input_buffer; size_deleted = utf8_next_char (start) - string; length_deleted = utf8_strnlen (string, size_deleted); gui_input_clipboard_copy (string, size_deleted); gui_input_move (gui_current_window->buffer, string, string + size_deleted, strlen (string + size_deleted)); gui_current_window->buffer->input_buffer_size -= size_deleted; gui_current_window->buffer->input_buffer_length -= length_deleted; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_current_window->buffer->input_buffer_pos -= length_deleted; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_delete_next_word: delete next word (default key: meta-d) */ void gui_input_delete_next_word () { int size_deleted, length_deleted; char *start, *string; if (gui_current_window->buffer->input) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); string = start; length_deleted = 0; while (string[0]) { if ((string[0] == ' ') && (string > start)) break; string = utf8_next_char (string); length_deleted++; } size_deleted = string - start; gui_input_clipboard_copy (start, size_deleted); gui_input_move (gui_current_window->buffer, start, string, strlen (string)); gui_current_window->buffer->input_buffer_size -= size_deleted; gui_current_window->buffer->input_buffer_length -= length_deleted; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_input_delete_beginning_of_line: delete all from cursor pos to beginning of line * (default key: ctrl-u) */ void gui_input_delete_beginning_of_line () { int length_deleted, size_deleted, pos_start; char *start; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_start = start - gui_current_window->buffer->input_buffer; size_deleted = start - gui_current_window->buffer->input_buffer; length_deleted = utf8_strnlen (gui_current_window->buffer->input_buffer, size_deleted); gui_input_clipboard_copy (gui_current_window->buffer->input_buffer, start - gui_current_window->buffer->input_buffer); gui_input_move (gui_current_window->buffer, gui_current_window->buffer->input_buffer, start, strlen (start)); gui_current_window->buffer->input_buffer_size -= size_deleted; gui_current_window->buffer->input_buffer_length -= length_deleted; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_current_window->buffer->input_buffer_pos = 0; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_delete_end_of_line: delete all from cursor pos to end of line * (default key: ctrl-k) */ void gui_input_delete_end_of_line (const char *args) { char *start; int size_deleted, length_deleted, pos_start; /* make C compiler happy */ (void) args; if (gui_current_window->buffer->input) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_start = start - gui_current_window->buffer->input_buffer; size_deleted = strlen (start); length_deleted = utf8_strlen (start); gui_input_clipboard_copy (start, size_deleted); start[0] = '\0'; gui_current_window->buffer->input_buffer_size = strlen (gui_current_window->buffer->input_buffer); gui_current_window->buffer->input_buffer_length = utf8_strlen (gui_current_window->buffer->input_buffer); gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_input_delete_line: delete entire line (default key: meta-r) */ void gui_input_delete_line () { if (gui_current_window->buffer->input) { gui_current_window->buffer->input_buffer[0] = '\0'; gui_current_window->buffer->input_buffer_size = 0; gui_current_window->buffer->input_buffer_length = 0; gui_current_window->buffer->input_buffer_pos = 0; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } /* * gui_input_transpose_chars: transpose chars (on lth left) at cursor pos * (default key: ctrl-t) */ void gui_input_transpose_chars () { char *start, *prev_char, saved_char[5]; int size_prev_char, size_start_char; int pos_prev_char, pos_start; if (gui_current_window->buffer->input) { if ((gui_current_window->buffer->input_buffer_pos > 0) && (gui_current_window->buffer->input_buffer_length > 1)) { if (gui_current_window->buffer->input_buffer_pos == gui_current_window->buffer->input_buffer_length) gui_current_window->buffer->input_buffer_pos--; start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_start = start - gui_current_window->buffer->input_buffer; prev_char = utf8_prev_char (gui_current_window->buffer->input_buffer, start); pos_prev_char = prev_char - gui_current_window->buffer->input_buffer; size_prev_char = start - prev_char; size_start_char = utf8_char_size (start); memcpy (saved_char, prev_char, size_prev_char); memcpy (prev_char, start, size_start_char); memcpy (prev_char + size_start_char, saved_char, size_prev_char); gui_current_window->buffer->input_buffer_pos++; gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_move_beginning_of_line: move cursor to beginning of line (default key: home) */ void gui_input_move_beginning_of_line () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { gui_current_window->buffer->input_buffer_pos = 0; gui_input_text_cursor_moved_signal (); } } } /* * gui_input_move_end_of_line: move cursor to end of line (default key: end) */ void gui_input_move_end_of_line () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; gui_input_text_cursor_moved_signal (); } } } /* * gui_input_move_previous_char: move cursor to previous char (default key: left) */ void gui_input_move_previous_char () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { gui_current_window->buffer->input_buffer_pos--; gui_input_text_cursor_moved_signal (); } } } /* * gui_input_move_next_char: move cursor to next char (default key: right) */ void gui_input_move_next_char () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { gui_current_window->buffer->input_buffer_pos++; gui_input_text_cursor_moved_signal (); } } } /* * gui_input_move_previous_word: move cursor to beginning of previous word * (default key: meta-b or ctrl-left) */ void gui_input_move_previous_word () { char *pos; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos - 1); while (pos && (pos[0] == ' ')) { pos = utf8_prev_char (gui_current_window->buffer->input_buffer, pos); } if (pos) { while (pos && (pos[0] != ' ')) { pos = utf8_prev_char (gui_current_window->buffer->input_buffer, pos); } if (pos) pos = utf8_next_char (pos); else pos = gui_current_window->buffer->input_buffer; gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, pos - gui_current_window->buffer->input_buffer); } else gui_current_window->buffer->input_buffer_pos = 0; gui_input_text_cursor_moved_signal (); } } } /* * gui_input_move_next_word: move cursor to the beginning of next word * (default key: meta-f or ctrl-right) */ void gui_input_move_next_word () { char *pos; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); while (pos[0] && (pos[0] == ' ')) { pos = utf8_next_char (pos); } if (pos[0]) { while (pos[0] && (pos[0] != ' ')) { pos = utf8_next_char (pos); } if (pos[0]) gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, pos - gui_current_window->buffer->input_buffer); else gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; } else gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, utf8_prev_char (gui_current_window->buffer->input_buffer, pos) - gui_current_window->buffer->input_buffer); gui_input_text_cursor_moved_signal (); } } } /* * gui_input_history_previous: recall previous command (default key: up) */ void gui_input_history_previous () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { if (gui_current_window->buffer->ptr_history) { if (!gui_current_window->buffer->ptr_history->next_history) return; gui_current_window->buffer->ptr_history = gui_current_window->buffer->ptr_history->next_history; if (!gui_current_window->buffer->ptr_history) gui_current_window->buffer->ptr_history = gui_current_window->buffer->history; } else gui_current_window->buffer->ptr_history = gui_current_window->buffer->history; if (gui_current_window->buffer->ptr_history) { /* bash/readline like use of history */ if (gui_current_window->buffer->ptr_history->prev_history == NULL) { if (gui_current_window->buffer->input_buffer_size > 0) { gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_history_buffer_add (gui_current_window->buffer, gui_current_window->buffer->input_buffer); gui_history_global_add (gui_current_window->buffer->input_buffer); } } else { if (gui_current_window->buffer->input_buffer_size > 0) { gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; if (gui_current_window->buffer->ptr_history->prev_history->text) free(gui_current_window->buffer->ptr_history->prev_history->text); gui_current_window->buffer->ptr_history->prev_history->text = strdup (gui_current_window->buffer->input_buffer); } } gui_current_window->buffer->input_buffer_size = strlen (gui_current_window->buffer->ptr_history->text); gui_current_window->buffer->input_buffer_length = utf8_strlen (gui_current_window->buffer->ptr_history->text); gui_input_optimize_size (gui_current_window->buffer); gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; gui_current_window->buffer->input_buffer_1st_display = 0; strcpy (gui_current_window->buffer->input_buffer, gui_current_window->buffer->ptr_history->text); } gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } else { /* search backward in buffer history */ gui_current_window->buffer->text_search = GUI_TEXT_SEARCH_BACKWARD; (void) gui_window_search_text (gui_current_window); } } } /* * gui_input_history_next: recall next command (default key: down) */ void gui_input_history_next () { if (gui_current_window->buffer->input) { if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { if (gui_current_window->buffer->ptr_history) { gui_current_window->buffer->ptr_history = gui_current_window->buffer->ptr_history->prev_history; if (gui_current_window->buffer->ptr_history) { gui_current_window->buffer->input_buffer_size = strlen (gui_current_window->buffer->ptr_history->text); gui_current_window->buffer->input_buffer_length = utf8_strlen (gui_current_window->buffer->ptr_history->text); } else { gui_current_window->buffer->input_buffer[0] = '\0'; gui_current_window->buffer->input_buffer_size = 0; gui_current_window->buffer->input_buffer_length = 0; } gui_input_optimize_size (gui_current_window->buffer); gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; gui_current_window->buffer->input_buffer_1st_display = 0; if (gui_current_window->buffer->ptr_history) { strcpy (gui_current_window->buffer->input_buffer, gui_current_window->buffer->ptr_history->text); } } else { /* add line to history then clear input */ if (gui_current_window->buffer->input_buffer_size > 0) { gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_history_buffer_add (gui_current_window->buffer, gui_current_window->buffer->input_buffer); gui_history_global_add (gui_current_window->buffer->input_buffer); gui_current_window->buffer->input_buffer[0] = '\0'; gui_current_window->buffer->input_buffer_size = 0; gui_current_window->buffer->input_buffer_length = 0; gui_current_window->buffer->input_buffer_pos = 0; gui_current_window->buffer->input_buffer_1st_display = 0; gui_input_optimize_size (gui_current_window->buffer); } } gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } else { /* search forward in buffer history */ gui_current_window->buffer->text_search = GUI_TEXT_SEARCH_FORWARD; (void) gui_window_search_text (gui_current_window); } } } /* * gui_input_history_global_previous: recall previous command in global history * (default key: ctrl-up) */ void gui_input_history_global_previous () { if ((gui_current_window->buffer->input) && (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { if (history_global_ptr) { history_global_ptr = history_global_ptr->next_history; if (!history_global_ptr) history_global_ptr = history_global; } else history_global_ptr = history_global; if (history_global_ptr) { gui_current_window->buffer->input_buffer_size = strlen (history_global_ptr->text); gui_current_window->buffer->input_buffer_length = utf8_strlen (history_global_ptr->text); gui_input_optimize_size (gui_current_window->buffer); gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; gui_current_window->buffer->input_buffer_1st_display = 0; strcpy (gui_current_window->buffer->input_buffer, history_global_ptr->text); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_history_global_next: recall next command in global history * (default key: ctrl-down) */ void gui_input_history_global_next () { if ((gui_current_window->buffer->input) && (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { if (history_global_ptr) { history_global_ptr = history_global_ptr->prev_history; if (history_global_ptr) { gui_current_window->buffer->input_buffer_size = strlen (history_global_ptr->text); gui_current_window->buffer->input_buffer_length = utf8_strlen (history_global_ptr->text); } else { gui_current_window->buffer->input_buffer_size = 0; gui_current_window->buffer->input_buffer_length = 0; } gui_input_optimize_size (gui_current_window->buffer); gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; gui_current_window->buffer->input_buffer_1st_display = 0; if (history_global_ptr) { strcpy (gui_current_window->buffer->input_buffer, history_global_ptr->text); } gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } } /* * gui_input_jump_smart: jump to buffer with activity (default key: alt-A) */ void gui_input_jump_smart () { if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { if (gui_hotlist) { if (!gui_hotlist_initial_buffer) gui_hotlist_initial_buffer = gui_current_window->buffer; gui_window_switch_to_buffer (gui_current_window, gui_hotlist->buffer, 1); gui_window_scroll_bottom (gui_current_window); } else { if (gui_hotlist_initial_buffer) { gui_window_switch_to_buffer (gui_current_window, gui_hotlist_initial_buffer, 1); gui_window_scroll_bottom (gui_current_window); gui_hotlist_initial_buffer = NULL; } } } } /* * gui_input_jump_last_buffer: jump to last buffer * (default key: meta-j, meta-l) */ void gui_input_jump_last_buffer () { if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { if (last_gui_buffer) gui_buffer_switch_by_number (gui_current_window, last_gui_buffer->number); } } /* * gui_input_jump_previously_visited_buffer: jump to previously visited buffer * (buffer displayed before current one) * (default key: meta-<) */ void gui_input_jump_previously_visited_buffer () { int index; struct t_gui_buffer_visited *ptr_buffer_visited; if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { index = gui_buffer_visited_get_index_previous (); if (index >= 0) { gui_buffers_visited_index = index; ptr_buffer_visited = gui_buffer_visited_search_by_number (gui_buffers_visited_index); if (ptr_buffer_visited) { gui_buffers_visited_frozen = 1; gui_buffer_switch_by_number (gui_current_window, ptr_buffer_visited->buffer->number); gui_buffers_visited_frozen = 0; } } } } /* * gui_input_jump_next_visited_buffer: jump to next visited buffer * (buffer displayed after current one) * (default key: meta->) */ void gui_input_jump_next_visited_buffer () { int index; struct t_gui_buffer_visited *ptr_buffer_visited; if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { index = gui_buffer_visited_get_index_next (); if (index >= 0) { gui_buffers_visited_index = index; ptr_buffer_visited = gui_buffer_visited_search_by_number (gui_buffers_visited_index); if (ptr_buffer_visited) { gui_buffers_visited_frozen = 1; gui_buffer_switch_by_number (gui_current_window, ptr_buffer_visited->buffer->number); gui_buffers_visited_frozen = 0; } } } } /* * gui_input_hotlist_clear: clear hotlist (default key: meta-h) */ void gui_input_hotlist_clear () { gui_hotlist_clear (); gui_hotlist_initial_buffer = gui_current_window->buffer; } /* * gui_input_grab_key: init "grab key mode" (next key will be inserted into * input buffer) (default key: meta-k) */ void gui_input_grab_key () { if (gui_current_window->buffer->input) gui_keyboard_grab_init (); } /* * gui_input_scroll_unread: scroll to first unread line of buffer * (default key: meta-u) */ void gui_input_scroll_unread () { if (gui_current_window->buffer->text_search == GUI_TEXT_SEARCH_DISABLED) { if (CONFIG_STRING(config_look_read_marker) && CONFIG_STRING(config_look_read_marker)[0] && (gui_current_window->buffer->type == GUI_BUFFER_TYPE_FORMATTED) && (gui_current_window->buffer->lines->first_line_not_read || (gui_current_window->buffer->lines->last_read_line && gui_current_window->buffer->lines->last_read_line != gui_current_window->buffer->lines->last_line))) { if (gui_current_window->buffer->lines->first_line_not_read) gui_current_window->start_line = gui_current_window->buffer->lines->first_line; else gui_current_window->start_line = gui_current_window->buffer->lines->last_read_line->next_line; gui_current_window->start_line_pos = 0; gui_current_window->first_line_displayed = (gui_current_window->start_line == gui_line_get_first_displayed (gui_current_window->buffer)); gui_buffer_ask_chat_refresh (gui_current_window->buffer, 2); } } } /* * gui_input_set_unread: set unread marker for all buffers * (default key: ctrl-s, ctrl-u) */ void gui_input_set_unread () { struct t_gui_buffer *ptr_buffer; /* set read marker for all standard buffers */ for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) { gui_buffer_set_unread (ptr_buffer); } } /* * gui_input_set_unread_current_buffer: set unread marker for current buffer */ void gui_input_set_unread_current_buffer () { if (gui_current_window) gui_buffer_set_unread (gui_current_window->buffer); } /* * gui_input_switch_active_buffer: switch active buffer (when many buffers are * merged) */ void gui_input_switch_active_buffer () { struct t_gui_buffer *ptr_buffer; ptr_buffer = gui_buffer_get_next_active_buffer (gui_current_window->buffer); if (ptr_buffer) { gui_buffer_set_active_buffer (ptr_buffer); gui_window_switch_to_buffer (gui_current_window, ptr_buffer, 1); } } /* * gui_input_insert: insert a string in command line * (many default keys are bound to this function) */ void gui_input_insert (const char *args) { char *args2; if (args) { args2 = string_convert_hex_chars (args); gui_input_insert_string (gui_current_window->buffer, (args2) ? args2 : args, -1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); if (args2) free (args2); } }