4 Copyright (C) 1999 Timo Sirainen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "module-formats.h"
26 #include "special-vars.h"
30 #include "completion.h"
31 #include "command-history.h"
33 #include "printtext.h"
36 #include "gui-entry.h"
37 #include "gui-windows.h"
42 typedef void (*ENTRY_REDIRECT_KEY_FUNC) (int key, void *data, SERVER_REC *server, WI_ITEM_REC *item);
43 typedef void (*ENTRY_REDIRECT_ENTRY_FUNC) (const char *line, void *data, SERVER_REC *server, WI_ITEM_REC *item);
51 static KEYBOARD_REC *keyboard;
52 static ENTRY_REDIRECT_REC *redir;
53 static int escape_next_key;
56 static unichar prev_key;
57 static GTimeVal last_keypress;
59 static int paste_detect_time, paste_verify_line_count;
60 static char *paste_entry;
61 static int paste_entry_pos;
62 static GArray *paste_buffer;
64 static char *paste_old_prompt;
65 static int paste_prompt, paste_line_count;
66 static int paste_join_multiline;
67 static int paste_timeout_id;
69 static void sig_input(void);
71 void input_listen_init(int handle)
73 readtag = g_input_add_poll(handle,
74 G_PRIORITY_HIGH, G_INPUT_READ,
75 (GInputFunction) sig_input, NULL);
78 void input_listen_deinit(void)
80 g_source_remove(readtag);
84 static void handle_key_redirect(int key)
86 ENTRY_REDIRECT_KEY_FUNC func;
89 func = (ENTRY_REDIRECT_KEY_FUNC) redir->func;
91 g_free_and_null(redir);
93 gui_entry_set_prompt(active_entry, "");
96 func(key, data, active_win->active_server, active_win->active);
99 static void handle_entry_redirect(const char *line)
101 ENTRY_REDIRECT_ENTRY_FUNC func;
104 gui_entry_set_hidden(active_entry, FALSE);
106 func = (ENTRY_REDIRECT_ENTRY_FUNC) redir->func;
108 g_free_and_null(redir);
110 gui_entry_set_prompt(active_entry, "");
113 func(line, data, active_win->active_server,
118 static int get_scroll_count(void)
123 str = settings_get_str("scroll_page_count");
124 count = atof(str + (*str == '/'));
128 count = active_mainwin->height-active_mainwin->statusbar_lines+count;
133 count = (active_mainwin->height-active_mainwin->statusbar_lines)/count;
138 static void window_prev_page(void)
140 gui_window_scroll(active_win, -get_scroll_count());
143 static void window_next_page(void)
145 gui_window_scroll(active_win, get_scroll_count());
148 static void paste_buffer_join_lines(GArray *buf)
150 #define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
151 unsigned int i, count, indent, line_len;
152 unichar *arr, *dest, *last_lf_pos;
155 /* first check if we actually want to join anything. This is assuming
156 that we only want to join lines if
158 a) first line doesn't begin with whitespace
159 b) subsequent lines begin with same amount of whitespace
160 c) whenever there's no whitespace, goto a)
180 arr = (unichar *) paste_buffer->data;
183 if (IS_WHITE(arr[0]))
186 /* find the first beginning of indented line */
187 for (i = 1; i < buf->len; i++) {
188 if (arr[i-1] == '\n' && IS_WHITE(arr[i]))
194 /* get how much indentation we have.. */
195 for (indent = 0; i < buf->len; i++, indent++) {
196 if (!IS_WHITE(arr[i]))
202 /* now, enforce these to all subsequent lines */
203 count = indent; last_lf = TRUE;
204 for (; i < buf->len; i++) {
206 if (IS_WHITE(arr[i]))
210 if (count != 0 && count != indent)
219 /* all looks fine - now remove the whitespace, but don't let lines
220 get longer than 400 chars */
221 dest = arr; last_lf = TRUE; last_lf_pos = NULL; line_len = 0;
222 for (i = 0; i < buf->len; i++) {
223 if (last_lf && IS_WHITE(arr[i])) {
224 /* whitespace, ignore */
225 } else if (arr[i] == '\n') {
226 if (!last_lf && i+1 != buf->len &&
227 IS_WHITE(arr[i+1])) {
231 *dest++ = '\n'; /* double-LF */
238 if (++line_len >= 400 && last_lf_pos != NULL) {
239 memmove(last_lf_pos+1, last_lf_pos,
241 *last_lf_pos = '\n'; last_lf_pos = NULL;
248 g_array_set_size(buf, dest - arr);
251 static void paste_send(void)
253 HISTORY_REC *history;
259 if (paste_join_multiline)
260 paste_buffer_join_lines(paste_buffer);
262 arr = (unichar *) paste_buffer->data;
263 if (active_entry->text_len == 0)
266 /* first line has to be kludged kind of to get pasting in the
267 middle of line right.. */
268 for (i = 0; i < paste_buffer->len; i++) {
269 if (arr[i] == '\r' || arr[i] == '\n') {
274 gui_entry_insert_char(active_entry, arr[i]);
277 text = gui_entry_get_text(active_entry);
278 history = command_history_current(active_win);
279 command_history_add(history, text);
281 signal_emit("send command", 3, text,
282 active_win->active_server, active_win->active);
286 /* rest of the lines */
287 str = g_string_new(NULL);
288 for (; i < paste_buffer->len; i++) {
289 if (arr[i] == '\r' || arr[i] == '\n') {
290 history = command_history_current(active_win);
291 command_history_add(history, str->str);
293 signal_emit("send command", 3, str->str,
294 active_win->active_server,
296 g_string_truncate(str, 0);
297 } else if (active_entry->utf8) {
298 out[g_unichar_to_utf8(arr[i], out)] = '\0';
299 g_string_append(str, out);
300 } else if (term_type == TERM_TYPE_BIG5) {
302 g_string_append_c(str, (arr[i] >> 8) & 0xff);
303 g_string_append_c(str, arr[i] & 0xff);
305 g_string_append_c(str, arr[i]);
309 gui_entry_set_text(active_entry, str->str);
310 g_string_free(str, TRUE);
313 static void paste_flush(int send)
316 gui_entry_set_text(active_entry, paste_entry);
317 gui_entry_set_pos(active_entry, paste_entry_pos);
318 g_free_and_null(paste_entry);
323 g_array_set_size(paste_buffer, 0);
325 gui_entry_set_prompt(active_entry,
326 paste_old_prompt == NULL ? "" : paste_old_prompt);
327 g_free(paste_old_prompt); paste_old_prompt = NULL;
328 paste_prompt = FALSE;
330 paste_line_count = 0;
332 gui_entry_redraw(active_entry);
335 static void insert_paste_prompt(void)
340 paste_old_prompt = g_strdup(active_entry->prompt);
341 printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
344 active_win->active == NULL ? "window" :
345 active_win->active->visible_name);
347 str = format_get_text(MODULE_NAME, active_win, NULL, NULL,
348 TXT_PASTE_PROMPT, 0, 0);
349 gui_entry_set_prompt(active_entry, str);
350 paste_entry = gui_entry_get_text(active_entry);
351 paste_entry_pos = gui_entry_get_pos(active_entry);
352 gui_entry_set_text(active_entry, "");
356 static void sig_gui_key_pressed(gpointer keyp)
363 key = GPOINTER_TO_INT(keyp);
365 if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HOTKEY) {
366 handle_key_redirect(key);
370 g_get_current_time(&now);
375 str[1] = (char)key+'@';
377 } else if (key == 127) {
381 } else if (!active_entry->utf8) {
386 str[0] = (char) (key >> 8);
387 str[1] = (char) (key & 0xff);
391 /* need to convert to utf8 */
392 str[g_unichar_to_utf8(key, str)] = '\0';
395 if (strcmp(str, "^") == 0) {
396 /* change it as ^^ */
401 if (escape_next_key) {
402 escape_next_key = FALSE;
403 gui_entry_insert_char(active_entry, key);
406 ret = key_pressed(keyboard, str);
408 /* key wasn't used for anything, print it */
409 gui_entry_insert_char(active_entry, key);
413 /* ret = 0 : some key create multiple characters - we're in the middle
414 of one. try to detect the keycombo as a single keypress rather than
415 multiple small onces to avoid incorrect paste detection.
417 don't count repeated keys so paste detection won't go on when
418 you're holding some key down */
419 if (ret != 0 && key != prev_key) {
425 static void key_send_line(void)
427 HISTORY_REC *history;
431 str = gui_entry_get_text(active_entry);
433 /* we can't use gui_entry_get_text() later, since the entry might
434 have been destroyed after we get back */
435 add_history = *str != '\0';
436 history = command_history_current(active_win);
439 signal_emit("send command", 3, str,
440 active_win->active_server,
443 if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN)
445 handle_entry_redirect(str);
449 history = command_history_find(history);
451 command_history_add(history, str);
454 if (active_entry != NULL)
455 gui_entry_set_text(active_entry, "");
456 command_history_clear_pos(active_win);
461 static void key_combo(void)
465 static void key_backward_history(void)
470 line = gui_entry_get_text(active_entry);
471 text = command_history_prev(active_win, line);
472 gui_entry_set_text(active_entry, text);
476 static void key_forward_history(void)
481 line = gui_entry_get_text(active_entry);
482 text = command_history_next(active_win, line);
483 gui_entry_set_text(active_entry, text);
487 static void key_beginning_of_line(void)
489 gui_entry_set_pos(active_entry, 0);
492 static void key_end_of_line(void)
494 gui_entry_set_pos(active_entry, active_entry->text_len);
497 static void key_backward_character(void)
499 gui_entry_move_pos(active_entry, -1);
502 static void key_forward_character(void)
504 gui_entry_move_pos(active_entry, 1);
507 static void key_backward_word(void)
509 gui_entry_move_words(active_entry, -1, FALSE);
512 static void key_forward_word(void)
514 gui_entry_move_words(active_entry, 1, FALSE);
517 static void key_backward_to_space(void)
519 gui_entry_move_words(active_entry, -1, TRUE);
522 static void key_forward_to_space(void)
524 gui_entry_move_words(active_entry, 1, TRUE);
527 static void key_erase_line(void)
529 gui_entry_set_pos(active_entry, active_entry->text_len);
530 gui_entry_erase(active_entry, active_entry->text_len, TRUE);
533 static void key_erase_to_beg_of_line(void)
537 pos = gui_entry_get_pos(active_entry);
538 gui_entry_erase(active_entry, pos, TRUE);
541 static void key_erase_to_end_of_line(void)
545 pos = gui_entry_get_pos(active_entry);
546 gui_entry_set_pos(active_entry, active_entry->text_len);
547 gui_entry_erase(active_entry, active_entry->text_len - pos, TRUE);
550 static void key_yank_from_cutbuffer(void)
554 cutbuffer = gui_entry_get_cutbuffer(active_entry);
555 if (cutbuffer != NULL) {
556 gui_entry_insert_text(active_entry, cutbuffer);
561 static void key_transpose_characters(void)
563 gui_entry_transpose_chars(active_entry);
566 static void key_transpose_words(void)
568 gui_entry_transpose_words(active_entry);
571 static void key_capitalize_word(void)
573 gui_entry_capitalize_word(active_entry);
576 static void key_downcase_word(void)
578 gui_entry_downcase_word(active_entry);
580 static void key_upcase_word(void)
582 gui_entry_upcase_word(active_entry);
585 static void key_delete_character(void)
587 if (gui_entry_get_pos(active_entry) < active_entry->text_len) {
588 gui_entry_erase_cell(active_entry);
592 static void key_backspace(void)
594 gui_entry_erase(active_entry, 1, FALSE);
597 static void key_delete_previous_word(void)
599 gui_entry_erase_word(active_entry, FALSE);
602 static void key_delete_next_word(void)
604 gui_entry_erase_next_word(active_entry, FALSE);
607 static void key_delete_to_previous_space(void)
609 gui_entry_erase_word(active_entry, TRUE);
612 static void key_delete_to_next_space(void)
614 gui_entry_erase_next_word(active_entry, TRUE);
617 static gboolean paste_timeout(gpointer data)
619 if (paste_line_count == 0) {
622 for (i = 0; i < paste_buffer->len; i++) {
623 unichar key = g_array_index(paste_buffer, unichar, i);
624 signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
626 g_array_set_size(paste_buffer, 0);
627 } else if (paste_verify_line_count > 0 &&
628 paste_line_count >= paste_verify_line_count &&
629 active_win->active != NULL)
630 insert_paste_prompt();
633 paste_timeout_id = -1;
637 static void sig_input(void)
640 /* no active entry yet - wait until we have it */
645 GArray *buffer = g_array_new(FALSE, FALSE, sizeof(unichar));
648 term_gets(buffer, &line_count);
649 key = g_array_index(buffer, unichar, 0);
650 if (key == 11 || key == 3)
651 paste_flush(key == 11);
652 g_array_free(buffer, TRUE);
654 term_gets(paste_buffer, &paste_line_count);
655 if (paste_detect_time > 0 && paste_buffer->len >= 3) {
656 if (paste_timeout_id != -1)
657 g_source_remove(paste_timeout_id);
658 paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL);
662 for (i = 0; i < paste_buffer->len; i++) {
663 unichar key = g_array_index(paste_buffer, unichar, i);
664 signal_emit("gui key pressed", 1, GINT_TO_POINTER(key));
666 g_array_set_size(paste_buffer, 0);
667 paste_line_count = 0;
672 time_t get_idle_time(void)
674 return last_keypress.tv_sec;
677 static void key_scroll_backward(void)
682 static void key_scroll_forward(void)
687 static void key_scroll_start(void)
689 signal_emit("command scrollback home", 3, NULL, active_win->active_server, active_win->active);
692 static void key_scroll_end(void)
694 signal_emit("command scrollback end", 3, NULL, active_win->active_server, active_win->active);
697 static void key_change_window(const char *data)
699 signal_emit("command window goto", 3, data, active_win->active_server, active_win->active);
702 static void key_completion(int erase, int backward)
707 text = gui_entry_get_text_and_pos(active_entry, &pos);
708 line = word_complete(active_win, text, &pos, erase, backward);
712 gui_entry_set_text(active_entry, line);
713 gui_entry_set_pos(active_entry, pos);
718 static void key_word_completion_backward(void)
720 key_completion(FALSE, TRUE);
723 static void key_word_completion(void)
725 key_completion(FALSE, FALSE);
728 static void key_erase_completion(void)
730 key_completion(TRUE, FALSE);
733 static void key_check_replaces(void)
738 text = gui_entry_get_text_and_pos(active_entry, &pos);
739 line = auto_word_complete(text, &pos);
743 gui_entry_set_text(active_entry, line);
744 gui_entry_set_pos(active_entry, pos);
749 static void key_previous_window(void)
751 signal_emit("command window previous", 3, "", active_win->active_server, active_win->active);
754 static void key_next_window(void)
756 signal_emit("command window next", 3, "", active_win->active_server, active_win->active);
759 static void key_left_window(void)
761 signal_emit("command window left", 3, "", active_win->active_server, active_win->active);
764 static void key_right_window(void)
766 signal_emit("command window right", 3, "", active_win->active_server, active_win->active);
769 static void key_upper_window(void)
771 signal_emit("command window up", 3, "", active_win->active_server, active_win->active);
774 static void key_lower_window(void)
776 signal_emit("command window down", 3, "", active_win->active_server, active_win->active);
779 static void key_active_window(void)
781 signal_emit("command window goto", 3, "active", active_win->active_server, active_win->active);
784 static SERVER_REC *get_prev_server(SERVER_REC *current)
788 if (current == NULL) {
789 return servers != NULL ? g_slist_last(servers)->data :
790 lookup_servers != NULL ?
791 g_slist_last(lookup_servers)->data : NULL;
794 /* connect2 -> connect1 -> server2 -> server1 -> connect2 -> .. */
796 pos = g_slist_index(servers, current);
799 return g_slist_nth(servers, pos-1)->data;
800 if (lookup_servers != NULL)
801 return g_slist_last(lookup_servers)->data;
802 return g_slist_last(servers)->data;
805 pos = g_slist_index(lookup_servers, current);
809 return g_slist_nth(lookup_servers, pos-1)->data;
811 return g_slist_last(servers)->data;
812 return g_slist_last(lookup_servers)->data;
815 static SERVER_REC *get_next_server(SERVER_REC *current)
819 if (current == NULL) {
820 return servers != NULL ? servers->data :
821 lookup_servers != NULL ? lookup_servers->data : NULL;
824 /* server1 -> server2 -> connect1 -> connect2 -> server1 -> .. */
826 pos = g_slist_find(servers, current);
828 if (pos->next != NULL)
829 return pos->next->data;
830 if (lookup_servers != NULL)
831 return lookup_servers->data;
832 return servers->data;
835 pos = g_slist_find(lookup_servers, current);
836 g_assert(pos != NULL);
838 if (pos->next != NULL)
839 return pos->next->data;
841 return servers->data;
842 return lookup_servers->data;
845 static void key_previous_window_item(void)
849 if (active_win->items != NULL) {
850 signal_emit("command window item prev", 3, "",
851 active_win->active_server, active_win->active);
852 } else if (servers != NULL || lookup_servers != NULL) {
854 server = active_win->active_server;
856 server = active_win->connect_server;
857 server = get_prev_server(server);
858 signal_emit("command window server", 3, server->tag,
859 active_win->active_server, active_win->active);
863 static void key_next_window_item(void)
867 if (active_win->items != NULL) {
868 signal_emit("command window item next", 3, "",
869 active_win->active_server, active_win->active);
870 } else if (servers != NULL || lookup_servers != NULL) {
872 server = active_win->active_server;
874 server = active_win->connect_server;
875 server = get_next_server(server);
876 signal_emit("command window server", 3, server->tag,
877 active_win->active_server, active_win->active);
881 static void key_escape(void)
883 escape_next_key = TRUE;
886 static void key_insert_text(const char *data)
890 str = parse_special_string(data, active_win->active_server,
891 active_win->active, "", NULL, 0);
892 gui_entry_insert_text(active_entry, str);
896 static void key_sig_stop(void)
901 static void sig_window_auto_changed(void)
905 if (active_entry == NULL)
908 text = gui_entry_get_text(active_entry);
909 command_history_next(active_win, text);
910 gui_entry_set_text(active_entry, "");
914 static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
915 void *flags, void *data)
917 redir = g_new0(ENTRY_REDIRECT_REC, 1);
919 redir->flags = GPOINTER_TO_INT(flags);
922 if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN)
923 gui_entry_set_hidden(active_entry, TRUE);
924 gui_entry_set_prompt(active_entry, entry);
927 static void setup_changed(void)
929 paste_detect_time = settings_get_time("paste_detect_time");
931 paste_verify_line_count = settings_get_int("paste_verify_line_count");
932 paste_join_multiline = settings_get_bool("paste_join_multiline");
935 void gui_readline_init(void)
937 static char changekeys[] = "1234567890qwertyuio";
938 char *key, data[MAX_INT_STRLEN];
941 escape_next_key = FALSE;
945 paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar));
946 paste_old_prompt = NULL;
947 paste_timeout_id = -1;
948 g_get_current_time(&last_keypress);
949 input_listen_init(STDIN_FILENO);
951 settings_add_str("history", "scroll_page_count", "/2");
952 settings_add_time("misc", "paste_detect_time", "5msecs");
953 /* NOTE: function keys can generate at least 5 characters long
954 keycodes. this must be larger to allow them to work. */
955 settings_add_int("misc", "paste_verify_line_count", 5);
956 settings_add_bool("misc", "paste_join_multiline", TRUE);
959 keyboard = keyboard_create(NULL);
960 key_configure_freeze();
962 key_bind("key", NULL, " ", "space", (SIGNAL_FUNC) key_combo);
963 key_bind("key", NULL, "^M", "return", (SIGNAL_FUNC) key_combo);
964 key_bind("key", NULL, "^J", "return", (SIGNAL_FUNC) key_combo);
965 key_bind("key", NULL, "^H", "backspace", (SIGNAL_FUNC) key_combo);
966 key_bind("key", NULL, "^?", "backspace", (SIGNAL_FUNC) key_combo);
967 key_bind("key", NULL, "^I", "tab", (SIGNAL_FUNC) key_combo);
970 key_bind("key", NULL, "^[", "meta", (SIGNAL_FUNC) key_combo);
971 key_bind("key", NULL, "meta-[", "meta2", (SIGNAL_FUNC) key_combo);
972 key_bind("key", NULL, "meta-O", "meta2", (SIGNAL_FUNC) key_combo);
973 key_bind("key", NULL, "meta-[O", "meta2", (SIGNAL_FUNC) key_combo);
976 key_bind("key", NULL, "meta2-A", "up", (SIGNAL_FUNC) key_combo);
977 key_bind("key", NULL, "meta2-B", "down", (SIGNAL_FUNC) key_combo);
978 key_bind("key", NULL, "meta2-C", "right", (SIGNAL_FUNC) key_combo);
979 key_bind("key", NULL, "meta2-D", "left", (SIGNAL_FUNC) key_combo);
981 key_bind("key", NULL, "meta2-1~", "home", (SIGNAL_FUNC) key_combo);
982 key_bind("key", NULL, "meta2-7~", "home", (SIGNAL_FUNC) key_combo);
983 key_bind("key", NULL, "meta2-H", "home", (SIGNAL_FUNC) key_combo);
985 key_bind("key", NULL, "meta2-4~", "end", (SIGNAL_FUNC) key_combo);
986 key_bind("key", NULL, "meta2-8~", "end", (SIGNAL_FUNC) key_combo);
987 key_bind("key", NULL, "meta2-F", "end", (SIGNAL_FUNC) key_combo);
989 key_bind("key", NULL, "meta2-5~", "prior", (SIGNAL_FUNC) key_combo);
990 key_bind("key", NULL, "meta2-I", "prior", (SIGNAL_FUNC) key_combo);
991 key_bind("key", NULL, "meta2-6~", "next", (SIGNAL_FUNC) key_combo);
992 key_bind("key", NULL, "meta2-G", "next", (SIGNAL_FUNC) key_combo);
994 key_bind("key", NULL, "meta2-2~", "insert", (SIGNAL_FUNC) key_combo);
995 key_bind("key", NULL, "meta2-3~", "delete", (SIGNAL_FUNC) key_combo);
997 key_bind("key", NULL, "meta2-d", "cleft", (SIGNAL_FUNC) key_combo);
998 key_bind("key", NULL, "meta2-c", "cright", (SIGNAL_FUNC) key_combo);
999 key_bind("key", NULL, "meta2-5D", "cleft", (SIGNAL_FUNC) key_combo);
1000 key_bind("key", NULL, "meta2-5C", "cright", (SIGNAL_FUNC) key_combo);
1001 key_bind("key", NULL, "meta2-1;5D", "cleft", (SIGNAL_FUNC) key_combo);
1002 key_bind("key", NULL, "meta2-1;5C", "cright", (SIGNAL_FUNC) key_combo);
1004 key_bind("key", NULL, "meta2-1;3A", "mup", (SIGNAL_FUNC) key_combo);
1005 key_bind("key", NULL, "meta2-1;3B", "mdown", (SIGNAL_FUNC) key_combo);
1006 key_bind("key", NULL, "meta2-1;3D", "mleft", (SIGNAL_FUNC) key_combo);
1007 key_bind("key", NULL, "meta2-1;3C", "mright", (SIGNAL_FUNC) key_combo);
1008 key_bind("key", NULL, "meta-up", "mup", (SIGNAL_FUNC) key_combo);
1009 key_bind("key", NULL, "meta-down", "mdown", (SIGNAL_FUNC) key_combo);
1010 key_bind("key", NULL, "meta-left", "mleft", (SIGNAL_FUNC) key_combo);
1011 key_bind("key", NULL, "meta-right", "mright", (SIGNAL_FUNC) key_combo);
1013 key_bind("key", NULL, "meta2-1;5~", "chome", (SIGNAL_FUNC) key_combo);
1014 key_bind("key", NULL, "meta2-7;5~", "chome", (SIGNAL_FUNC) key_combo);
1015 key_bind("key", NULL, "meta2-5H", "chome", (SIGNAL_FUNC) key_combo);
1016 key_bind("key", NULL, "meta2-1;5H", "chome", (SIGNAL_FUNC) key_combo);
1018 key_bind("key", NULL, "meta2-4;5~", "cend", (SIGNAL_FUNC) key_combo);
1019 key_bind("key", NULL, "meta2-8;5~", "cend", (SIGNAL_FUNC) key_combo);
1020 key_bind("key", NULL, "meta2-5F", "cend", (SIGNAL_FUNC) key_combo);
1021 key_bind("key", NULL, "meta2-1;5F", "cend", (SIGNAL_FUNC) key_combo);
1023 /* cursor movement */
1024 key_bind("backward_character", "Move the cursor a character backward", "left", NULL, (SIGNAL_FUNC) key_backward_character);
1025 key_bind("forward_character", "Move the cursor a character forward", "right", NULL, (SIGNAL_FUNC) key_forward_character);
1026 key_bind("backward_word", "Move the cursor a word backward", "cleft", NULL, (SIGNAL_FUNC) key_backward_word);
1027 key_bind("backward_word", NULL, "meta-b", NULL, (SIGNAL_FUNC) key_backward_word);
1028 key_bind("forward_word", "Move the cursor a word forward", "cright", NULL, (SIGNAL_FUNC) key_forward_word);
1029 key_bind("forward_word", NULL, "meta-f", NULL, (SIGNAL_FUNC) key_forward_word);
1030 key_bind("backward_to_space", "Move the cursor backward to a space", NULL, NULL, (SIGNAL_FUNC) key_backward_to_space);
1031 key_bind("forward_to_space", "Move the cursor forward to a space", NULL, NULL, (SIGNAL_FUNC) key_forward_to_space);
1032 key_bind("beginning_of_line", "Move the cursor to the beginning of the line", "home", NULL, (SIGNAL_FUNC) key_beginning_of_line);
1033 key_bind("beginning_of_line", NULL, "^A", NULL, (SIGNAL_FUNC) key_beginning_of_line);
1034 key_bind("end_of_line", "Move the cursor to the end of the line", "end", NULL, (SIGNAL_FUNC) key_end_of_line);
1035 key_bind("end_of_line", NULL, "^E", NULL, (SIGNAL_FUNC) key_end_of_line);
1038 key_bind("backward_history", "Go back one line in the history", "up", NULL, (SIGNAL_FUNC) key_backward_history);
1039 key_bind("forward_history", "Go forward one line in the history", "down", NULL, (SIGNAL_FUNC) key_forward_history);
1042 key_bind("backspace", "Delete the previous character", "backspace", NULL, (SIGNAL_FUNC) key_backspace);
1043 key_bind("delete_character", "Delete the current character", "delete", NULL, (SIGNAL_FUNC) key_delete_character);
1044 key_bind("delete_character", NULL, "^D", NULL, (SIGNAL_FUNC) key_delete_character);
1045 key_bind("delete_next_word", "Delete the word after the cursor", "meta-d", NULL, (SIGNAL_FUNC) key_delete_next_word);
1046 key_bind("delete_previous_word", "Delete the word before the cursor", "meta-backspace", NULL, (SIGNAL_FUNC) key_delete_previous_word);
1047 key_bind("delete_to_previous_space", "Delete up to the previous space", "^W", NULL, (SIGNAL_FUNC) key_delete_to_previous_space);
1048 key_bind("delete_to_next_space", "Delete up to the next space", "", NULL, (SIGNAL_FUNC) key_delete_to_next_space);
1049 key_bind("erase_line", "Erase the whole input line", "^U", NULL, (SIGNAL_FUNC) key_erase_line);
1050 key_bind("erase_to_beg_of_line", "Erase everything before the cursor", NULL, NULL, (SIGNAL_FUNC) key_erase_to_beg_of_line);
1051 key_bind("erase_to_end_of_line", "Erase everything after the cursor", "^K", NULL, (SIGNAL_FUNC) key_erase_to_end_of_line);
1052 key_bind("yank_from_cutbuffer", "\"Undelete\", paste the last deleted text", "^Y", NULL, (SIGNAL_FUNC) key_yank_from_cutbuffer);
1053 key_bind("transpose_characters", "Swap current and previous character", "^T", NULL, (SIGNAL_FUNC) key_transpose_characters);
1054 key_bind("transpose_words", "Swap current and previous word", NULL, NULL, (SIGNAL_FUNC) key_transpose_words);
1055 key_bind("capitalize_word", "Capitalize the current word", NULL, NULL, (SIGNAL_FUNC) key_capitalize_word);
1056 key_bind("downcase_word", "Downcase the current word", NULL, NULL, (SIGNAL_FUNC) key_downcase_word);
1057 key_bind("upcase_word", "Upcase the current word", NULL, NULL, (SIGNAL_FUNC) key_upcase_word);
1059 /* line transmitting */
1060 key_bind("send_line", "Execute the input line", "return", NULL, (SIGNAL_FUNC) key_send_line);
1061 key_bind("word_completion_backward", "", NULL, NULL, (SIGNAL_FUNC) key_word_completion_backward);
1062 key_bind("word_completion", "Complete the current word", "tab", NULL, (SIGNAL_FUNC) key_word_completion);
1063 key_bind("erase_completion", "Remove the completion added by word_completion", "meta-k", NULL, (SIGNAL_FUNC) key_erase_completion);
1064 key_bind("check_replaces", "Check word replaces", NULL, NULL, (SIGNAL_FUNC) key_check_replaces);
1066 /* window managing */
1067 key_bind("previous_window", "Go to the previous window", "^P", NULL, (SIGNAL_FUNC) key_previous_window);
1068 key_bind("next_window", "Go to the next window", "^N", NULL, (SIGNAL_FUNC) key_next_window);
1069 key_bind("upper_window", "Go to the split window above", "mup", NULL, (SIGNAL_FUNC) key_upper_window);
1070 key_bind("lower_window", "Go to the split window below", "mdown", NULL, (SIGNAL_FUNC) key_lower_window);
1071 key_bind("left_window", "Go to the previous window in the current split window", "mleft", NULL, (SIGNAL_FUNC) key_left_window);
1072 key_bind("right_window", "Go to the next window in the current split window", "mright", NULL, (SIGNAL_FUNC) key_right_window);
1073 key_bind("active_window", "Go to next window with the highest activity", "meta-a", NULL, (SIGNAL_FUNC) key_active_window);
1074 key_bind("next_window_item", "Go to the next channel/query. In empty windows change to the next server", "^X", NULL, (SIGNAL_FUNC) key_next_window_item);
1075 key_bind("previous_window_item", "Go to the previous channel/query. In empty windows change to the previous server", NULL, NULL, (SIGNAL_FUNC) key_previous_window_item);
1077 key_bind("refresh_screen", "Redraw screen", "^L", NULL, (SIGNAL_FUNC) irssi_redraw);
1078 key_bind("scroll_backward", "Scroll to previous page", "prior", NULL, (SIGNAL_FUNC) key_scroll_backward);
1079 key_bind("scroll_backward", NULL, "meta-p", NULL, (SIGNAL_FUNC) key_scroll_backward);
1080 key_bind("scroll_forward", "Scroll to next page", "next", NULL, (SIGNAL_FUNC) key_scroll_forward);
1081 key_bind("scroll_forward", NULL, "meta-n", NULL, (SIGNAL_FUNC) key_scroll_forward);
1082 key_bind("scroll_start", "Scroll to the beginning of the window", "chome", NULL, (SIGNAL_FUNC) key_scroll_start);
1083 key_bind("scroll_end", "Scroll to the end of the window", "cend", NULL, (SIGNAL_FUNC) key_scroll_end);
1085 /* inserting special input characters to line.. */
1086 key_bind("escape_char", "Insert the next character exactly as-is to input line", NULL, NULL, (SIGNAL_FUNC) key_escape);
1087 key_bind("insert_text", "Append text to line", NULL, NULL, (SIGNAL_FUNC) key_insert_text);
1090 key_bind("multi", NULL, "return", "check_replaces;send_line", NULL);
1091 key_bind("multi", NULL, "space", "check_replaces;insert_text ", NULL);
1093 /* moving between windows */
1094 for (n = 0; changekeys[n] != '\0'; n++) {
1095 key = g_strdup_printf("meta-%c", changekeys[n]);
1097 key_bind("change_window", "Change window", key, data, (SIGNAL_FUNC) key_change_window);
1102 key_bind("stop_irc", "Send SIGSTOP to client", "^Z", NULL, (SIGNAL_FUNC) key_sig_stop);
1104 key_configure_thaw();
1106 signal_add("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
1107 signal_add("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
1108 signal_add("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
1109 signal_add("setup changed", (SIGNAL_FUNC) setup_changed);
1112 void gui_readline_deinit(void)
1114 input_listen_deinit();
1116 key_configure_freeze();
1118 key_unbind("backward_character", (SIGNAL_FUNC) key_backward_character);
1119 key_unbind("forward_character", (SIGNAL_FUNC) key_forward_character);
1120 key_unbind("backward_word", (SIGNAL_FUNC) key_backward_word);
1121 key_unbind("forward_word", (SIGNAL_FUNC) key_forward_word);
1122 key_unbind("backward_to_space", (SIGNAL_FUNC) key_backward_to_space);
1123 key_unbind("forward_to_space", (SIGNAL_FUNC) key_forward_to_space);
1124 key_unbind("beginning_of_line", (SIGNAL_FUNC) key_beginning_of_line);
1125 key_unbind("end_of_line", (SIGNAL_FUNC) key_end_of_line);
1127 key_unbind("backward_history", (SIGNAL_FUNC) key_backward_history);
1128 key_unbind("forward_history", (SIGNAL_FUNC) key_forward_history);
1130 key_unbind("backspace", (SIGNAL_FUNC) key_backspace);
1131 key_unbind("delete_character", (SIGNAL_FUNC) key_delete_character);
1132 key_unbind("delete_next_word", (SIGNAL_FUNC) key_delete_next_word);
1133 key_unbind("delete_previous_word", (SIGNAL_FUNC) key_delete_previous_word);
1134 key_unbind("delete_to_next_space", (SIGNAL_FUNC) key_delete_to_next_space);
1135 key_unbind("delete_to_previous_space", (SIGNAL_FUNC) key_delete_to_previous_space);
1136 key_unbind("erase_line", (SIGNAL_FUNC) key_erase_line);
1137 key_unbind("erase_to_beg_of_line", (SIGNAL_FUNC) key_erase_to_beg_of_line);
1138 key_unbind("erase_to_end_of_line", (SIGNAL_FUNC) key_erase_to_end_of_line);
1139 key_unbind("yank_from_cutbuffer", (SIGNAL_FUNC) key_yank_from_cutbuffer);
1140 key_unbind("transpose_characters", (SIGNAL_FUNC) key_transpose_characters);
1141 key_unbind("transpose_words", (SIGNAL_FUNC) key_transpose_words);
1143 key_unbind("capitalize_word", (SIGNAL_FUNC) key_capitalize_word);
1144 key_unbind("downcase_word", (SIGNAL_FUNC) key_downcase_word);
1145 key_unbind("upcase_word", (SIGNAL_FUNC) key_upcase_word);
1147 key_unbind("send_line", (SIGNAL_FUNC) key_send_line);
1148 key_unbind("word_completion_backward", (SIGNAL_FUNC) key_word_completion_backward);
1149 key_unbind("word_completion", (SIGNAL_FUNC) key_word_completion);
1150 key_unbind("erase_completion", (SIGNAL_FUNC) key_erase_completion);
1151 key_unbind("check_replaces", (SIGNAL_FUNC) key_check_replaces);
1153 key_unbind("previous_window", (SIGNAL_FUNC) key_previous_window);
1154 key_unbind("next_window", (SIGNAL_FUNC) key_next_window);
1155 key_unbind("upper_window", (SIGNAL_FUNC) key_upper_window);
1156 key_unbind("lower_window", (SIGNAL_FUNC) key_lower_window);
1157 key_unbind("left_window", (SIGNAL_FUNC) key_left_window);
1158 key_unbind("right_window", (SIGNAL_FUNC) key_right_window);
1159 key_unbind("active_window", (SIGNAL_FUNC) key_active_window);
1160 key_unbind("next_window_item", (SIGNAL_FUNC) key_next_window_item);
1161 key_unbind("previous_window_item", (SIGNAL_FUNC) key_previous_window_item);
1163 key_unbind("refresh_screen", (SIGNAL_FUNC) irssi_redraw);
1164 key_unbind("scroll_backward", (SIGNAL_FUNC) key_scroll_backward);
1165 key_unbind("scroll_forward", (SIGNAL_FUNC) key_scroll_forward);
1166 key_unbind("scroll_start", (SIGNAL_FUNC) key_scroll_start);
1167 key_unbind("scroll_end", (SIGNAL_FUNC) key_scroll_end);
1169 key_unbind("escape_char", (SIGNAL_FUNC) key_escape);
1170 key_unbind("insert_text", (SIGNAL_FUNC) key_insert_text);
1171 key_unbind("change_window", (SIGNAL_FUNC) key_change_window);
1172 key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop);
1173 keyboard_destroy(keyboard);
1174 g_array_free(paste_buffer, TRUE);
1176 key_configure_thaw();
1178 signal_remove("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
1179 signal_remove("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
1180 signal_remove("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
1181 signal_remove("setup changed", (SIGNAL_FUNC) setup_changed);