diff options
Diffstat (limited to 'src/command')
-rw-r--r-- | src/command/cmd_ac.c | 218 | ||||
-rw-r--r-- | src/command/cmd_defs.c | 7 | ||||
-rw-r--r-- | src/command/cmd_funcs.c | 45 |
3 files changed, 164 insertions, 106 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index 09383edf..d738b455 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -57,6 +57,8 @@ #include "pgp/gpg.h" #endif +static char* _complete_filepath(const char *const input, char *const startstr); + static char* _sub_autocomplete(ProfWin *window, const char *const input); static char* _notify_autocomplete(ProfWin *window, const char *const input); static char* _theme_autocomplete(ProfWin *window, const char *const input); @@ -187,7 +189,7 @@ static Autocomplete plugins_ac; static Autocomplete plugins_load_ac; static Autocomplete plugins_unload_ac; static Autocomplete plugins_reload_ac; -static Autocomplete sendfile_ac; +static Autocomplete filepath_ac; static Autocomplete blocked_ac; static Autocomplete tray_ac; static Autocomplete presence_ac; @@ -705,11 +707,12 @@ cmd_ac_init(void) autocomplete_add(autoping_ac, "timeout"); plugins_ac = autocomplete_new(); + autocomplete_add(plugins_ac, "install"); autocomplete_add(plugins_ac, "load"); autocomplete_add(plugins_ac, "unload"); autocomplete_add(plugins_ac, "reload"); - sendfile_ac = autocomplete_new(); + filepath_ac = autocomplete_new(); blocked_ac = autocomplete_new(); autocomplete_add(blocked_ac, "add"); @@ -903,7 +906,7 @@ cmd_ac_reset(ProfWin *window) autocomplete_reset(notify_mention_ac); autocomplete_reset(notify_trigger_ac); autocomplete_reset(sub_ac); - autocomplete_reset(sendfile_ac); + autocomplete_reset(filepath_ac); autocomplete_reset(who_room_ac); autocomplete_reset(who_roster_ac); @@ -1111,7 +1114,7 @@ cmd_ac_uninit(void) autocomplete_free(plugins_load_ac); autocomplete_free(plugins_unload_ac); autocomplete_free(plugins_reload_ac); - autocomplete_free(sendfile_ac); + autocomplete_free(filepath_ac); autocomplete_free(blocked_ac); autocomplete_free(tray_ac); autocomplete_free(presence_ac); @@ -1890,6 +1893,10 @@ _plugins_autocomplete(ProfWin *window, const char *const input) { char *result = NULL; + if (strncmp(input, "/plugins install ", 17) == 0) { + return _complete_filepath(input, "/plugins install"); + } + if (strncmp(input, "/plugins load ", 14) == 0) { if (plugins_load_ac == NULL) { plugins_load_ac = autocomplete_new(); @@ -2719,107 +2726,9 @@ _close_autocomplete(ProfWin *window, const char *const input) static char* _sendfile_autocomplete(ProfWin *window, const char *const input) { - static char* last_directory = NULL; - - unsigned int output_off = 0; - - char *result = NULL; - char *tmp; - - // strip command - char *inpcp = (char*)input + 9; - while (*inpcp == ' ') { - inpcp++; - } - - inpcp = strdup(inpcp); - - // strip quotes - if (*inpcp == '"') { - tmp = strchr(inpcp+1, '"'); - if (tmp) { - *tmp = '\0'; - } - tmp = strdup(inpcp+1); - free(inpcp); - inpcp = tmp; - } - - // expand ~ to $HOME - if (inpcp[0] == '~' && inpcp[1] == '/') { - if (asprintf(&tmp, "%s/%sfoo", getenv("HOME"), inpcp+2) == -1) { - return NULL; - } - output_off = strlen(getenv("HOME"))+1; - } else { - if (asprintf(&tmp, "%sfoo", inpcp) == -1) { - return NULL; - } - } - free(inpcp); - inpcp = tmp; - - char* inpcp2 = strdup(inpcp); - char* foofile = strdup(basename(inpcp2)); - char* directory = strdup(dirname(inpcp)); - free(inpcp); - free(inpcp2); - - if (!last_directory || strcmp(last_directory, directory) != 0) { - free(last_directory); - last_directory = directory; - autocomplete_reset(sendfile_ac); - - struct dirent *dir; - - DIR *d = opendir(directory); - if (d) { - while ((dir = readdir(d)) != NULL) { - if (strcmp(dir->d_name, ".") == 0) { - continue; - } else if (strcmp(dir->d_name, "..") == 0) { - continue; - } else if (*(dir->d_name) == '.' && *foofile != '.') { - // only show hidden files on explicit request - continue; - } - char * acstring; - if (output_off) { - if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) { - return NULL; - } - if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) { - return NULL; - } - free(tmp); - } else if (strcmp(directory, "/") == 0) { - if (asprintf(&acstring, "/%s", dir->d_name) == -1) { - return NULL; - } - } else { - if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) { - return NULL; - } - } - autocomplete_add(sendfile_ac, acstring); - free(acstring); - } - closedir(d); - } - } else { - free(foofile); - free(directory); - } - - result = autocomplete_param_with_ac(input, "/sendfile", sendfile_ac, TRUE); - if (result) { - return result; - } - - return NULL; + return _complete_filepath(input, "/sendfile"); } - static char* _subject_autocomplete(ProfWin *window, const char *const input) { @@ -3019,3 +2928,106 @@ _presence_autocomplete(ProfWin *window, const char *const input) return NULL; } + +static char* +_complete_filepath(const char *const input, char *const startstr) +{ + static char* last_directory = NULL; + + unsigned int output_off = 0; + + char *result = NULL; + char *tmp; + + // strip command + char *inpcp = (char*)input + strlen(startstr); + while (*inpcp == ' ') { + inpcp++; + } + + inpcp = strdup(inpcp); + + // strip quotes + if (*inpcp == '"') { + tmp = strchr(inpcp+1, '"'); + if (tmp) { + *tmp = '\0'; + } + tmp = strdup(inpcp+1); + free(inpcp); + inpcp = tmp; + } + + // expand ~ to $HOME + if (inpcp[0] == '~' && inpcp[1] == '/') { + if (asprintf(&tmp, "%s/%sfoo", getenv("HOME"), inpcp+2) == -1) { + return NULL; + } + output_off = strlen(getenv("HOME"))+1; + } else { + if (asprintf(&tmp, "%sfoo", inpcp) == -1) { + return NULL; + } + } + free(inpcp); + inpcp = tmp; + + char* inpcp2 = strdup(inpcp); + char* foofile = strdup(basename(inpcp2)); + char* directory = strdup(dirname(inpcp)); + free(inpcp); + free(inpcp2); + + if (!last_directory || strcmp(last_directory, directory) != 0) { + free(last_directory); + last_directory = directory; + autocomplete_reset(filepath_ac); + + struct dirent *dir; + + DIR *d = opendir(directory); + if (d) { + while ((dir = readdir(d)) != NULL) { + if (strcmp(dir->d_name, ".") == 0) { + continue; + } else if (strcmp(dir->d_name, "..") == 0) { + continue; + } else if (*(dir->d_name) == '.' && *foofile != '.') { + // only show hidden files on explicit request + continue; + } + char * acstring; + if (output_off) { + if (asprintf(&tmp, "%s/%s", directory, dir->d_name) == -1) { + return NULL; + } + if (asprintf(&acstring, "~/%s", tmp+output_off) == -1) { + return NULL; + } + free(tmp); + } else if (strcmp(directory, "/") == 0) { + if (asprintf(&acstring, "/%s", dir->d_name) == -1) { + return NULL; + } + } else { + if (asprintf(&acstring, "%s/%s", directory, dir->d_name) == -1) { + return NULL; + } + } + autocomplete_add(filepath_ac, acstring); + free(acstring); + } + closedir(d); + } + } else { + free(foofile); + free(directory); + } + + result = autocomplete_param_with_ac(input, startstr, filepath_ac, TRUE); + if (result) { + return result; + } + + return NULL; +} diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 1a94605a..a9fc3089 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1979,16 +1979,19 @@ static struct cmd_t command_defs[] = CMD_NOTAGS CMD_SYN( "/plugins", + "/plugins install <path>", "/plugins unload <plugin>", "/plugins load <plugin>", "/plugins reload [<plugin>]") CMD_DESC( "Manage plugins. Passing no arguments lists currently loaded plugins.") CMD_ARGS( - { "load <plugin>", "Load a plugin." }, - { "unload <plugin>", "Unload a plugin." }, + { "install <file>", "Install file to plugins directory, and load or reload the plugin." }, + { "load <plugin>", "Load a plugin that already exists in the plugin directory." }, + { "unload <plugin>", "Unload a loaded plugin." }, { "reload [<plugin>]", "Reload a plugin, passing no argument will reload all plugins" }) CMD_EXAMPLES( + "/plugin install /home/steveharris/Downloads/metal.py", "/plugin load browser.py", "/plugin unload say.py", "/plugin reload wikipedia.py") diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index fcce7028..05de90a5 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -6025,7 +6025,50 @@ cmd_xa(ProfWin *window, const char *const command, gchar **args) gboolean cmd_plugins(ProfWin *window, const char *const command, gchar **args) { - if (g_strcmp0(args[0], "load") == 0) { + if (g_strcmp0(args[0], "install") == 0) { + char *filename = args[1]; + if (filename == NULL) { + cons_bad_cmd_usage(command); + return TRUE; + } + + // expand ~ to $HOME + if (filename[0] == '~' && filename[1] == '/') { + if (asprintf(&filename, "%s/%s", getenv("HOME"), filename+2) == -1) { + return TRUE; + } + } else { + filename = strdup(filename); + } + + if (access(filename, R_OK) != 0) { + cons_show("File not found: %s", filename); + free(filename); + return TRUE; + } + + if (!is_regular_file(filename)) { + cons_show("Not a file: %s", filename); + free(filename); + return TRUE; + } + + if (!g_str_has_suffix(filename, ".py") && !g_str_has_suffix(filename, ".so")) { + cons_show("Plugins must have one of the following extensions: '.py' '.so'"); + free(filename); + return TRUE; + } + + char *plugin_name = basename(filename); + gboolean result = plugins_install(plugin_name, filename); + if (result) { + cons_show("Plugin installed, use '/plugin load %s' to enable the plugin.", plugin_name); + } else { + cons_show("Failed to install plugin: %s", plugin_name); + } + + return TRUE; + } else if (g_strcmp0(args[0], "load") == 0) { if (args[1] == NULL) { cons_bad_cmd_usage(command); return TRUE; |