From ffa1d11e3c0499442545d2b63ac3c25cbdca911f Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Sun, 12 Jun 2022 15:22:56 +0200 Subject: [PATCH] [Script] Look into ~/.config/rofi/scripts/ for user scripts. --- include/modes/script.h | 10 ++++++ source/modes/script.c | 73 ++++++++++++++++++++++++++++++++++++++++++ source/rofi.c | 6 +++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/include/modes/script.h b/include/modes/script.h index 8616eb28..3436e796 100644 --- a/include/modes/script.h +++ b/include/modes/script.h @@ -54,5 +54,15 @@ Mode *script_mode_parse_setup(const char *str); * @returns true when valid. */ gboolean script_mode_is_valid(const char *token); + +/** + * Gather the users scripts from `~/.config/rofi/scripts/` + */ +void script_mode_gather_user_scripts(void); + +/** + * Cleanup memory allocated by `script_mode_gather_user_scripts` + */ +void script_mode_cleanup(void); /**@}*/ #endif // ROFI_MODE_SCRIPT_H diff --git a/source/modes/script.c b/source/modes/script.c index 994e3b97..643127cc 100644 --- a/source/modes/script.c +++ b/source/modes/script.c @@ -438,7 +438,77 @@ script_get_icon(const Mode *sw, unsigned int selected_line, int height) { } #include "mode-private.h" + +typedef struct ScriptUser { + char *name; + char *path; +} ScriptUser; + +ScriptUser *user_scripts = NULL; +int num_scripts = 0; + +void script_mode_cleanup(void) { + for (size_t i = 0; i < num_scripts; i++) { + g_free(user_scripts[i].name); + g_free(user_scripts[i].path); + } + g_free(user_scripts); +} +void script_mode_gather_user_scripts(void) { + const char *cpath = g_get_user_config_dir(); + char *script_dir = g_build_filename(cpath, "rofi", "scripts", NULL); + if (g_file_test(script_dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) == + FALSE) { + g_free(script_dir); + return; + } + GDir *sd = g_dir_open(script_dir, 0, NULL); + if (sd) { + const char *file = NULL; + while ((file = g_dir_read_name(sd)) != NULL) { + char *sp = g_build_filename(cpath, "rofi", "scripts", file, NULL); + user_scripts = g_realloc(user_scripts, num_scripts + 1); + user_scripts[num_scripts].path = sp; + user_scripts[num_scripts].name = g_strdup(file); + char *dot = strrchr(user_scripts[num_scripts].name, '.'); + if (dot) { + *dot = '\0'; + } + num_scripts++; + } + } + + g_free(script_dir); +} + +static int script_mode_has_user_script(char const *const user) { + + for (int i = 0; i < num_scripts; i++) { + if (g_strcmp0(user_scripts[i].name, user) == 0) { + return i; + } + } + return -1; +} + Mode *script_mode_parse_setup(const char *str) { + int ui = 0; + if ((ui = script_mode_has_user_script(str)) >= 0) { + Mode *sw = g_malloc0(sizeof(*sw)); + sw->name = g_strdup(user_scripts[ui].name); + sw->ed = g_strdup(user_scripts[ui].path); + sw->free = script_switcher_free; + sw->_init = script_mode_init; + sw->_get_num_entries = script_mode_get_num_entries; + sw->_result = script_mode_result; + sw->_destroy = script_mode_destroy; + sw->_token_match = script_token_match; + sw->_get_message = script_get_message; + sw->_get_icon = script_get_icon; + sw->_get_completion = NULL, sw->_preprocess_input = NULL, + sw->_get_display_value = _get_display_value; + return sw; + } Mode *sw = g_malloc0(sizeof(*sw)); char *endp = NULL; char *parse = g_strdup(str); @@ -477,5 +547,8 @@ Mode *script_mode_parse_setup(const char *str) { } gboolean script_mode_is_valid(const char *token) { + if (script_mode_has_user_script(token) >= 0) { + return TRUE; + } return strchr(token, ':') != NULL; } diff --git a/source/rofi.c b/source/rofi.c index db91f9e9..096d85d7 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -162,6 +162,7 @@ static void teardown(int pfd) { // Cleanup view rofi_view_cleanup(); + // Cleanup pid file. remove_pid_file(pfd); } @@ -415,7 +416,8 @@ static void help_print_mode_not_found(const char *mode) { } static void help_print_no_arguments(void) { - GString *emesg = g_string_new("Rofi is unsure what to show.\n\n"); + GString *emesg = g_string_new( + "Rofi is unsure what to show.\n\n"); g_string_append(emesg, "Please specify the mode you want to show.\n\n"); g_string_append( emesg, " rofi -show {mode}\n\n"); @@ -475,6 +477,7 @@ static void cleanup(void) { rofi_theme = NULL; } TIMINGS_STOP(); + script_mode_cleanup(); rofi_collectmodes_destroy(); rofi_icon_fetcher_destroy(); @@ -587,6 +590,7 @@ static void rofi_collect_modes(void) { g_strfreev(paths); } } + script_mode_gather_user_scripts(); } /**