diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/en/autogen/user/weechat_commands.txt | 2 | ||||
-rw-r--r-- | doc/en/autogen/user/weechat_options.txt | 5 | ||||
-rw-r--r-- | doc/en/weechat_user.en.txt | 8 | ||||
-rw-r--r-- | doc/fr/autogen/user/weechat_commands.txt | 2 | ||||
-rw-r--r-- | doc/fr/autogen/user/weechat_options.txt | 5 | ||||
-rw-r--r-- | doc/fr/weechat_user.fr.txt | 8 | ||||
-rw-r--r-- | doc/it/autogen/user/weechat_commands.txt | 2 | ||||
-rw-r--r-- | doc/it/autogen/user/weechat_options.txt | 5 | ||||
-rw-r--r-- | doc/it/weechat_user.it.txt | 8 | ||||
-rw-r--r-- | po/cs.po | 6 | ||||
-rw-r--r-- | po/de.po | 8 | ||||
-rw-r--r-- | po/es.po | 6 | ||||
-rw-r--r-- | po/fr.po | 9 | ||||
-rw-r--r-- | po/hu.po | 7 | ||||
-rw-r--r-- | po/it.po | 7 | ||||
-rw-r--r-- | po/pl.po | 6 | ||||
-rw-r--r-- | po/ru.po | 6 | ||||
-rw-r--r-- | po/weechat.pot | 5 | ||||
-rw-r--r-- | src/core/wee-command.c | 8 | ||||
-rw-r--r-- | src/core/wee-config.c | 7 | ||||
-rw-r--r-- | src/core/wee-config.h | 1 | ||||
-rw-r--r-- | src/gui/curses/gui-curses-keyboard.c | 7 | ||||
-rw-r--r-- | src/gui/gui-buffer.c | 204 | ||||
-rw-r--r-- | src/gui/gui-buffer.h | 21 | ||||
-rw-r--r-- | src/gui/gui-input.c | 362 | ||||
-rw-r--r-- | src/gui/gui-input.h | 7 | ||||
-rw-r--r-- | src/gui/gui-keyboard.c | 2 | ||||
-rw-r--r-- | src/gui/gui-window.c | 2 |
29 files changed, 558 insertions, 172 deletions
@@ -1,12 +1,14 @@ WeeChat ChangeLog ================= FlashCode <flashcode@flashtux.org> -v0.3.3-dev, 2010-04-21 +v0.3.3-dev, 2010-04-28 Version 0.3.3 (under dev!) -------------------------- +* core: add keys for undo/redo changes on command line + (default: ctrl/alt + underscore) (task #9483) * irc: add new options irc.network.autoreconnect_delay_growing and irc.network.autoreconnect_delay_max (task #10338) * irc: add new option irc.color.item_buffer_name_ssl (task #10339) diff --git a/doc/en/autogen/user/weechat_commands.txt b/doc/en/autogen/user/weechat_commands.txt index 594e75887..8b11f6edf 100644 --- a/doc/en/autogen/user/weechat_commands.txt +++ b/doc/en/autogen/user/weechat_commands.txt @@ -179,7 +179,7 @@ value: number of history entries to show ........................................ -• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: +• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | undo | redo | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: ........................................ functions for command line diff --git a/doc/en/autogen/user/weechat_options.txt b/doc/en/autogen/user/weechat_options.txt index 9ee772b99..c7eb572f7 100644 --- a/doc/en/autogen/user/weechat_options.txt +++ b/doc/en/autogen/user/weechat_options.txt @@ -433,6 +433,11 @@ ** type: integer ** values: group_time_asc, group_time_desc, group_number_asc, group_number_desc, number_asc, number_desc (default value: group_time_asc) +* *weechat.look.input_undo_max* +** description: max number of "undo" for command line, by buffer (0 = undo disabled) +** type: integer +** values: 0 .. 65535 (default value: 32) + * *weechat.look.item_time_format* ** description: time format for "time" bar item ** type: string diff --git a/doc/en/weechat_user.en.txt b/doc/en/weechat_user.en.txt index f1c5d63b4..90939e57b 100644 --- a/doc/en/weechat_user.en.txt +++ b/doc/en/weechat_user.en.txt @@ -529,6 +529,14 @@ Keys for command line Paste clipboard content + `/input clipboard_paste` +| Ctrl + _ | + Undo last action on command line + + `/input undo` + +| Alt + _ | + Redo last action on command line + + `/input redo` + | Tab | Complete command or nick (Tab again: find next completion) + `/input complete_next` diff --git a/doc/fr/autogen/user/weechat_commands.txt b/doc/fr/autogen/user/weechat_commands.txt index fe67b3e94..baf673a80 100644 --- a/doc/fr/autogen/user/weechat_commands.txt +++ b/doc/fr/autogen/user/weechat_commands.txt @@ -179,7 +179,7 @@ valeur: nombre d'entrées dans l'historique à afficher ........................................ -• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: +• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | undo | redo | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: ........................................ fonctions pour la ligne de commande diff --git a/doc/fr/autogen/user/weechat_options.txt b/doc/fr/autogen/user/weechat_options.txt index 9a9a4c8cd..d90694497 100644 --- a/doc/fr/autogen/user/weechat_options.txt +++ b/doc/fr/autogen/user/weechat_options.txt @@ -433,6 +433,11 @@ ** type: entier ** valeurs: group_time_asc, group_time_desc, group_number_asc, group_number_desc, number_asc, number_desc (valeur par défaut: group_time_asc) +* *weechat.look.input_undo_max* +** description: nombre maximum de "undo" pour la ligne de commande, par tampon (0 = undo désactivé) +** type: entier +** valeurs: 0 .. 65535 (valeur par défaut: 32) + * *weechat.look.item_time_format* ** description: format de date/heure pour l'objet de barre "time" ** type: chaîne diff --git a/doc/fr/weechat_user.fr.txt b/doc/fr/weechat_user.fr.txt index bc3b6aa77..2b0fb8ae7 100644 --- a/doc/fr/weechat_user.fr.txt +++ b/doc/fr/weechat_user.fr.txt @@ -541,6 +541,14 @@ Touches pour la ligne de commande Coller le contenu du presse-papiers + `/input clipboard_paste` +| Ctrl + _ | + Défaire la dernière action sur la ligne de commande + + `/input undo` + +| Alt + _ | + Refaire la dernière action sur la ligne de commande + + `/input redo` + | Tab | Compléter la commande ou le pseudo (Tab de nouveau : trouver la complétion suivante) + diff --git a/doc/it/autogen/user/weechat_commands.txt b/doc/it/autogen/user/weechat_commands.txt index 15f9cc9ec..8eabc7076 100644 --- a/doc/it/autogen/user/weechat_commands.txt +++ b/doc/it/autogen/user/weechat_commands.txt @@ -179,7 +179,7 @@ valore: numero delle voci nella cronologia da mostrare ........................................ -• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: +• *`/input`* `return | complete_next | complete_previous | search_next | delete_previous_char | delete_next_char | delete_previous_word | delete_next_word | delete_beginning_of_line | delete_end_of_line | delete_line | clipboard_paste | transpose_chars | undo | redo | move_beginning_of_line | move_end_of_line | move_previous_char | move_next_char | move_previous_word | move_next_word | history_previous | history_next | history_global_previous | history_global_next | jump_smart | jump_last_buffer | jump_previously_visited_buffer | jump_next_visited_buffer | hotlist_clear | grab_key | grab_key_command | scroll_unread | set_unread | set_unread_current_buffer | switch_active_buffer | switch_active_buffer_previous | insert [args]`:: ........................................ funzioni per la riga di comando diff --git a/doc/it/autogen/user/weechat_options.txt b/doc/it/autogen/user/weechat_options.txt index e7a477f8f..d5de0be2b 100644 --- a/doc/it/autogen/user/weechat_options.txt +++ b/doc/it/autogen/user/weechat_options.txt @@ -433,6 +433,11 @@ ** tipo: intero ** valori: group_time_asc, group_time_desc, group_number_asc, group_number_desc, number_asc, number_desc (valore predefinito: group_time_asc) +* *weechat.look.input_undo_max* +** descrizione: max number of "undo" for command line, by buffer (0 = undo disabled) +** tipo: intero +** valori: 0 .. 65535 (valore predefinito: 32) + * *weechat.look.item_time_format* ** descrizione: formato dell'ora per l'elemento della barra "tempo" ** tipo: stringa diff --git a/doc/it/weechat_user.it.txt b/doc/it/weechat_user.it.txt index 0315b7d12..e4553cc5a 100644 --- a/doc/it/weechat_user.it.txt +++ b/doc/it/weechat_user.it.txt @@ -538,6 +538,14 @@ Tasti per la riga di comando Incolla il contenuto degli appunti + `/input clipboard_paste` +| Ctrl + _ | + Undo last action on command line + + `/input undo` + +| Alt + _ | + Redo last action on command line + + `/input redo` + | Tab | Completa comando o nick (Tab di nuovo: trova prossimo completamento) + `/input complete_next` @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:50+0200\n" "Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1740,6 +1740,10 @@ msgstr "" "[skupina_číslo_vzestupně], group_number_desc [skupina_číslo_sestupně], " "number_asc [číslo_vzestupně], number_desc [číslo_sestupně] ) " +#, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "maximální počet řádků v historii bufferu (0 = nekonečně)" + msgid "time format for \"time\" bar item" msgstr "formát času pro \"time\" položu pole" @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:50+0200\n" "Last-Translator: Nils G <weechatter@arcor.de>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1805,6 +1805,12 @@ msgstr "" "Sortierung der Hotlist (group_time_asc (Standardwert), group_time_desc, " "group_number_asc, group_number_desc, number_asc, number_desc)" +#, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "" +"maximale Anzahl an Zeilen im Verlaufsspeicher. Dies gilt pro Buffer (0: " +"keine Zeilenbegrenzung)" + msgid "time format for \"time\" bar item" msgstr "Zeitformatierung für die \"time\" Option in der Infobar" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:50+0200\n" "Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1760,6 +1760,10 @@ msgstr "" "group_time_desc, group_number_asc, group_number_desc, number_asc, " "number_desc)" +#, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "número máximo de líneas para cada buffer (0 = ilimitado)" + # "time" is an item name, so keep it in english msgid "time format for \"time\" bar item" msgstr "formato para el elemento \"time\" de la barra" @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" -"PO-Revision-Date: 2010-04-21 22:17+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" +"PO-Revision-Date: 2010-04-23 22:48+0200\n" "Last-Translator: FlashCode <flashcode@flashtux.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" "MIME-Version: 1.0\n" @@ -1765,6 +1765,11 @@ msgstr "" "group_time_desc, group_number_asc, group_number_desc, number_asc, " "number_desc)" +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "" +"nombre maximum de \"undo\" pour la ligne de commande, par tampon (0 = undo " +"désactivé)" + msgid "time format for \"time\" bar item" msgstr "format de date/heure pour l'objet de barre \"time\"" @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:51+0200\n" "Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1546,6 +1546,11 @@ msgid "" msgstr "" #, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "" +"felhasználói parancsok maximális száma az előzményekben (0 = korlátlan)" + +#, fuzzy msgid "time format for \"time\" bar item" msgstr "időbélyeg a információs pult idejéhez" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Weechat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:51+0200\n" "Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1756,6 +1756,11 @@ msgstr "" "group_time_desc, group_number_asc, group_number_desc, number_asc, " "number_desc)" +#, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "" +"numero massimo di righe nella cronologia per buffer (0 = nessun limite)" + msgid "time format for \"time\" bar item" msgstr "formato dell'ora per l'elemento della barra \"tempo\"" @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:51+0200\n" "Last-Translator: Krzysztof Koroscik <soltys@szluug.org>\n" "Language-Team: Polish\n" @@ -1767,6 +1767,10 @@ msgstr "" "typ sortowania hotlisty (group_time_asc (domyślny), group_time_desc, " "group_number_asc, group_number_desc, number_asc, number_desc)" +#, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "maksymalna ilość lini w histori każdego bufora (0 = bez ograniczeń)" + msgid "time format for \"time\" bar item" msgstr "format czasu dla elementu paska \"time\"" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: WeeChat 0.3.3-dev\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n" -"POT-Creation-Date: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\n" "PO-Revision-Date: 2010-04-18 10:51+0200\n" "Last-Translator: Pavel Shevchuk <stlwrt@gmail.com>\n" "Language-Team: weechat-dev <weechat-dev@nongnu.org>\n" @@ -1555,6 +1555,10 @@ msgstr "" "group_number_asc, group_number_desc, number_asc, number_desc)" #, fuzzy +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "максимальное количество команд в истории (0 = не ограничено)" + +#, fuzzy msgid "time format for \"time\" bar item" msgstr "время в информационной строке" diff --git a/po/weechat.pot b/po/weechat.pot index 0174a4214..b1173d990 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: 2010-04-21 23:20+0200\n" +"POT-Creation-Date: 2010-04-28 15:04+0200\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" @@ -1336,6 +1336,9 @@ msgid "" "group_number_asc, group_number_desc, number_asc, number_desc)" msgstr "" +msgid "max number of \"undo\" for command line, by buffer (0 = undo disabled)" +msgstr "" + msgid "time format for \"time\" bar item" msgstr "" diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 1a6d689b7..935e8ec73 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -1943,6 +1943,10 @@ command_input (void *data, struct t_gui_buffer *buffer, if (argc > 2) gui_input_insert (gui_current_window->buffer, argv_eol[2]); } + else if (string_strcasecmp (argv[1], "undo") == 0) + gui_input_undo (gui_current_window->buffer); + else if (string_strcasecmp (argv[1], "redo") == 0) + gui_input_redo (gui_current_window->buffer); } return WEECHAT_RC_OK; @@ -4592,7 +4596,7 @@ command_init () "delete_previous_word | delete_next_word | " "delete_beginning_of_line | delete_end_of_line | " "delete_line | clipboard_paste | transpose_chars | " - "move_beginning_of_line | move_end_of_line | " + "undo | redo | move_beginning_of_line | move_end_of_line | " "move_previous_char | move_next_char | move_previous_word | " "move_next_word | history_previous | history_next | " "history_global_previous | history_global_next | " @@ -4607,7 +4611,7 @@ command_init () "delete_previous_char|delete_next_char|" "delete_previous_word|delete_next_word|" "delete_beginning_of_line|delete_end_of_line|" - "delete_line|clipboard_paste|transpose_chars|" + "delete_line|clipboard_paste|transpose_chars|undo|redo|" "move_beginning_of_line|move_end_of_line|" "move_previous_char|move_next_char|move_previous_word|" "move_next_word|history_previous|history_next|" diff --git a/src/core/wee-config.c b/src/core/wee-config.c index 784e689ff..3989b6181 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -86,6 +86,7 @@ struct t_config_option *config_look_hotlist_names_level; struct t_config_option *config_look_hotlist_names_merged_buffers; struct t_config_option *config_look_hotlist_short_names; struct t_config_option *config_look_hotlist_sort; +struct t_config_option *config_look_input_undo_max; struct t_config_option *config_look_item_time_format; struct t_config_option *config_look_jump_current_to_previous_buffer; struct t_config_option *config_look_jump_previous_buffer_when_closing; @@ -1329,6 +1330,12 @@ config_weechat_init_options () "group_time_asc|group_time_desc|group_number_asc|" "group_number_desc|number_asc|number_desc", 0, 0, "group_time_asc", NULL, 0, NULL, NULL, &config_change_hotlist, NULL, NULL, NULL); + config_look_input_undo_max = config_file_new_option ( + weechat_config_file, ptr_section, + "input_undo_max", "integer", + N_("max number of \"undo\" for command line, by buffer (0 = undo " + "disabled)"), + NULL, 0, 65535, "32", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL); config_look_item_time_format = config_file_new_option ( weechat_config_file, ptr_section, "item_time_format", "string", diff --git a/src/core/wee-config.h b/src/core/wee-config.h index 70aee5b8d..a53f57b63 100644 --- a/src/core/wee-config.h +++ b/src/core/wee-config.h @@ -99,6 +99,7 @@ extern struct t_config_option *config_look_hotlist_names_level; extern struct t_config_option *config_look_hotlist_names_merged_buffers; extern struct t_config_option *config_look_hotlist_short_names; extern struct t_config_option *config_look_hotlist_sort; +extern struct t_config_option *config_look_input_undo_max; extern struct t_config_option *config_look_item_time_format; extern struct t_config_option *config_look_jump_current_to_previous_buffer; extern struct t_config_option *config_look_jump_previous_buffer_when_closing; diff --git a/src/gui/curses/gui-curses-keyboard.c b/src/gui/curses/gui-curses-keyboard.c index dc8957024..9625b4e47 100644 --- a/src/gui/curses/gui-curses-keyboard.c +++ b/src/gui/curses/gui-curses-keyboard.c @@ -88,6 +88,8 @@ gui_keyboard_default_bindings () BIND(/* ^R */ "ctrl-R", "/input search_text"); BIND(/* basckpace */ "ctrl-H", "/input delete_previous_char"); BIND(/* basckpace */ "ctrl-?", "/input delete_previous_char"); + BIND(/* ^_ */ "ctrl-_", "/input undo"); + BIND(/* m-_ */ "meta-_", "/input redo"); BIND(/* del */ "meta2-3~", "/input delete_next_char"); BIND(/* ^D */ "ctrl-D", "/input delete_next_char"); BIND(/* ^W */ "ctrl-W", "/input delete_previous_word"); @@ -338,11 +340,12 @@ gui_keyboard_flush () if (strcmp (key_str, "^^") == 0) key_str[1] = '\0'; + 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); + gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1); } /* incremental text search in buffer */ @@ -435,7 +438,7 @@ gui_keyboard_read_cb (void *data, int fd) else if (cancel_paste) gui_keyboard_paste_cancel (); else if (text_added_to_buffer) - gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); + gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 0); } else { diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 906f24293..f31e4d748 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -477,6 +477,16 @@ gui_buffer_new (struct t_weechat_plugin *plugin, new_buffer->input_buffer_pos = 0; new_buffer->input_buffer_1st_display = 0; + /* undo for input */ + (new_buffer->input_undo_snap).data = NULL; + (new_buffer->input_undo_snap).pos = 0; + (new_buffer->input_undo_snap).prev_undo = NULL; /* not used */ + (new_buffer->input_undo_snap).next_undo = NULL; /* not used */ + new_buffer->input_undo = NULL; + new_buffer->last_input_undo = NULL; + new_buffer->ptr_input_undo = NULL; + new_buffer->input_undo_count = 0; + /* init completion */ new_completion = malloc (sizeof (*new_completion)); if (new_completion) @@ -1321,9 +1331,9 @@ gui_buffer_set (struct t_gui_buffer *buffer, const char *property, } else if (string_strcasecmp (property, "input") == 0) { - gui_input_delete_line (buffer); - gui_input_insert_string (buffer, value, 0); - gui_input_text_changed_modifier_and_signal (buffer); + gui_buffer_undo_snap (buffer); + gui_input_replace_input (buffer, value); + gui_input_text_changed_modifier_and_signal (buffer, 1); } else if (string_strcasecmp (property, "input_pos") == 0) { @@ -1841,6 +1851,7 @@ gui_buffer_close (struct t_gui_buffer *buffer) free (buffer->short_name); if (buffer->input_buffer) free (buffer->input_buffer); + gui_buffer_undo_free_all (buffer); if (buffer->completion) gui_completion_free (buffer->completion); gui_history_buffer_free (buffer); @@ -2303,6 +2314,178 @@ gui_buffer_unmerge (struct t_gui_buffer *buffer, int number) } /* + * gui_buffer_undo_snap: do a "snapshot" of buffer input (save content and + * position) + */ + +void +gui_buffer_undo_snap (struct t_gui_buffer *buffer) +{ + if ((buffer->input_undo_snap).data) + { + free ((buffer->input_undo_snap).data); + (buffer->input_undo_snap).data = NULL; + } + (buffer->input_undo_snap).pos = 0; + + if (CONFIG_INTEGER(config_look_input_undo_max) > 0) + { + (buffer->input_undo_snap).data = (buffer->input_buffer) ? + strdup (buffer->input_buffer) : NULL; + (buffer->input_undo_snap).pos = buffer->input_buffer_pos; + } +} + +/* + * gui_buffer_undo_snap_free: free "snapshot" of buffer input + */ + +void +gui_buffer_undo_snap_free (struct t_gui_buffer *buffer) +{ + if ((buffer->input_undo_snap).data) + { + free ((buffer->input_undo_snap).data); + (buffer->input_undo_snap).data = NULL; + } + (buffer->input_undo_snap).pos = 0; +} + +/* + * gui_buffer_undo_add: add undo in list, with current input buffer + postion + * if before_undo is not NULL, then undo is added before + * this undo, otherwise it is added to the end of list + */ + +void +gui_buffer_undo_add (struct t_gui_buffer *buffer) +{ + struct t_gui_input_undo *new_undo; + + /* undo disabled by config */ + if (CONFIG_INTEGER(config_look_input_undo_max) == 0) + goto end; + + /* + * if nothing has changed since snapshot of input buffer, then do nothing + * (just discard snapshot) + */ + if ((buffer->input_undo_snap).data + && (strcmp (buffer->input_buffer, (buffer->input_undo_snap).data) == 0)) + { + goto end; + } + + /* max number of undo reached? */ + if ((buffer->input_undo_count > 0) + && (buffer->input_undo_count >= CONFIG_INTEGER(config_look_input_undo_max) + 1)) + { + /* remove older undo in buffer (first in list) */ + gui_buffer_undo_free (buffer, buffer->input_undo); + } + + /* remove all undos after current undo */ + if (buffer->ptr_input_undo) + { + while (buffer->ptr_input_undo->next_undo) + { + gui_buffer_undo_free (buffer, buffer->ptr_input_undo->next_undo); + } + } + + /* if input is the same as current undo, then do not add it */ + if (buffer->ptr_input_undo + && (buffer->ptr_input_undo)->data + && (buffer->input_undo_snap).data + && (strcmp ((buffer->input_undo_snap).data, (buffer->ptr_input_undo)->data) == 0)) + { + goto end; + } + + new_undo = (struct t_gui_input_undo *)malloc (sizeof (*new_undo)); + if (!new_undo) + goto end; + + if ((buffer->input_undo_snap).data) + { + new_undo->data = strdup ((buffer->input_undo_snap).data); + new_undo->pos = (buffer->input_undo_snap).pos; + } + else + { + new_undo->data = (buffer->input_buffer) ? + strdup (buffer->input_buffer) : NULL; + new_undo->pos = buffer->input_buffer_pos; + } + + /* add undo to the list */ + new_undo->prev_undo = buffer->last_input_undo; + new_undo->next_undo = NULL; + if (buffer->input_undo) + (buffer->last_input_undo)->next_undo = new_undo; + else + buffer->input_undo = new_undo; + buffer->last_input_undo = new_undo; + + buffer->ptr_input_undo = new_undo; + buffer->input_undo_count++; + +end: + gui_buffer_undo_snap_free (buffer); +} + +/* + * gui_buffer_undo_free: free undo and remove it from list + */ + +void +gui_buffer_undo_free (struct t_gui_buffer *buffer, + struct t_gui_input_undo *undo) +{ + /* update current undo if needed */ + if (buffer->ptr_input_undo == undo) + { + if ((buffer->ptr_input_undo)->next_undo) + buffer->ptr_input_undo = (buffer->ptr_input_undo)->next_undo; + else + buffer->ptr_input_undo = (buffer->ptr_input_undo)->prev_undo; + } + + /* free data */ + if (undo->data) + free (undo->data); + + /* remove undo from list */ + if (undo->prev_undo) + (undo->prev_undo)->next_undo = undo->next_undo; + if (undo->next_undo) + (undo->next_undo)->prev_undo = undo->prev_undo; + if (buffer->input_undo == undo) + buffer->input_undo = undo->next_undo; + if (buffer->last_input_undo == undo) + buffer->last_input_undo = undo->prev_undo; + + free (undo); + + buffer->input_undo_count--; +} + +/* + * gui_buffer_undo_free_all: free all undos of a buffer + */ + +void +gui_buffer_undo_free_all (struct t_gui_buffer *buffer) +{ + gui_buffer_undo_snap_free (buffer); + + while (buffer->input_undo) + { + gui_buffer_undo_free (buffer, buffer->input_undo); + } +} + +/* * gui_buffer_visited_search: search a visited buffer in list of visited buffers */ @@ -2695,6 +2878,7 @@ gui_buffer_print_log () struct t_gui_buffer_local_var *ptr_local_var; struct t_gui_line *ptr_line; struct t_gui_buffer_visited *ptr_buffer_visited; + struct t_gui_input_undo *ptr_undo; char *tags; int num; @@ -2742,6 +2926,20 @@ gui_buffer_print_log () log_printf (" input_buffer_length. . : %d", ptr_buffer->input_buffer_length); log_printf (" input_buffer_pos . . . : %d", ptr_buffer->input_buffer_pos); log_printf (" input_buffer_1st_disp. : %d", ptr_buffer->input_buffer_1st_display); + log_printf (" input_undo_snap.data . : '%s'", (ptr_buffer->input_undo_snap).data); + log_printf (" input_undo_snap.pos. . : %d", (ptr_buffer->input_undo_snap).pos); + log_printf (" input_undo . . . . . . : 0x%lx", ptr_buffer->input_undo); + log_printf (" last_input_undo. . . . : 0x%lx", ptr_buffer->last_input_undo); + log_printf (" ptr_input_undo . . . . : 0x%lx", ptr_buffer->ptr_input_undo); + log_printf (" input_undo_count . . . : %d", ptr_buffer->input_undo_count); + num = 0; + for (ptr_undo = ptr_buffer->input_undo; ptr_undo; + ptr_undo = ptr_undo->next_undo) + { + log_printf (" undo[%04d] . . . . . : 0x%lx ('%s' / %d)", + num, ptr_undo, ptr_undo->data, ptr_undo->pos); + num++; + } log_printf (" completion . . . . . . : 0x%lx", ptr_buffer->completion); log_printf (" history. . . . . . . . : 0x%lx", ptr_buffer->history); log_printf (" last_history . . . . . : 0x%lx", ptr_buffer->last_history); diff --git a/src/gui/gui-buffer.h b/src/gui/gui-buffer.h index 0d6ef808e..2dacd8bdf 100644 --- a/src/gui/gui-buffer.h +++ b/src/gui/gui-buffer.h @@ -57,6 +57,14 @@ struct t_gui_buffer_local_var struct t_gui_buffer_local_var *next_var; /* link to next variable */ }; +struct t_gui_input_undo +{ + char *data; /* content of input buffer */ + int pos; /* position of cursor in buffer */ + struct t_gui_input_undo *prev_undo;/* link to previous undo */ + struct t_gui_input_undo *next_undo;/* link to next undo */ +}; + struct t_gui_buffer { struct t_weechat_plugin *plugin; /* plugin which created this buffer */ @@ -133,6 +141,13 @@ struct t_gui_buffer int input_buffer_pos; /* position into buffer */ int input_buffer_1st_display; /* first char displayed on screen */ + /* undo/redo for input */ + struct t_gui_input_undo input_undo_snap; /* snapshot of input buffer */ + struct t_gui_input_undo *input_undo; /* undo for input */ + struct t_gui_input_undo *last_input_undo; /* last undo for input */ + struct t_gui_input_undo *ptr_input_undo; /* pointer to current undo */ + int input_undo_count; /* number of undos */ + /* completion */ struct t_gui_completion *completion; /* completion */ @@ -252,6 +267,12 @@ extern void gui_buffer_move_to_number (struct t_gui_buffer *buffer, int number); extern void gui_buffer_merge (struct t_gui_buffer *buffer, struct t_gui_buffer *target_buffer); extern void gui_buffer_unmerge (struct t_gui_buffer *buffer, int number); +extern void gui_buffer_undo_snap (struct t_gui_buffer *buffer); +extern void gui_buffer_undo_snap_free (struct t_gui_buffer *buffer); +extern void gui_buffer_undo_add (struct t_gui_buffer *buffer); +extern void gui_buffer_undo_free (struct t_gui_buffer *buffer, + struct t_gui_input_undo *undo); +extern void gui_buffer_undo_free_all (struct t_gui_buffer *buffer); extern struct t_gui_buffer_visited *gui_buffer_visited_search_by_number (int number); extern void gui_buffer_visited_remove (struct t_gui_buffer_visited *buffer_visited); extern void gui_buffer_visited_remove_by_buffer (struct t_gui_buffer *buffer); diff --git a/src/gui/gui-input.c b/src/gui/gui-input.c index 9552e99dc..2977bbef6 100644 --- a/src/gui/gui-input.c +++ b/src/gui/gui-input.c @@ -112,10 +112,14 @@ gui_input_paste_pending_signal () */ void -gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer) +gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer, + int save_undo) { char str_buffer[128], *new_input; + if (save_undo) + gui_buffer_undo_add (buffer); + /* send modifier, and change input if needed */ snprintf (str_buffer, sizeof (str_buffer), "0x%lx", (long unsigned int)buffer); @@ -266,11 +270,12 @@ gui_input_clipboard_paste (struct t_gui_buffer *buffer) { if (buffer->input && gui_input_clipboard) { + gui_buffer_undo_snap (buffer); gui_input_insert_string (buffer, gui_input_clipboard, -1); gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -304,10 +309,11 @@ gui_input_return (struct t_gui_window *window) window->buffer->input_buffer_pos = 0; window->buffer->input_buffer_1st_display = 0; gui_completion_stop (window->buffer->completion, 1); + gui_buffer_undo_free_all (window->buffer); window->buffer->ptr_history = NULL; history_global_ptr = NULL; gui_input_optimize_size (window->buffer); - gui_input_text_changed_modifier_and_signal (window->buffer); + gui_input_text_changed_modifier_and_signal (window->buffer, 0); input_data (window->buffer, command); free (command); } @@ -382,14 +388,15 @@ gui_input_complete (struct t_gui_buffer *buffer) { 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); } } @@ -402,6 +409,7 @@ gui_input_complete_next (struct t_gui_buffer *buffer) { if (buffer->input && (buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { + gui_buffer_undo_snap (buffer); gui_completion_search (buffer->completion, 1, buffer->input_buffer, @@ -409,7 +417,7 @@ gui_input_complete_next (struct t_gui_buffer *buffer) utf8_real_pos (buffer->input_buffer, buffer->input_buffer_pos)); gui_input_complete (buffer); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -422,6 +430,7 @@ gui_input_complete_previous (struct t_gui_buffer *buffer) { if (buffer->input && (buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) { + gui_buffer_undo_snap (buffer); gui_completion_search (buffer->completion, -1, buffer->input_buffer, @@ -429,7 +438,7 @@ gui_input_complete_previous (struct t_gui_buffer *buffer) utf8_real_pos (buffer->input_buffer, buffer->input_buffer_pos)); gui_input_complete (buffer); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -454,7 +463,6 @@ gui_input_search_text (struct t_gui_window *window) } } - /* * gui_input_delete_previous_char: delete previous char (default key: backspace) */ @@ -465,24 +473,22 @@ gui_input_delete_previous_char (struct t_gui_buffer *buffer) char *pos, *pos_last; int char_size, size_to_move; - if (buffer->input) + if (buffer->input && (buffer->input_buffer_pos > 0)) { - if (buffer->input_buffer_pos > 0) - { - pos = utf8_add_offset (buffer->input_buffer, - buffer->input_buffer_pos); - pos_last = utf8_prev_char (buffer->input_buffer, pos); - char_size = pos - pos_last; - size_to_move = strlen (pos); - gui_input_move (buffer, pos_last, pos, size_to_move); - buffer->input_buffer_size -= char_size; - buffer->input_buffer_length--; - buffer->input_buffer_pos--; - buffer->input_buffer[buffer->input_buffer_size] = '\0'; - gui_input_optimize_size (buffer); - gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); - } + gui_buffer_undo_snap (buffer); + pos = utf8_add_offset (buffer->input_buffer, + buffer->input_buffer_pos); + pos_last = utf8_prev_char (buffer->input_buffer, pos); + char_size = pos - pos_last; + size_to_move = strlen (pos); + gui_input_move (buffer, pos_last, pos, size_to_move); + buffer->input_buffer_size -= char_size; + buffer->input_buffer_length--; + buffer->input_buffer_pos--; + buffer->input_buffer[buffer->input_buffer_size] = '\0'; + gui_input_optimize_size (buffer); + gui_completion_stop (buffer->completion, 1); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -496,23 +502,22 @@ gui_input_delete_next_char (struct t_gui_buffer *buffer) char *pos, *pos_next; int char_size, size_to_move; - if (buffer->input) + if (buffer->input + && (buffer->input_buffer_pos < buffer->input_buffer_length)) { - if (buffer->input_buffer_pos < buffer->input_buffer_length) - { - pos = utf8_add_offset (buffer->input_buffer, - buffer->input_buffer_pos); - pos_next = utf8_next_char (pos); - char_size = pos_next - pos; - size_to_move = strlen (pos_next); - gui_input_move (buffer, pos, pos_next, size_to_move); - buffer->input_buffer_size -= char_size; - buffer->input_buffer_length--; - buffer->input_buffer[buffer->input_buffer_size] = '\0'; - gui_input_optimize_size (buffer); - gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); - } + gui_buffer_undo_snap (buffer); + pos = utf8_add_offset (buffer->input_buffer, + buffer->input_buffer_pos); + pos_next = utf8_next_char (pos); + char_size = pos_next - pos; + size_to_move = strlen (pos_next); + gui_input_move (buffer, pos, pos_next, size_to_move); + buffer->input_buffer_size -= char_size; + buffer->input_buffer_length--; + buffer->input_buffer[buffer->input_buffer_size] = '\0'; + gui_input_optimize_size (buffer); + gui_completion_stop (buffer->completion, 1); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -526,53 +531,51 @@ gui_input_delete_previous_word (struct t_gui_buffer *buffer) int length_deleted, size_deleted; char *start, *string; - if (buffer->input) + if (buffer->input && (buffer->input_buffer_pos > 0)) { - if (buffer->input_buffer_pos > 0) + gui_buffer_undo_snap (buffer); + start = utf8_add_offset (buffer->input_buffer, + buffer->input_buffer_pos - 1); + string = start; + while (string && (string[0] == ' ')) + { + string = utf8_prev_char (buffer->input_buffer, string); + } + if (string) { - start = utf8_add_offset (buffer->input_buffer, - buffer->input_buffer_pos - 1); - string = start; - while (string && (string[0] == ' ')) + while (string && (string[0] != ' ')) { string = utf8_prev_char (buffer->input_buffer, string); } if (string) { - while (string && (string[0] != ' ')) + while (string && (string[0] == ' ')) { string = utf8_prev_char (buffer->input_buffer, string); } - if (string) - { - while (string && (string[0] == ' ')) - { - string = utf8_prev_char (buffer->input_buffer, string); - } - } } - - if (string) - string = utf8_next_char (utf8_next_char (string)); - else - string = 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 (buffer, string, string + size_deleted, - strlen (string + size_deleted)); - - buffer->input_buffer_size -= size_deleted; - buffer->input_buffer_length -= length_deleted; - buffer->input_buffer[buffer->input_buffer_size] = '\0'; - buffer->input_buffer_pos -= length_deleted; - gui_input_optimize_size (buffer); - gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); } + + if (string) + string = utf8_next_char (utf8_next_char (string)); + else + string = 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 (buffer, string, string + size_deleted, + strlen (string + size_deleted)); + + buffer->input_buffer_size -= size_deleted; + buffer->input_buffer_length -= length_deleted; + buffer->input_buffer[buffer->input_buffer_size] = '\0'; + buffer->input_buffer_pos -= length_deleted; + gui_input_optimize_size (buffer); + gui_completion_stop (buffer->completion, 1); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -588,6 +591,7 @@ gui_input_delete_next_word (struct t_gui_buffer *buffer) if (buffer->input) { + gui_buffer_undo_snap (buffer); start = utf8_add_offset (buffer->input_buffer, buffer->input_buffer_pos); string = start; @@ -610,7 +614,7 @@ gui_input_delete_next_word (struct t_gui_buffer *buffer) buffer->input_buffer[buffer->input_buffer_size] = '\0'; gui_input_optimize_size (buffer); gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -626,28 +630,26 @@ gui_input_delete_beginning_of_line (struct t_gui_buffer *buffer) int length_deleted, size_deleted, pos_start; char *start; - if (buffer->input) + if (buffer->input && (buffer->input_buffer_pos > 0)) { - if (buffer->input_buffer_pos > 0) - { - start = utf8_add_offset (buffer->input_buffer, - buffer->input_buffer_pos); - pos_start = start - buffer->input_buffer; - size_deleted = start - buffer->input_buffer; - length_deleted = utf8_strnlen (buffer->input_buffer, size_deleted); - gui_input_clipboard_copy (buffer->input_buffer, - start - buffer->input_buffer); - - gui_input_move (buffer, buffer->input_buffer, start, strlen (start)); - - buffer->input_buffer_size -= size_deleted; - buffer->input_buffer_length -= length_deleted; - buffer->input_buffer[buffer->input_buffer_size] = '\0'; - buffer->input_buffer_pos = 0; - gui_input_optimize_size (buffer); - gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); - } + gui_buffer_undo_snap (buffer); + start = utf8_add_offset (buffer->input_buffer, + buffer->input_buffer_pos); + pos_start = start - buffer->input_buffer; + size_deleted = start - buffer->input_buffer; + length_deleted = utf8_strnlen (buffer->input_buffer, size_deleted); + gui_input_clipboard_copy (buffer->input_buffer, + start - buffer->input_buffer); + + gui_input_move (buffer, buffer->input_buffer, start, strlen (start)); + + buffer->input_buffer_size -= size_deleted; + buffer->input_buffer_length -= length_deleted; + buffer->input_buffer[buffer->input_buffer_size] = '\0'; + buffer->input_buffer_pos = 0; + gui_input_optimize_size (buffer); + gui_completion_stop (buffer->completion, 1); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -664,6 +666,7 @@ gui_input_delete_end_of_line (struct t_gui_buffer *buffer) if (buffer->input) { + gui_buffer_undo_snap (buffer); start = utf8_add_offset (buffer->input_buffer, buffer->input_buffer_pos); pos_start = start - buffer->input_buffer; @@ -675,7 +678,7 @@ gui_input_delete_end_of_line (struct t_gui_buffer *buffer) buffer->input_buffer_length = utf8_strlen (buffer->input_buffer); gui_input_optimize_size (buffer); gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -688,13 +691,14 @@ gui_input_delete_line (struct t_gui_buffer *buffer) { if (buffer->input) { + gui_buffer_undo_snap (buffer); buffer->input_buffer[0] = '\0'; buffer->input_buffer_size = 0; buffer->input_buffer_length = 0; buffer->input_buffer_pos = 0; gui_input_optimize_size (buffer); gui_completion_stop (buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -710,31 +714,31 @@ gui_input_transpose_chars (struct t_gui_buffer *buffer) int size_prev_char, size_start_char; int pos_prev_char, pos_start; - if (buffer->input) + if (buffer->input && (buffer->input_buffer_pos > 0) + && (buffer->input_buffer_length > 1)) { - if ((buffer->input_buffer_pos > 0) && (buffer->input_buffer_length > 1)) - { - if (buffer->input_buffer_pos == buffer->input_buffer_length) - buffer->input_buffer_pos--; - - start = utf8_add_offset (buffer->input_buffer, - buffer->input_buffer_pos); - pos_start = start - buffer->input_buffer; - prev_char = utf8_prev_char (buffer->input_buffer, start); - pos_prev_char = prev_char - 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); - - buffer->input_buffer_pos++; - - gui_completion_stop (buffer->completion, 1); - - gui_input_text_changed_modifier_and_signal (buffer); - } + gui_buffer_undo_snap (buffer); + + if (buffer->input_buffer_pos == buffer->input_buffer_length) + buffer->input_buffer_pos--; + + start = utf8_add_offset (buffer->input_buffer, + buffer->input_buffer_pos); + pos_start = start - buffer->input_buffer; + prev_char = utf8_prev_char (buffer->input_buffer, start); + pos_prev_char = prev_char - 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); + + buffer->input_buffer_pos++; + + gui_completion_stop (buffer->completion, 1); + + gui_input_text_changed_modifier_and_signal (buffer, 1); } } @@ -948,7 +952,8 @@ gui_input_history_previous (struct t_gui_window *window) strcpy (window->buffer->input_buffer, window->buffer->ptr_history->text); } - gui_input_text_changed_modifier_and_signal (window->buffer); + gui_input_text_changed_modifier_and_signal (window->buffer, 0); + gui_buffer_undo_free_all (window->buffer); } else { @@ -1013,7 +1018,8 @@ gui_input_history_next (struct t_gui_window *window) gui_input_optimize_size (window->buffer); } } - gui_input_text_changed_modifier_and_signal (window->buffer); + gui_input_text_changed_modifier_and_signal (window->buffer, 0); + gui_buffer_undo_free_all (window->buffer); } else { @@ -1050,7 +1056,8 @@ gui_input_history_global_previous (struct t_gui_buffer *buffer) buffer->input_buffer_pos = buffer->input_buffer_length; buffer->input_buffer_1st_display = 0; strcpy (buffer->input_buffer, history_global_ptr->text); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 0); + gui_buffer_undo_free_all (buffer); } } } @@ -1063,31 +1070,30 @@ gui_input_history_global_previous (struct t_gui_buffer *buffer) void gui_input_history_global_next (struct t_gui_buffer *buffer) { - if (buffer->input && (buffer->text_search == GUI_TEXT_SEARCH_DISABLED)) + if (buffer->input && (buffer->text_search == GUI_TEXT_SEARCH_DISABLED) + && history_global_ptr) { + history_global_ptr = history_global_ptr->prev_history; if (history_global_ptr) { - history_global_ptr = history_global_ptr->prev_history; - if (history_global_ptr) - { - buffer->input_buffer_size = strlen (history_global_ptr->text); - buffer->input_buffer_length = utf8_strlen (history_global_ptr->text); - } - else - { - buffer->input_buffer[0] = '\0'; - buffer->input_buffer_size = 0; - buffer->input_buffer_length = 0; - } - gui_input_optimize_size (buffer); - buffer->input_buffer_pos = buffer->input_buffer_length; - buffer->input_buffer_1st_display = 0; - if (history_global_ptr) - { - strcpy (buffer->input_buffer, history_global_ptr->text); - } - gui_input_text_changed_modifier_and_signal (buffer); + buffer->input_buffer_size = strlen (history_global_ptr->text); + buffer->input_buffer_length = utf8_strlen (history_global_ptr->text); + } + else + { + buffer->input_buffer[0] = '\0'; + buffer->input_buffer_size = 0; + buffer->input_buffer_length = 0; + } + gui_input_optimize_size (buffer); + buffer->input_buffer_pos = buffer->input_buffer_length; + buffer->input_buffer_1st_display = 0; + if (history_global_ptr) + { + strcpy (buffer->input_buffer, history_global_ptr->text); } + gui_input_text_changed_modifier_and_signal (buffer, 0); + gui_buffer_undo_free_all (buffer); } } @@ -1339,10 +1345,70 @@ gui_input_insert (struct t_gui_buffer *buffer, const char *args) if (args) { + gui_buffer_undo_snap (buffer); args2 = string_convert_hex_chars (args); gui_input_insert_string (buffer, (args2) ? args2 : args, -1); - gui_input_text_changed_modifier_and_signal (buffer); + gui_input_text_changed_modifier_and_signal (buffer, 1); if (args2) free (args2); } } + +/* + * gui_input_undo_use: use a undo: replace input with undo content + */ + +void +gui_input_undo_use (struct t_gui_buffer *buffer, struct t_gui_input_undo *undo) +{ + if ((undo->data) && (strcmp (undo->data, buffer->input_buffer) != 0)) + { + gui_input_replace_input (buffer, undo->data); + gui_input_set_pos (buffer, undo->pos); + gui_input_text_changed_modifier_and_signal (buffer, 0); + } +} + +/* + * gui_input_undo: undo last action on input buffer + */ + +void +gui_input_undo (struct t_gui_buffer *buffer) +{ + if (buffer->ptr_input_undo) + { + /* + * if we are doing undo and that undo pointer is to the end of list + * (for example first time undo is used), then save current input + * content in undo list + */ + if ((buffer->ptr_input_undo == buffer->last_input_undo) + && (buffer->ptr_input_undo)->data + && (strcmp (buffer->input_buffer, (buffer->ptr_input_undo)->data) != 0)) + { + gui_buffer_undo_snap_free (buffer); + gui_buffer_undo_add (buffer); + } + + if (buffer->ptr_input_undo && (buffer->ptr_input_undo)->prev_undo) + { + buffer->ptr_input_undo = (buffer->ptr_input_undo)->prev_undo; + gui_input_undo_use (buffer, buffer->ptr_input_undo); + } + } +} + +/* + * gui_input_redo: redo last action on input buffer + */ + +void +gui_input_redo (struct t_gui_buffer *buffer) +{ + if (buffer->ptr_input_undo && (buffer->ptr_input_undo)->next_undo) + { + buffer->ptr_input_undo = (buffer->ptr_input_undo)->next_undo; + gui_input_undo_use (buffer, buffer->ptr_input_undo); + } +} diff --git a/src/gui/gui-input.h b/src/gui/gui-input.h index a03a6ec44..16dd8b9a0 100644 --- a/src/gui/gui-input.h +++ b/src/gui/gui-input.h @@ -29,8 +29,11 @@ extern char *gui_input_clipboard; /* input functions */ +extern void gui_input_replace_input (struct t_gui_buffer *buffer, + const char *new_input); extern void gui_input_paste_pending_signal (); -extern void gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer); +extern void gui_input_text_changed_modifier_and_signal (struct t_gui_buffer *buffer, + int save_undo); extern void gui_input_move (struct t_gui_buffer *buffer, char *target, const char *source, int size); extern void gui_input_set_pos (struct t_gui_buffer *buffer, int pos); @@ -72,5 +75,7 @@ extern void gui_input_set_unread_buffer (struct t_gui_buffer *buffer); extern void gui_input_switch_active_buffer (struct t_gui_window *window); extern void gui_input_switch_active_buffer_previous (struct t_gui_window *window); extern void gui_input_insert (struct t_gui_buffer *buffer, const char *args); +extern void gui_input_undo (struct t_gui_buffer *buffer); +extern void gui_input_redo (struct t_gui_buffer *buffer); #endif /* gui-input.h */ diff --git a/src/gui/gui-keyboard.c b/src/gui/gui-keyboard.c index 3228afaf3..7f8d45aac 100644 --- a/src/gui/gui-keyboard.c +++ b/src/gui/gui-keyboard.c @@ -136,7 +136,7 @@ gui_keyboard_grab_end () } if (gui_current_window->buffer->completion) gui_completion_stop (gui_current_window->buffer->completion, 1); - gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); + gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1); } free (expanded_key); } diff --git a/src/gui/gui-window.c b/src/gui/gui-window.c index 171971ddd..63a85748e 100644 --- a/src/gui/gui-window.c +++ b/src/gui/gui-window.c @@ -921,7 +921,7 @@ gui_window_search_stop (struct t_gui_window *window) { gui_input_insert_string (window->buffer, window->buffer->text_search_input, -1); - gui_input_text_changed_modifier_and_signal (window->buffer); + gui_input_text_changed_modifier_and_signal (window->buffer, 0); free (window->buffer->text_search_input); window->buffer->text_search_input = NULL; } |