diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 1dfc5cc0..a4cd788e 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -185,6 +185,7 @@ static Autocomplete console_msg_ac; static Autocomplete autoping_ac; static Autocomplete plugins_ac; static Autocomplete plugins_load_ac; +static Autocomplete plugins_unload_ac; static Autocomplete sendfile_ac; static Autocomplete blocked_ac; static Autocomplete tray_ac; @@ -484,6 +485,7 @@ cmd_ac_init(void) theme_load_ac = NULL; plugins_load_ac = NULL; + plugins_unload_ac = NULL; who_roster_ac = autocomplete_new(); autocomplete_add(who_roster_ac, "chat"); @@ -702,6 +704,7 @@ cmd_ac_init(void) plugins_ac = autocomplete_new(); autocomplete_add(plugins_ac, "load"); + autocomplete_add(plugins_ac, "unload"); sendfile_ac = autocomplete_new(); @@ -909,6 +912,10 @@ cmd_ac_reset(ProfWin *window) autocomplete_free(plugins_load_ac); plugins_load_ac = NULL; } + if (plugins_unload_ac) { + autocomplete_free(plugins_unload_ac); + plugins_unload_ac = NULL; + } autocomplete_reset(account_ac); autocomplete_reset(account_set_ac); autocomplete_reset(account_clear_ac); @@ -1087,6 +1094,7 @@ cmd_ac_uninit(void) autocomplete_free(autoping_ac); autocomplete_free(plugins_ac); autocomplete_free(plugins_load_ac); + autocomplete_free(plugins_unload_ac); autocomplete_free(sendfile_ac); autocomplete_free(blocked_ac); autocomplete_free(tray_ac); @@ -1865,6 +1873,7 @@ static char* _plugins_autocomplete(ProfWin *window, const char *const input) { char *result = NULL; + if (strncmp(input, "/plugins load ", 14) == 0) { if (plugins_load_ac == NULL) { plugins_load_ac = autocomplete_new(); @@ -1881,6 +1890,24 @@ _plugins_autocomplete(ProfWin *window, const char *const input) return result; } } + + if (strncmp(input, "/plugins unload ", 16) == 0) { + if (plugins_unload_ac == NULL) { + plugins_unload_ac = autocomplete_new(); + GSList *plugins = plugins_loaded_list(); + GSList *curr = plugins; + while (curr) { + autocomplete_add(plugins_unload_ac, curr->data); + curr = g_slist_next(curr); + } + g_slist_free(plugins); + } + result = autocomplete_param_with_ac(input, "/plugins unload", plugins_unload_ac, TRUE); + if (result) { + return result; + } + } + result = autocomplete_param_with_ac(input, "/plugins", plugins_ac, TRUE); if (result) { return result; diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index dacf1c91..02f5ee93 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1979,13 +1979,16 @@ static struct cmd_t command_defs[] = CMD_NOTAGS CMD_SYN( "/plugins", + "/plugins unload ", "/plugins load ") CMD_DESC( "Manage plugins. Passing no arguments lists currently loaded plugins.") CMD_ARGS( - { "load ", "Load a plugin." }) + { "load ", "Load a plugin." }, + { "unload ", "Unload a plugin." }) CMD_EXAMPLES( - "/plugin load browser.py") + "/plugin load browser.py", + "/plugin unload say.py") }, { "/prefs", diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 7f3419e3..b935f13d 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -6038,6 +6038,20 @@ cmd_plugins(ProfWin *window, const char *const command, gchar **args) cons_show("Failed to load plugin: %s", args[1]); } + return TRUE; + } else if (g_strcmp0(args[0], "unload") == 0) { + if (args[1] == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + gboolean res = plugins_unload(args[1]); + if (res) { + prefs_remove_plugin(args[1]); + cons_show("Unloaded plugin: %s", args[1]); + } else { + cons_show("Failed to unload plugin: %s", args[1]); + } + return TRUE; } else { GSList *plugins = plugins_get_list(); diff --git a/src/config/preferences.c b/src/config/preferences.c index 9381d014..636bd33d 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -631,6 +631,13 @@ prefs_add_plugin(const char *const name) _save_prefs(); } +void +prefs_remove_plugin(const char *const name) +{ + conf_string_list_remove(prefs, "plugins", "load", name); + _save_prefs(); +} + void prefs_free_plugins(gchar **plugins) { diff --git a/src/config/preferences.h b/src/config/preferences.h index a7b84dfe..3111f81e 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -191,6 +191,7 @@ void prefs_set_autoxa_time(gint value); gchar** prefs_get_plugins(void); void prefs_free_plugins(gchar **plugins); void prefs_add_plugin(const char *const name); +void prefs_remove_plugin(const char *const name); char prefs_get_otr_char(void); void prefs_set_otr_char(char ch); diff --git a/src/plugins/plugins.c b/src/plugins/plugins.c index 5757a174..707ca497 100644 --- a/src/plugins/plugins.c +++ b/src/plugins/plugins.c @@ -172,6 +172,12 @@ plugins_load(const char *const name) } } +gboolean +plugins_unload(const char *const name) +{ + return FALSE; +} + GSList * plugins_get_list(void) { @@ -218,6 +224,20 @@ plugins_unloaded_list(void) return result; } +GSList* +plugins_loaded_list(void) +{ + GSList *result = NULL; + GSList *curr = plugins; + while (curr) { + ProfPlugin *plugin = curr->data; + result = g_slist_append(result, plugin->name); + curr = g_slist_next(curr); + } + + return result; +} + char * plugins_autocomplete(const char * const input) { diff --git a/src/plugins/plugins.h b/src/plugins/plugins.h index b03248ab..a5b10a3e 100644 --- a/src/plugins/plugins.h +++ b/src/plugins/plugins.h @@ -100,11 +100,13 @@ typedef struct prof_plugin_t { void plugins_init(void); GSList* plugins_get_list(void); GSList *plugins_unloaded_list(void); +GSList *plugins_loaded_list(void); char* plugins_autocomplete(const char *const input); void plugins_reset_autocomplete(void); void plugins_shutdown(void); gboolean plugins_load(const char *const name); +gboolean plugins_unload(const char *const name); void plugins_on_start(void); void plugins_on_shutdown(void);