about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_ac.c8
-rw-r--r--src/command/cmd_ac.h1
-rw-r--r--src/plugins/callbacks.c25
-rw-r--r--src/plugins/plugins.c19
-rw-r--r--src/profanity.c4
-rw-r--r--src/window_list.c23
-rw-r--r--src/window_list.h2
7 files changed, 75 insertions, 7 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index da466b76..565ce336 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -787,6 +787,14 @@ cmd_ac_remove(const char *const value)
     }
 }
 
+void
+cmd_ac_remove_help(const char *const value)
+{
+    if (help_ac) {
+        autocomplete_remove(help_ac, value);
+    }
+}
+
 gboolean
 cmd_ac_exists(char *cmd)
 {
diff --git a/src/command/cmd_ac.h b/src/command/cmd_ac.h
index b294fcd5..637ebcf6 100644
--- a/src/command/cmd_ac.h
+++ b/src/command/cmd_ac.h
@@ -48,6 +48,7 @@ void cmd_ac_add_alias(ProfAlias *alias);
 void cmd_ac_add_alias_value(char *value);
 
 void cmd_ac_remove(const char *const value);
+void cmd_ac_remove_help(const char *const value);
 void cmd_ac_remove_alias_value(char *value);
 
 gboolean cmd_ac_exists(char *cmd);
diff --git a/src/plugins/callbacks.c b/src/plugins/callbacks.c
index d313690b..52f0aebd 100644
--- a/src/plugins/callbacks.c
+++ b/src/plugins/callbacks.c
@@ -41,6 +41,7 @@
 #include "plugins/plugins.h"
 #include "tools/autocomplete.h"
 #include "tools/parser.h"
+#include "window_list.h"
 
 #include "ui/ui.h"
 
@@ -141,9 +142,31 @@ callbacks_init(void)
 void
 callbacks_remove(const char *const plugin_name)
 {
-    // TODO remove from cmd_ac and cmd_ac_help
+    GHashTable *command_hash = g_hash_table_lookup(p_commands, plugin_name);
+    if (command_hash) {
+        GList *commands = g_hash_table_get_keys(command_hash);
+        GList *curr = commands;
+        while (curr) {
+            char *command = curr->data;
+            cmd_ac_remove(command);
+            cmd_ac_remove_help(&command[1]);
+            curr = g_list_next(curr);
+        }
+        g_list_free(commands);
+    }
+
     g_hash_table_remove(p_commands, plugin_name);
     g_hash_table_remove(p_timed_functions, plugin_name);
+
+    GHashTable *tag_to_win_cb_hash = g_hash_table_lookup(p_window_callbacks, plugin_name);
+    GList *tags = g_hash_table_get_keys(tag_to_win_cb_hash);
+    GList *curr = tags;
+    while (curr) {
+        wins_close_plugin(curr->data);
+        curr = g_list_next(curr);
+    }
+    g_list_free(tags);
+
     g_hash_table_remove(p_window_callbacks, plugin_name);
 }
 
diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c
index 449bbecf..ea8e7d6a 100644
--- a/src/plugins/plugins.c
+++ b/src/plugins/plugins.c
@@ -171,10 +171,19 @@ plugins_unload(const char *const name)
     ProfPlugin *plugin = g_hash_table_lookup(plugins, name);
     if (plugin) {
         plugin->on_unload_func(plugin);
+#ifdef HAVE_PYTHON
+        if (plugin->lang == LANG_PYTHON) {
+            python_plugin_destroy(plugin);
+        }
+#endif
+#ifdef HAVE_C
+        if (plugin->lang == LANG_C) {
+            c_plugin_destroy(plugin);
+        }
+#endif
+        prefs_remove_plugin(name);
+        g_hash_table_remove(plugins, name);
     }
-
-    prefs_remove_plugin(name);
-
     return TRUE;
 }
 
@@ -240,7 +249,9 @@ void
 plugins_win_process_line(char *win, const char * const line)
 {
     PluginWindowCallback *window = callbacks_get_window_handler(win);
-    window->callback_exec(window, win, line);
+    if (window) {
+        window->callback_exec(window, win, line);
+    }
 }
 
 void
diff --git a/src/profanity.c b/src/profanity.c
index c9e19fa8..37e9dbcf 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -391,7 +391,6 @@ _shutdown(void)
     plugins_on_shutdown();
     muc_close();
     caps_close();
-    ui_close();
 #ifdef HAVE_LIBOTR
     otr_shutdown();
 #endif
@@ -402,10 +401,11 @@ _shutdown(void)
     theme_close();
     accounts_close();
     tlscerts_close();
-    cmd_uninit();
     log_stderr_close();
     log_close();
     plugins_shutdown();
+    cmd_uninit();
+    ui_close();
     prefs_close();
     if (saved_status) {
         free(saved_status);
diff --git a/src/window_list.c b/src/window_list.c
index 01d5d412..4f2d86e0 100644
--- a/src/window_list.c
+++ b/src/window_list.c
@@ -226,6 +226,29 @@ wins_get_plugin(const char *const tag)
     return NULL;
 }
 
+void
+wins_close_plugin(const char *const tag)
+{
+    GList *values = g_hash_table_get_values(windows);
+    GList *curr = values;
+
+    while (curr) {
+        ProfWin *window = curr->data;
+        if (window->type == WIN_PLUGIN) {
+            ProfPluginWin *pluginwin = (ProfPluginWin*)window;
+            if (g_strcmp0(pluginwin->tag, tag) == 0) {
+                int num = wins_get_num(window);
+                wins_close_by_num(num);
+                g_list_free(values);
+                return;
+            }
+        }
+        curr = g_list_next(curr);
+    }
+
+    g_list_free(values);
+}
+
 GList*
 wins_get_private_chats(const char *const roomjid)
 {
diff --git a/src/window_list.h b/src/window_list.h
index 97fe43e1..109620f9 100644
--- a/src/window_list.h
+++ b/src/window_list.h
@@ -61,6 +61,8 @@ ProfPrivateWin* wins_get_private(const char *const fulljid);
 ProfPluginWin* wins_get_plugin(const char *const tag);
 ProfXMLWin* wins_get_xmlconsole(void);
 
+void wins_close_plugin(const char *const tag);
+
 ProfWin* wins_get_current(void);
 
 void wins_set_current_by_num(int i);