about summary refs log tree commit diff stats
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/chatwin.c4
-rw-r--r--src/ui/inputwin.c27
-rw-r--r--src/ui/mucwin.c3
-rw-r--r--src/ui/privwin.c3
-rw-r--r--src/ui/win_types.h1
-rw-r--r--src/ui/window.c28
-rw-r--r--src/ui/window.h2
-rw-r--r--src/ui/window_list.c22
-rw-r--r--src/ui/window_list.h2
9 files changed, 91 insertions, 1 deletions
diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c
index 0224d720..d02e4162 100644
--- a/src/ui/chatwin.c
+++ b/src/ui/chatwin.c
@@ -323,6 +323,7 @@ chatwin_incoming_msg(ProfChatWin* chatwin, ProfMessage* message, gboolean win_cr
     }
 
     wins_add_urls_ac(window, message);
+    wins_add_quotes_ac(window, message->plain);
 
     if (prefs_get_boolean(PREF_BEEP)) {
         beep();
@@ -346,6 +347,9 @@ chatwin_outgoing_msg(ProfChatWin* chatwin, const char* const message, char* id,
 {
     assert(chatwin != NULL);
 
+    ProfWin* window = (ProfWin*)chatwin;
+    wins_add_quotes_ac(window, message);
+
     char* enc_char;
     if (chatwin->outgoing_char) {
         enc_char = chatwin->outgoing_char;
diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c
index 9e34c0b6..d19d8719 100644
--- a/src/ui/inputwin.c
+++ b/src/ui/inputwin.c
@@ -558,6 +558,10 @@ _inp_rl_getc(FILE* stream)
     if (_inp_edited(ch)) {
         ProfWin* window = wins_get_current();
         cmd_ac_reset(window);
+
+        if ((window->type == WIN_CHAT || window->type == WIN_MUC || window->type == WIN_PRIVATE) && window->quotes_ac != NULL) {
+            autocomplete_reset(window->quotes_ac);
+        }
     }
     return ch;
 }
@@ -597,6 +601,17 @@ _inp_rl_tab_handler(int count, int key)
         }
     }
 
+    if (strncmp(rl_line_buffer, ">", 1) == 0) {
+        ProfWin* window = wins_get_current();
+        char* result = win_quote_autocomplete(window, rl_line_buffer, FALSE);
+        if (result) {
+            rl_replace_line(result, 1);
+            rl_point = rl_end;
+            free(result);
+            return 0;
+        }
+    }
+
     ProfWin* current = wins_get_current();
     if (current->type == WIN_MUC) {
         char* result = muc_autocomplete(current, rl_line_buffer, FALSE);
@@ -607,7 +622,6 @@ _inp_rl_tab_handler(int count, int key)
         }
     }
 
-
     return 0;
 }
 
@@ -629,6 +643,17 @@ _inp_rl_shift_tab_handler(int count, int key)
         }
     }
 
+    if (strncmp(rl_line_buffer, ">", 1) == 0) {
+        ProfWin* window = wins_get_current();
+        char* result = win_quote_autocomplete(window, rl_line_buffer, TRUE);
+        if (result) {
+            rl_replace_line(result, 1);
+            rl_point = rl_end;
+            free(result);
+            return 0;
+        }
+    }
+
     ProfWin* current = wins_get_current();
     if (current->type == WIN_MUC) {
         char* result = muc_autocomplete(current, rl_line_buffer, TRUE);
diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c
index 5bf21722..c5aed583 100644
--- a/src/ui/mucwin.c
+++ b/src/ui/mucwin.c
@@ -541,6 +541,8 @@ mucwin_outgoing_msg(ProfMucWin* mucwin, const char* const message, const char* c
     if (id) {
         _mucwin_set_last_message(mucwin, id, message);
     }
+
+    wins_add_quotes_ac(window, message);
 }
 
 void
@@ -576,6 +578,7 @@ mucwin_incoming_msg(ProfMucWin* mucwin, const ProfMessage* const message, GSList
 
     win_insert_last_read_position_marker((ProfWin*)mucwin, mucwin->roomjid);
     wins_add_urls_ac(window, message);
+    wins_add_quotes_ac(window, message->plain);
 
     if (g_slist_length(mentions) > 0) {
         _mucwin_print_mention(window, message->plain, message->from_jid->resourcepart, mynick, mentions, ch, flags);
diff --git a/src/ui/privwin.c b/src/ui/privwin.c
index 73ef61a0..20611ea4 100644
--- a/src/ui/privwin.c
+++ b/src/ui/privwin.c
@@ -82,6 +82,7 @@ privwin_incoming_msg(ProfPrivateWin* privatewin, ProfMessage* message)
     }
 
     wins_add_urls_ac(window, message);
+    wins_add_quotes_ac(window, message->plain);
 
     if (prefs_get_boolean(PREF_BEEP)) {
         beep();
@@ -99,6 +100,8 @@ privwin_outgoing_msg(ProfPrivateWin* privwin, const char* const message)
 {
     assert(privwin != NULL);
 
+    ProfWin* window = (ProfWin*)privwin;
+    wins_add_quotes_ac(window, message);
     win_print_outgoing((ProfWin*)privwin, "-", NULL, NULL, message);
 }
 
diff --git a/src/ui/win_types.h b/src/ui/win_types.h
index f2237a79..70d226b0 100644
--- a/src/ui/win_types.h
+++ b/src/ui/win_types.h
@@ -148,6 +148,7 @@ typedef struct prof_win_t
     win_type_t type;
     ProfLayout* layout;
     Autocomplete urls_ac;
+    Autocomplete quotes_ac;
 } ProfWin;
 
 typedef struct prof_console_win_t
diff --git a/src/ui/window.c b/src/ui/window.c
index 54932f21..7952497c 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -2020,3 +2020,31 @@ win_insert_last_read_position_marker(ProfWin* window, char* id)
 
     g_date_time_unref(time);
 }
+
+char*
+win_quote_autocomplete(ProfWin* window, const char* const input, gboolean previous)
+{
+    if (window->type != WIN_CHAT && window->type != WIN_MUC && window->type != WIN_PRIVATE) {
+        return NULL;
+    }
+
+    char* result = autocomplete_complete(window->quotes_ac, input + 1, FALSE, previous);
+    if (result == NULL) {
+        return NULL;
+    }
+
+    gchar **parts = g_strsplit(result, "\n", -1);
+    gchar *quoted_result = g_strjoinv("\n> ", parts);
+
+    GString* replace_with = g_string_new("> ");
+    g_string_append(replace_with, quoted_result);
+    g_string_append(replace_with, "\n");
+
+    g_free(result);
+    g_free(quoted_result);
+    g_strfreev(parts);
+
+    result = replace_with->str;
+    g_string_free(replace_with, FALSE);
+    return result;
+}
diff --git a/src/ui/window.h b/src/ui/window.h
index 22a1db51..c7c2853e 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -93,4 +93,6 @@ void win_sub_page_up(ProfWin* window);
 void win_insert_last_read_position_marker(ProfWin* window, char* id);
 void win_remove_entry_message(ProfWin* window, const char* const id);
 
+char* win_quote_autocomplete(ProfWin* window, const char* const input, gboolean previous);
+
 #endif
diff --git a/src/ui/window_list.c b/src/ui/window_list.c
index 01379804..a6ebb5fe 100644
--- a/src/ui/window_list.c
+++ b/src/ui/window_list.c
@@ -554,6 +554,7 @@ wins_close_by_num(int i)
                     }
                 }
                 autocomplete_free(window->urls_ac);
