diff --git a/config/config.c b/config/config.c index 05dd91be..7bde9703 100644 --- a/config/config.c +++ b/config/config.c @@ -158,4 +158,6 @@ Settings config = { .refilter_timeout_limit = 300, /** workaround for broken xserver (#300 on xserver, #611) */ .xserver_i300_workaround = FALSE, + /** What browser to use for completion */ + .completer_mode = "recursivebrowser", }; diff --git a/include/mode.h b/include/mode.h index 3af46281..a60c9954 100644 --- a/include/mode.h +++ b/include/mode.h @@ -247,6 +247,28 @@ char *mode_preprocess_input(Mode *mode, const char *input); * free). */ char *mode_get_message(const Mode *mode); + +/** + * @param mode The mode to create an instance off. + * + * @returns a new instance of the mode. + */ +Mode *mode_create(const Mode *mode); + +/** + * @param mode The mode to query + * @param menu_retv The menu return value. + * @param input Pointer to the user input string. [in][out] + * @param selected_line the line selected by the user. + * @param path get the path to the selected file. [out] + * + * Acts on the user interaction. + * + * @returns the next #ModeMode. + */ +ModeMode mode_completer_result(Mode *sw, int menu_retv, char **input, + unsigned int selected_line, char **path); + /**@}*/ G_END_DECLS #endif diff --git a/include/rofi.h b/include/rofi.h index 7ae59fee..38f4c44a 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -103,6 +103,8 @@ void rofi_quit_main_loop(void); * @return returns Mode * when found, NULL if not. */ Mode *rofi_collect_modes_search(const char *name); + +const Mode *rofi_get_completer(void); /** Reset terminal */ #define color_reset "\033[0m" /** Set terminal text bold */ diff --git a/include/settings.h b/include/settings.h index 7a15112c..1af9b952 100644 --- a/include/settings.h +++ b/include/settings.h @@ -184,6 +184,8 @@ typedef struct { /** workaround for broken xserver (#300 on xserver, #611) */ gboolean xserver_i300_workaround; + /** completer mode */ + char *completer_mode; } Settings; /** Default number of lines in the list view */ diff --git a/source/mode.c b/source/mode.c index e62127cb..2e2cdfa3 100644 --- a/source/mode.c +++ b/source/mode.c @@ -44,8 +44,9 @@ int mode_init(Mode *mode) { g_return_val_if_fail(mode != NULL, FALSE); g_return_val_if_fail(mode->_init != NULL, FALSE); - if ( mode->type == MODE_TYPE_UNSET ) { - g_warning("Mode '%s' does not have a type set. Please update mode.", mode->name); + if (mode->type == MODE_TYPE_UNSET) { + g_warning("Mode '%s' does not have a type set. Please update mode.", + mode->name); } // to make sure this is initialized correctly. mode->fallback_icon_fetch_uid = 0; @@ -208,4 +209,24 @@ char *mode_get_message(const Mode *mode) { } return NULL; } + +Mode *mode_create(const Mode *mode) { + if (mode->_create) { + return mode->_create(); + } + return NULL; +} + +ModeMode mode_completer_result(Mode *mode, int menu_retv, char **input, + unsigned int selected_line, char **path) { + if ((mode->type & MODE_TYPE_COMPLETER) == 0) { + g_warning("Trying to call completer_result on non completion mode."); + return 0; + } + if (mode->_completer_result) { + return mode->_completer_result(mode, menu_retv, input, selected_line, path); + } + return 0; +} + /**@}*/ diff --git a/source/modes/drun.c b/source/modes/drun.c index 41b086ca..69151f84 100644 --- a/source/modes/drun.c +++ b/source/modes/drun.c @@ -1182,8 +1182,8 @@ static ModeMode drun_mode_result(Mode *sw, int mretv, char **input, retv = MODE_EXIT; } else { char *path = NULL; - retv = file_browser_mode_completer(rmpd->completer, mretv, input, - selected_line, &path); + retv = mode_completer_result(rmpd->completer, mretv, input, selected_line, + &path); if (retv == MODE_EXIT) { exec_cmd_entry(&(rmpd->entry_list[rmpd->selected_line]), path); } @@ -1247,9 +1247,12 @@ static ModeMode drun_mode_result(Mode *sw, int mretv, char **input, g_free(*input); *input = g_strdup(rmpd->old_completer_input); - rmpd->completer = create_new_file_browser(); - mode_init(rmpd->completer); - rmpd->file_complete = TRUE; + const Mode *comp = rofi_get_completer(); + if (comp) { + rmpd->completer = mode_create(comp); + mode_init(rmpd->completer); + rmpd->file_complete = TRUE; + } } g_regex_unref(regex); } @@ -1483,7 +1486,7 @@ Mode drun_mode = {.name = "drun", ._get_icon = _get_icon, ._preprocess_input = NULL, .private_data = NULL, - .free = NULL, - .type = MODE_TYPE_SWITCHER }; + .free = NULL, + .type = MODE_TYPE_SWITCHER}; #endif // ENABLE_DRUN diff --git a/source/modes/recursivebrowser.c b/source/modes/recursivebrowser.c index e88d3362..6c7a5b4f 100644 --- a/source/modes/recursivebrowser.c +++ b/source/modes/recursivebrowser.c @@ -230,11 +230,11 @@ static void scan_dir(FileBrowserModePrivateData *pd, GFile *path) { case DT_LNK: { FBFile *f = g_malloc0(sizeof(FBFile)); // Rofi expects utf-8, so lets convert the filename. - f->name = g_filename_to_utf8(rd->d_name, -1, NULL, NULL, NULL); + f->path = g_build_filename(cdir, rd->d_name, NULL); + f->name = g_filename_to_utf8(f->path, -1, NULL, NULL, NULL); if (f->name == NULL) { f->name = rofi_force_utf8(rd->d_name, -1); } - f->path = g_build_filename(cdir, rd->d_name, NULL); f->icon_fetch_uid = 0; f->icon_fetch_size = 0; f->link = TRUE; @@ -536,5 +536,4 @@ Mode recursive_browser_mode = { ._completer_result = recursive_browser_mode_completer, .private_data = NULL, .free = NULL, - .type = MODE_TYPE_SWITCHER|MODE_TYPE_COMPLETER -}; + .type = MODE_TYPE_SWITCHER | MODE_TYPE_COMPLETER}; diff --git a/source/modes/run.c b/source/modes/run.c index db3245da..4bc5ec03 100644 --- a/source/modes/run.c +++ b/source/modes/run.c @@ -440,8 +440,8 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input, retv = MODE_EXIT; } else { char *path = NULL; - retv = file_browser_mode_completer(rmpd->completer, mretv, input, - selected_line, &path); + retv = mode_completer_result(rmpd->completer, mretv, input, selected_line, + &path); if (retv == MODE_EXIT) { if (path == NULL) { exec_cmd(rmpd->cmd_list[rmpd->selected_line].entry, run_in_term); @@ -488,9 +488,12 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input, g_free(*input); *input = g_strdup(rmpd->old_completer_input); - rmpd->completer = create_new_file_browser(); - mode_init(rmpd->completer); - rmpd->file_complete = TRUE; + const Mode *comp = rofi_get_completer(); + if (comp) { + rmpd->completer = mode_create(comp); + mode_init(rmpd->completer); + rmpd->file_complete = TRUE; + } } } return retv; @@ -573,5 +576,5 @@ Mode run_mode = {.name = "run", ._preprocess_input = NULL, .private_data = NULL, .free = NULL, - .type = MODE_TYPE_SWITCHER }; + .type = MODE_TYPE_SWITCHER}; /** @}*/ diff --git a/source/rofi.c b/source/rofi.c index 8ea16158..10d94a0e 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -165,6 +165,21 @@ static int mode_lookup(const char *name) { } return -1; } +/** + * @param name Name of the mode to lookup. + * + * Find the index of the mode with name. + * + * @returns index of the mode in modes, -1 if not found. + */ +static const Mode *mode_available_lookup(const char *name) { + for (unsigned int i = 0; i < num_available_modes; i++) { + if (strcmp(mode_get_name(available_modes[i]), name) == 0) { + return available_modes[i]; + } + } + return NULL; +} /** * Teardown the gui. @@ -1196,3 +1211,12 @@ int rofi_theme_rasi_validate(const char *filename) { return EXIT_FAILURE; } + +const Mode *rofi_get_completer(void) { + const Mode *index = mode_available_lookup(config.completer_mode); + printf("%p\n", index); + if (index != NULL) { + return index; + } + return NULL; +} diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 34d2fff5..833031a3 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -439,6 +439,12 @@ static XrmOption xrmOptions[] = { NULL, "Workaround for XServer issue #300 (issue #611 for rofi.)", CONFIG_DEFAULT}, + {xrm_String, + "completer-mode", + {.str = &(config.completer_mode)}, + NULL, + "What completer to use for drun/run.", + CONFIG_DEFAULT}, }; /** Dynamic array of extra options */