diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | doc/de/autogen/user/weechat_options.txt | 7 | ||||
-rw-r--r-- | doc/en/autogen/user/weechat_options.txt | 7 | ||||
-rw-r--r-- | doc/fr/autogen/user/weechat_options.txt | 7 | ||||
-rw-r--r-- | doc/it/autogen/user/weechat_options.txt | 7 | ||||
-rw-r--r-- | po/cs.po | 7 | ||||
-rw-r--r-- | po/de.po | 7 | ||||
-rw-r--r-- | po/es.po | 7 | ||||
-rw-r--r-- | po/fr.po | 22 | ||||
-rw-r--r-- | po/hu.po | 7 | ||||
-rw-r--r-- | po/it.po | 7 | ||||
-rw-r--r-- | po/ja.po | 7 | ||||
-rw-r--r-- | po/pl.po | 7 | ||||
-rw-r--r-- | po/pt_BR.po | 7 | ||||
-rw-r--r-- | po/ru.po | 7 | ||||
-rw-r--r-- | po/weechat.pot | 7 | ||||
-rw-r--r-- | src/core/wee-command.c | 4 | ||||
-rw-r--r-- | src/core/wee-config.c | 10 | ||||
-rw-r--r-- | src/core/wee-config.h | 1 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-key.c | 351 | ||||
-rw-r--r-- | src/gui/gui-key.c | 172 | ||||
-rw-r--r-- | src/gui/gui-key.h | 13 |
22 files changed, 460 insertions, 218 deletions
@@ -1,14 +1,15 @@ WeeChat ChangeLog ================= Sébastien Helleu <flashcode@flashtux.org> -v0.3.8-dev, 2012-03-06 +v0.3.8-dev, 2012-03-09 Version 0.3.8 (under dev!) -------------------------- -* core: add support of terminal "bracketed paste mode", new option - weechat.look.paste_bracketed (task #11316) +* core: add support of terminal "bracketed paste mode", new options + weechat.look.paste_bracketed and weechat.look.paste_bracketed_timer_delay + (task #11316) * core: fix display of wide chars on last column of chat area (patch #7733) * api: add list "gui_buffer_last_displayed" in hdata "buffer" * irc: fix display of color in hostname (join/part/quit messages) diff --git a/doc/de/autogen/user/weechat_options.txt b/doc/de/autogen/user/weechat_options.txt index d3b0db582..b4e085553 100644 --- a/doc/de/autogen/user/weechat_options.txt +++ b/doc/de/autogen/user/weechat_options.txt @@ -583,10 +583,15 @@ ** Typ: boolesch ** Werte: on, off (Standardwert: `off`) +* [[option_weechat.look.paste_bracketed_timer_delay]] *weechat.look.paste_bracketed_timer_delay* +** Beschreibung: `force end of bracketed paste after this delay (in seconds) if the control sequence for end of bracketed paste ("ESC[201~") was not received in time` +** Typ: integer +** Werte: 1 .. 60 (Standardwert: `10`) + * [[option_weechat.look.paste_max_lines]] *weechat.look.paste_max_lines* ** Beschreibung: `max number of lines for paste without asking user (-1 = disable this feature)` ** Typ: integer -** Werte: -1 .. 2147483647 (Standardwert: `3`) +** Werte: -1 .. 2147483647 (Standardwert: `1`) * [[option_weechat.look.prefix_action]] *weechat.look.prefix_action* ** Beschreibung: `Präfix für Action-Nachrichten` diff --git a/doc/en/autogen/user/weechat_options.txt b/doc/en/autogen/user/weechat_options.txt index e4191aef8..11c2d3b7d 100644 --- a/doc/en/autogen/user/weechat_options.txt +++ b/doc/en/autogen/user/weechat_options.txt @@ -583,10 +583,15 @@ ** type: boolean ** values: on, off (default value: `off`) +* [[option_weechat.look.paste_bracketed_timer_delay]] *weechat.look.paste_bracketed_timer_delay* +** description: `force end of bracketed paste after this delay (in seconds) if the control sequence for end of bracketed paste ("ESC[201~") was not received in time` +** type: integer +** values: 1 .. 60 (default value: `10`) + * [[option_weechat.look.paste_max_lines]] *weechat.look.paste_max_lines* ** description: `max number of lines for paste without asking user (-1 = disable this feature)` ** type: integer -** values: -1 .. 2147483647 (default value: `3`) +** values: -1 .. 2147483647 (default value: `1`) * [[option_weechat.look.prefix_action]] *weechat.look.prefix_action* ** description: `prefix for action messages` diff --git a/doc/fr/autogen/user/weechat_options.txt b/doc/fr/autogen/user/weechat_options.txt index 036fcab3c..97a378665 100644 --- a/doc/fr/autogen/user/weechat_options.txt +++ b/doc/fr/autogen/user/weechat_options.txt @@ -583,10 +583,15 @@ ** type: booléen ** valeurs: on, off (valeur par défaut: `off`) +* [[option_weechat.look.paste_bracketed_timer_delay]] *weechat.look.paste_bracketed_timer_delay* +** description: `forcer la fin du "bracketed paste" après ce délai (en secondes) si la séquence de contrôle pour la fin du "bracketed paste" ("ESC[201~") n'a pas été reçue à temps` +** type: entier +** valeurs: 1 .. 60 (valeur par défaut: `10`) + * [[option_weechat.look.paste_max_lines]] *weechat.look.paste_max_lines* ** description: `nombre maximum de lignes pour la détection de collage sans demander à l'utilisateur (-1 = désactiver cette fonctionnalité)` ** type: entier -** valeurs: -1 .. 2147483647 (valeur par défaut: `3`) +** valeurs: -1 .. 2147483647 (valeur par défaut: `1`) * [[option_weechat.look.prefix_action]] *weechat.look.prefix_action* ** description: `préfixe pour les messages d'action` diff --git a/doc/it/autogen/user/weechat_options.txt b/doc/it/autogen/user/weechat_options.txt index 77a515038..9664bea49 100644 --- a/doc/it/autogen/user/weechat_options.txt +++ b/doc/it/autogen/user/weechat_options.txt @@ -583,10 +583,15 @@ ** tipo: bool ** valori: on, off (valore predefinito: `off`) +* [[option_weechat.look.paste_bracketed_timer_delay]] *weechat.look.paste_bracketed_timer_delay* +** descrizione: `force end of bracketed paste after this delay (in seconds) if the control sequence for end of bracketed paste ("ESC[201~") was not received in time` +** tipo: intero +** valori: 1 .. 60 (valore predefinito: `10`) + * [[option_weechat.look.paste_max_lines]] *weechat.look.paste_max_lines* ** descrizione: `max number of lines for paste without asking user (-1 = disable this feature)` ** tipo: intero -** valori: -1 .. 2147483647 (valore predefinito: `3`) +** valori: -1 .. 2147483647 (valore predefinito: `1`) * [[option_weechat.look.prefix_action]] *weechat.look.prefix_action* ** descrizione: `prefisso per i messaggi di azione` @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2520,6 +2520,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -23,7 +23,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Nils Görs <weechatter@arcor.de>\n" "Language-Team: German <weechatter@arcor.de>\n" @@ -2760,6 +2760,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2660,6 +2660,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -21,8 +21,8 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" -"PO-Revision-Date: 2012-03-04 19:40+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" +"PO-Revision-Date: 2012-03-09 10:33+0100\n" "Last-Translator: Sebastien Helleu <flashcode@flashtux.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" "Language: French\n" @@ -2677,6 +2677,14 @@ msgstr "" "[201~\")" msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" +"forcer la fin du \"bracketed paste\" après ce délai (en secondes) si la " +"séquence de contrôle pour la fin du \"bracketed paste\" (\"ESC[201~\") n'a " +"pas été reçue à temps" + +msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" msgstr "" "nombre maximum de lignes pour la détection de collage sans demander à " @@ -8620,6 +8628,16 @@ msgid "Constants" msgstr "Constantes" #~ msgid "" +#~ "delay (in seconds) to wait for control sequence ending a bracketed paste " +#~ "(\"ESC[201~\"); if the control sequence is not received and that delay is " +#~ "reached, WeeChat will end the bracketed paste" +#~ msgstr "" +#~ "délai (en secondes) à attendre pour la séquence de contrôle qui termine " +#~ "le mode \"bracketed paste\" (\"ESC[201~\"); si la séquence de contrôle " +#~ "n'est pas reçue et que ce délai est atteint, WeeChat terminera le " +#~ "\"bracketed paste\"" + +#~ msgid "" #~ "enable bracketed paste mode (if available, only some terminals support it)" #~ msgstr "" #~ "activer le mode \"bracketed paste\" (si disponible, seulement quelques " @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2160,6 +2160,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2651,6 +2651,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: \"AYANOKOUZI, Ryuunosuke\" <i38w7i3@yahoo.co.jp>\n" "Language-Team: Japanese\n" @@ -2601,6 +2601,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Krzysztof Korościk <soltys@szluug.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2659,6 +2659,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" diff --git a/po/pt_BR.po b/po/pt_BR.po index 00bf61dc7..c8a472bf6 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Sergio Durigan Junior <sergiosdj@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2598,6 +2598,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" @@ -21,7 +21,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.8-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: 2012-02-26 09:16+0100\n" "Last-Translator: Aleksey V Zapparov AKA ixti <ixti@member.fsf.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -2187,6 +2187,11 @@ msgid "" "\", followed by the pasted text, followed by \"ESC[201~\")" msgstr "" +msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + #, fuzzy msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" diff --git a/po/weechat.pot b/po/weechat.pot index 8faa0da62..740bae07b 100644 --- a/po/weechat.pot +++ b/po/weechat.pot @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2012-03-04 19:39+0100\n" +"POT-Creation-Date: 2012-03-09 10:32+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -1909,6 +1909,11 @@ msgid "" msgstr "" msgid "" +"force end of bracketed paste after this delay (in seconds) if the control " +"sequence for end of bracketed paste (\"ESC[201~\") was not received in time" +msgstr "" + +msgid "" "max number of lines for paste without asking user (-1 = disable this feature)" msgstr "" diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 6445918f2..d92a8dfe2 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -2394,7 +2394,9 @@ COMMAND_CALLBACK(input) else if (string_strcasecmp (argv[1], "redo") == 0) gui_input_redo (buffer); else if (string_strcasecmp (argv[1], "paste_start") == 0) - gui_key_paste_bracketed_start (); + { + /* do nothing here */ + } else if (string_strcasecmp (argv[1], "paste_stop") == 0) { /* do nothing here */ diff --git a/src/core/wee-config.c b/src/core/wee-config.c index 20beb3ed0..228cbc934 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -126,6 +126,7 @@ struct t_config_option *config_look_mouse_timer_delay; struct t_config_option *config_look_nickmode; struct t_config_option *config_look_nickmode_empty; struct t_config_option *config_look_paste_bracketed; +struct t_config_option *config_look_paste_bracketed_timer_delay; struct t_config_option *config_look_paste_max_lines; struct t_config_option *config_look_prefix[GUI_CHAT_NUM_PREFIXES]; struct t_config_option *config_look_prefix_align; @@ -1981,12 +1982,19 @@ config_weechat_init_options () "text from typed-in text (\"ESC[200~\", followed by the pasted text, " "followed by \"ESC[201~\")"), NULL, 0, 0, "off", NULL, 0, NULL, NULL, &config_change_paste_bracketed, NULL, NULL, NULL); + config_look_paste_bracketed_timer_delay = config_file_new_option ( + weechat_config_file, ptr_section, + "paste_bracketed_timer_delay", "integer", + N_("force end of bracketed paste after this delay (in seconds) if the " + "control sequence for end of bracketed paste (\"ESC[201~\") was not " + "received in time"), + NULL, 1, 60, "10", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); config_look_paste_max_lines = config_file_new_option ( weechat_config_file, ptr_section, "paste_max_lines", "integer", N_("max number of lines for paste without asking user " "(-1 = disable this feature)"), - NULL, -1, INT_MAX, "3", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); + NULL, -1, INT_MAX, "1", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); config_look_prefix[GUI_CHAT_PREFIX_ERROR] = config_file_new_option ( weechat_config_file, ptr_section, "prefix_error", "string", diff --git a/src/core/wee-config.h b/src/core/wee-config.h index 02ad65338..95c1c2428 100644 --- a/src/core/wee-config.h +++ b/src/core/wee-config.h @@ -150,6 +150,7 @@ extern struct t_config_option *config_look_mouse_timer_delay; extern struct t_config_option *config_look_nickmode; extern struct t_config_option *config_look_nickmode_empty; extern struct t_config_option *config_look_paste_bracketed; +extern struct t_config_option *config_look_paste_bracketed_timer_delay; extern struct t_config_option *config_look_paste_max_lines; extern struct t_config_option *config_look_prefix[]; extern struct t_config_option *config_look_prefix_align; 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; } 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 */ diff --git a/src/gui/gui-key.h b/src/gui/gui-key.h index c418e8499..373d033e5 100644 --- a/src/gui/gui-key.h +++ b/src/gui/gui-key.h @@ -26,6 +26,10 @@ struct t_hashtable; #define GUI_KEY_GRAB_DELAY_DEFAULT 500 +#define GUI_KEY_BRACKETED_PASTE_START "\x1B[200~" +#define GUI_KEY_BRACKETED_PASTE_END "\x1B[201~" +#define GUI_KEY_BRACKETED_PASTE_LENGTH 6 + enum t_gui_key_context { GUI_KEY_CONTEXT_DEFAULT = 0, @@ -110,10 +114,17 @@ extern void gui_key_free_all (struct t_gui_key **keys, int *keys_count); extern void gui_key_buffer_reset (); extern void gui_key_buffer_add (unsigned char key); +extern int gui_key_buffer_search (int start_index, int max_index, + const char *string); +extern void gui_key_buffer_remove (int index, int number); +extern void gui_key_paste_remove_newline (); extern void gui_key_paste_start (); -extern void gui_key_paste_bracketed_start (); extern int gui_key_get_paste_lines (); extern int gui_key_paste_check (int bracketed_paste); +extern void gui_key_paste_bracketed_timer_remove (); +extern void gui_key_paste_bracketed_timer_add (); +extern void gui_key_paste_bracketed_start (); +extern void gui_key_paste_bracketed_stop (); extern void gui_key_paste_accept (); extern void gui_key_paste_cancel (); extern void gui_key_end (); |