+                autocomplete_free(window->quotes_ac);
                 break;
             }
             case WIN_MUC:
@@ -566,6 +567,7 @@ wins_close_by_num(int i)
                     g_date_time_unref(mucwin->last_msg_timestamp);
                 }
                 autocomplete_free(window->urls_ac);
+                autocomplete_free(window->quotes_ac);
                 break;
             }
             case WIN_PRIVATE:
@@ -574,6 +576,7 @@ wins_close_by_num(int i)
                 autocomplete_remove(wins_ac, privwin->fulljid);
                 autocomplete_remove(wins_close_ac, privwin->fulljid);
                 autocomplete_free(window->urls_ac);
+                autocomplete_free(window->quotes_ac);
                 break;
             }
             case WIN_XML:
@@ -646,6 +649,7 @@ wins_new_chat(const char* const barejid)
         }
     }
     newwin->urls_ac = autocomplete_new();
+    newwin->quotes_ac = autocomplete_new();
 
     return newwin;
 }
@@ -661,6 +665,7 @@ wins_new_muc(const char* const roomjid)
     autocomplete_add(wins_ac, roomjid);
     autocomplete_add(wins_close_ac, roomjid);
     newwin->urls_ac = autocomplete_new();
+    newwin->quotes_ac = autocomplete_new();
 
     return newwin;
 }
@@ -688,6 +693,7 @@ wins_new_private(const char* const fulljid)
     autocomplete_add(wins_ac, fulljid);
     autocomplete_add(wins_close_ac, fulljid);
     newwin->urls_ac = autocomplete_new();
+    newwin->quotes_ac = autocomplete_new();
 
     return newwin;
 }
@@ -1299,6 +1305,14 @@ wins_add_urls_ac(const ProfWin* const win, const ProfMessage* const message)
     g_regex_unref(regex);
 }
 
+void
+wins_add_quotes_ac(const ProfWin* const win, const char* const message)
+{
+    autocomplete_add_reverse(win->quotes_ac, message);
+    // for people who run profanity a long time, we don't want to waste a lot of memory
+    autocomplete_remove_older_than_max_reverse(win->quotes_ac, 20);
+}
+
 char*
 wins_get_url(const char* const search_str, gboolean previous, void* context)
 {
@@ -1306,3 +1320,11 @@ wins_get_url(const char* const search_str, gboolean previous, void* context)
 
     return autocomplete_complete(win->urls_ac, search_str, FALSE, previous);
 }
+
+char*
+wins_get_quote(const char* const search_str, gboolean previous, void* context)
+{
+    ProfWin* win = (ProfWin*)context;
+
+    return autocomplete_complete(win->quotes_ac, search_str, FALSE, previous);
+}
diff --git a/src/ui/window_list.h b/src/ui/window_list.h
index 06ae6d7e..bcb18d14 100644
--- a/src/ui/window_list.h
+++ b/src/ui/window_list.h
@@ -102,5 +102,7 @@ void win_close_reset_search_attempts(void);
 
 void wins_add_urls_ac(const ProfWin* const win, const ProfMessage* const message);
 char* wins_get_url(const char* const search_str, gboolean previous, void* context);
+void wins_add_quotes_ac(const ProfWin* const win, const char* const message);
+char* wins_get_quote(const char* const search_str, gboolean previous, void* context);
 
 #endif