From d2aad68bceb11cb24d284608c2de8b7f00928aa4 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Tue, 8 Sep 2015 22:23:03 +0200 Subject: [PATCH] Keep the line matched (if possible) when filtering. --- include/rofi.h | 2 +- source/dialogs/dmenu.c | 13 +++--- source/rofi.c | 94 +++++++++++++++++++++++------------------- 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/include/rofi.h b/include/rofi.h index 3d809ec9..7a380f69 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -95,7 +95,7 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensi * @returns The command issued (see MenuReturn) */ MenuReturn menu ( Switcher *sw, char **input, char *prompt, - int *selected_line, + unsigned int *selected_line, unsigned int *next_pos, const char *message ) __attribute__ ( ( nonnull ( 1, 2, 3, 4 ) ) ); /** * @param sig The caught signal diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index e3eeb060..6c1cff5c 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "rofi.h" #include "dialogs/dmenu.h" #include "helper.h" @@ -44,7 +45,7 @@ struct range_pair typedef struct _DmenuModePrivateData { char *prompt; - int selected_line; + unsigned int selected_line; char *message; char *format; struct range_pair * urgent_list; @@ -225,13 +226,13 @@ static void dmenu_mode_init ( Switcher *sw ) DmenuModePrivateData *pd = (DmenuModePrivateData *) sw->private_data; pd->prompt = "dmenu "; - pd->selected_line = -1; + pd->selected_line = UINT32_MAX; find_arg_str ( "-mesg", &( pd->message ) ); // Check prompt find_arg_str ( "-p", &( pd->prompt ) ); - find_arg_int ( "-selected-row", &( pd->selected_line ) ); + find_arg_uint ( "-selected-row", &( pd->selected_line ) ); // By default we print the unescaped line back. pd->format = "s"; @@ -291,7 +292,7 @@ int dmenu_switcher_dialog ( void ) int retv = FALSE; int restart = FALSE; unsigned int cmd_list_length = 0; - char **cmd_list = dmenu_mode.get_data ( &( cmd_list_length ), &dmenu_mode ); + char **cmd_list = dmenu_mode.get_data ( &( cmd_list_length ), &dmenu_mode ); int only_selected = FALSE; @@ -368,14 +369,14 @@ int dmenu_switcher_dialog ( void ) retv = TRUE; } // Quick switch with entry selected. - else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line >= 0 ) { + else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line < UINT32_MAX ) { dmenu_output_formatted_line ( pd->format, cmd_list[pd->selected_line], pd->selected_line, input ); restart = FALSE; retv = 10 + ( mretv & MENU_LOWER_MASK ); } // Quick switch without entry selected. - else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line == -1 ) { + else if ( ( mretv & MENU_QUICK_SWITCH ) && pd->selected_line == UINT32_MAX ) { dmenu_output_formatted_line ( pd->format, input, -1, input ); restart = FALSE; diff --git a/source/rofi.c b/source/rofi.c index 5390789c..a4f1eec0 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -233,52 +233,52 @@ static Window create_window ( Display *display ) typedef struct MenuState { - Switcher *sw; - unsigned int menu_lines; - unsigned int max_elements; - unsigned int max_rows; - unsigned int columns; + Switcher *sw; + unsigned int menu_lines; + unsigned int max_elements; + unsigned int max_rows; + unsigned int columns; // window width,height - unsigned int w, h; - int x, y; - unsigned int element_width; - int top_offset; + unsigned int w, h; + int x, y; + unsigned int element_width; + int top_offset; // Update/Refilter list. - int update; - int refilter; - int rchanged; - int cur_page; + int update; + int refilter; + int rchanged; + int cur_page; // Entries - textbox *text; - textbox *prompt_tb; - textbox *message_tb; - textbox *case_indicator; - textbox **boxes; - scrollbar *scrollbar; - int *distance; - int *line_map; + textbox *text; + textbox *prompt_tb; + textbox *message_tb; + textbox *case_indicator; + textbox **boxes; + scrollbar *scrollbar; + int *distance; + unsigned int *line_map; - unsigned int num_lines; + unsigned int num_lines; // Selected element. - unsigned int selected; - unsigned int filtered_lines; + unsigned int selected; + unsigned int filtered_lines; // Last offset in paginating. - unsigned int last_offset; + unsigned int last_offset; - KeySym prev_key; - Time last_button_press; + KeySym prev_key; + Time last_button_press; - int quit; - int skip_absorb; + int quit; + int skip_absorb; // Return state - int *selected_line; - MenuReturn retv; - char **lines; - int line_height; + unsigned int *selected_line; + MenuReturn retv; + char **lines; + int line_height; }MenuState; /** @@ -704,6 +704,7 @@ static void menu_mouse_navigation ( MenuState *state, XButtonEvent *xbe ) static void menu_refilter ( MenuState *state, char **lines, menu_match_cb mmc, void *mmc_data, int sorting, int case_sensitive ) { + unsigned int sl = state->line_map[state->selected]; if ( strlen ( state->text->text ) > 0 ) { unsigned int j = 0; char **tokens = tokenize ( state->text->text, case_sensitive ); @@ -746,6 +747,12 @@ static void menu_refilter ( MenuState *state, char **lines, menu_match_cb mmc, v scrollbar_set_max_value ( state->scrollbar, state->filtered_lines ); state->refilter = FALSE; state->rchanged = TRUE; + for ( unsigned int i = 0; i < state->filtered_lines; i++ ) { + if ( state->line_map[i] == sl ) { + state->selected = i; + break; + } + } } @@ -902,12 +909,12 @@ static void menu_paste ( MenuState *state, XSelectionEvent *xse ) } MenuReturn menu ( Switcher *sw, char **input, char *prompt, - int *selected_line, + unsigned int *selected_line, unsigned int *next_pos, const char *message ) { - int shift = FALSE; - MenuState state = { - .sw = sw, + int shift = FALSE; + MenuState state = { + .sw = sw, .selected_line = selected_line, .retv = MENU_CANCEL, .prev_key = 0, @@ -1041,7 +1048,7 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, scrollbar_set_max_value ( state.scrollbar, state.num_lines ); // filtered list - state.line_map = g_malloc0_n ( state.num_lines, sizeof ( int ) ); + state.line_map = g_malloc0_n ( state.num_lines, sizeof ( unsigned int ) ); if ( config.levenshtein_sort ) { state.distance = (int *) g_malloc0_n ( state.num_lines, sizeof ( int ) ); } @@ -1086,9 +1093,10 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, state.quit = FALSE; menu_refilter ( &state, state.lines, sw->token_match, sw, config.levenshtein_sort, config.case_sensitive ); - for ( unsigned int i = 0; ( *( state.selected_line ) ) >= 0 && !state.selected && i < state.filtered_lines; i++ ) { + for ( unsigned int i = 0; ( *( state.selected_line ) ) < UINT32_MAX && !state.selected && i < state.filtered_lines; i++ ) { if ( state.line_map[i] == *( state.selected_line ) ) { state.selected = i; + break; } } @@ -1299,7 +1307,7 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, void error_dialog ( const char *msg, int markup ) { MenuState state = { - .sw = NULL, + .sw = NULL, .selected_line = NULL, .retv = MENU_CANCEL, .prev_key = 0, @@ -2064,9 +2072,9 @@ int main ( int argc, char *argv[] ) SwitcherMode switcher_run ( char **input, Switcher *sw ) { - char *prompt = g_strdup_printf ( "%s:", sw->name ); - int selected_line = -1; - int mretv = menu ( sw, input, prompt, &selected_line, NULL, NULL ); + char *prompt = g_strdup_printf ( "%s:", sw->name ); + unsigned int selected_line = UINT32_MAX; + int mretv = menu ( sw, input, prompt, &selected_line, NULL, NULL ); g_free ( prompt ); return sw->result ( mretv, input, selected_line, sw );