summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--doc/en/autogen/user/weechat_commands.txt2
-rw-r--r--doc/en/autogen/user/weechat_options.txt5
-rw-r--r--doc/en/weechat_user.en.txt8
-rw-r--r--doc/fr/autogen/user/weechat_commands.txt2
-rw-r--r--doc/fr/autogen/user/weechat_options.txt5
-rw-r--r--doc/fr/weechat_user.fr.txt8
-rw-r--r--doc/it/autogen/user/weechat_commands.txt2
-rw-r--r--doc/it/autogen/user/weechat_options.txt5
-rw-r--r--doc/it/weechat_user.it.txt8
-rw-r--r--po/cs.po6
-rw-r--r--po/de.po8
-rw-r--r--po/es.po6
-rw-r--r--po/fr.po9
-rw-r--r--po/hu.po7
-rw-r--r--po/it.po7
-rw-r--r--po/pl.po6
-rw-r--r--po/ru.po6
-rw-r--r--po/weechat.pot5
-rw-r--r--src/core/wee-command.c8
-rw-r--r--src/core/wee-config.c7
-rw-r--r--src/core/wee-config.h1
-rw-r--r--src/gui/curses/gui-curses-keyboard.c7
-rw-r--r--src/gui/gui-buffer.c204
-rw-r--r--src/gui/gui-buffer.h21
-rw-r--r--src/gui/gui-input.c362
-rw-r--r--src/gui/gui-input.h7
-rw-r--r--src/gui/gui-keyboard.c2
-rw-r--r--src/gui/gui-window.c2
29 files changed, 558 insertions, 172 deletions
diff --git a/ChangeLog b/ChangeLog
index 98dbbbb06..047512305 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
........................................
-&bull; *`/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]`::
+&bull; *`/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
........................................
-&bull; *`/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]`::
+&bull; *`/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
........................................
-&bull; *`/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]`::
+&bull; *`/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`
diff --git a/po/cs.po b/po/cs.po
index f49191f9f..7a30e03b8 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -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"
diff --git a/po/de.po b/po/de.po
index d67bfa013..cd615397f 100644
--- a/po/de.po
+++ b/po/de.po
@@ -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"
diff --git a/po/es.po b/po/es.po
index 784295213..adb64f4f8 100644
--- a/po/es.po
+++ b/po/es.po
@@ -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"
diff --git a/po/fr.po b/po/fr.po
index b1f7e3827..5a55f62e3 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -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\""
diff --git a/po/hu.po b/po/hu.po
index ed3293816..d11f4446d 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -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"
diff --git a/po/it.po b/po/it.po
index 88fb162a2..a8ec7e518 100644
--- a/po/it.po
+++ b/po/it.po
@@ -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\""
diff --git a/po/pl.po b/po/pl.po
index e78823620..040c14594 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -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\""
diff --git a/po/ru.po b/po/ru.po
index b134eac85..52162ae02 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -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;
}