diff --git a/config/config.c b/config/config.c index 62adab5dc..cd7ebb5ee 100644 --- a/config/config.c +++ b/config/config.c @@ -155,6 +155,10 @@ Settings config = { .plugin_path = PLUGIN_PATH, .max_history_size = 25, .combi_hide_mode_prefix = FALSE, + /** Combi format display */ + .combi_display_format = "{mode} {element}", + .combi_no_linebreak_modi = "", + .combi_no_linebreak_str = " ", .matching_negate_char = '-', diff --git a/include/settings.h b/include/settings.h index b1f35e33d..d1816190b 100644 --- a/include/settings.h +++ b/include/settings.h @@ -184,6 +184,10 @@ typedef struct /** Maximum history length per mode. */ unsigned int max_history_size; gboolean combi_hide_mode_prefix; + /** Combi mode formatting */ + char * combi_display_format; + char * combi_no_linebreak_modi; + char * combi_no_linebreak_str; char matching_negate_char; diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index 691afce9f..fff4d9e62 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -39,6 +39,7 @@ #include #include "mode-private.h" #include +#include "widgets/textbox.h" /** * Combi Mode @@ -47,6 +48,7 @@ typedef struct { Mode *mode; gboolean disable; + gboolean print_newline; } CombiMode; typedef struct @@ -69,6 +71,10 @@ static void combi_mode_parse_switchers ( Mode *sw ) char *switcher_str = g_strdup ( config.combi_modi ); const char * const sep = ",#"; // Split token on ','. This modifies switcher_str. + + GHashTable *ht; + ht = g_hash_table_new ( g_str_hash, g_str_equal ); + for ( char *token = strtok_r ( switcher_str, sep, &savept ); token != NULL; token = strtok_r ( NULL, sep, &savept ) ) { // Resize and add entry. @@ -78,14 +84,19 @@ static void combi_mode_parse_switchers ( Mode *sw ) Mode *mode = rofi_collect_modi_search ( token ); if ( mode ) { pd->switchers[pd->num_switchers].disable = FALSE; - pd->switchers[pd->num_switchers++].mode = mode; + pd->switchers[pd->num_switchers].mode = mode; + pd->switchers[pd->num_switchers].print_newline = TRUE; + g_hash_table_insert( ht, token, &( pd->switchers[pd->num_switchers++] ) ); + /* g_hash_table_insert( ht, token, pd->switchers + pd->num_switchers ); */ } else { // If not build in, use custom switchers. Mode *sw = script_switcher_parse_setup ( token ); if ( sw != NULL ) { pd->switchers[pd->num_switchers].disable = FALSE; - pd->switchers[pd->num_switchers++].mode = sw; + pd->switchers[pd->num_switchers].mode = sw; + pd->switchers[pd->num_switchers].print_newline = TRUE; + g_hash_table_insert( ht, token, &( pd->switchers[pd->num_switchers++] ) ); } else { // Report error, don't continue. @@ -94,8 +105,21 @@ static void combi_mode_parse_switchers ( Mode *sw ) } } } + + savept = NULL; + for ( char *token = strtok_r ( config.combi_no_linebreak_modi, sep, &savept ); token != NULL; + token = strtok_r ( NULL, sep, &savept ) ) { + CombiMode *mode = g_hash_table_lookup ( ht, token ); + if ( mode != NULL ) { + mode->print_newline = FALSE; + } + else { + g_warning ( "%s is in -combi-no-linebreak-modi but not in -combi-modi.", token ); + } + } // Free string that was modified by strtok_r g_free ( switcher_str ); + g_hash_table_destroy( ht ); } static int combi_mode_init ( Mode *sw ) @@ -184,7 +208,11 @@ static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned return mretv & MENU_LOWER_MASK; } + unsigned offset = 0; for ( unsigned i = 0; i < pd->num_switchers; i++ ) { + if ( pd->switchers[i].disable ) { + offset += pd->lengths[i]; + } if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { return mode_result ( pd->switchers[i].mode, mretv, input, selected_line - pd->starts[i] ); @@ -222,9 +250,26 @@ static char * combi_mgrv ( const Mode *sw, unsigned int selected_line, int *stat char * retv; char * str = retv = mode_get_display_value ( pd->switchers[i].mode, selected_line - pd->starts[i], state, attr_list, TRUE ); const char *dname = mode_get_display_name ( pd->switchers[i].mode ); + char *format_str = g_strdup( config.combi_display_format ); if ( !config.combi_hide_mode_prefix ) { - retv = g_strdup_printf ( "%s %s", dname, str ); + if ( ! ( *state & MARKUP ) ) { + // Mode does not use markup, but we want to, so escape output + char * tmp_str = g_markup_escape_text( str, -1 ); + g_free(str); + str = tmp_str; + *state |= MARKUP; + } + char *dname_markup = g_markup_escape_text ( dname, -1 ); + char *opt_linebreak = g_strdup(pd->switchers[i].print_newline ? "\n" : config.combi_no_linebreak_str); + retv = helper_string_replace_if_exists( format_str, + "{mode}", dname_markup, + "{linebreak}", opt_linebreak, + "{element}", str, + NULL ); g_free ( str ); + g_free ( dname_markup ); + g_free ( opt_linebreak ); + g_free ( format_str ); } if ( attr_list != NULL ) { diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 13058262b..6f430ea9e 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -219,6 +219,12 @@ static XrmOption xrmOptions[] = { "Max history size (WARNING: can cause slowdowns when set to high).", CONFIG_DEFAULT }, { xrm_Boolean, "combi-hide-mode-prefix", { .snum = &config.combi_hide_mode_prefix }, NULL, "Hide the prefix mode prefix on the combi view.", CONFIG_DEFAULT }, + { xrm_String, "combi-display-format", { .str = &config.combi_display_format }, NULL, + "Combi mode format string. (Supports: mode,element)", CONFIG_DEFAULT }, + { xrm_String, "combi-no-linebreak-modi", { .str = &config.combi_no_linebreak_modi }, NULL, + "Modi that do not use a linbreak for {linebreak} in combi mode, but -combi-no-linebreak-str instead.", CONFIG_DEFAULT }, + { xrm_String, "combi-no-linebreak-str", { .str = &config.combi_no_linebreak_str }, NULL, + "String used instead of linebreak in the output formatting for -combi-no-linebreak-modi.", CONFIG_DEFAULT }, { xrm_Char, "matching-negate-char", { .charc = &config.matching_negate_char }, NULL, "Set the character used to negate the matching. ('\\0' to disable)", CONFIG_DEFAULT }, { xrm_String, "cache-dir", { .str = &config.cache_dir }, NULL, diff --git a/test/run_combi_mode_format.sh b/test/run_combi_mode_format.sh new file mode 100755 index 000000000..062eb4306 --- /dev/null +++ b/test/run_combi_mode_format.sh @@ -0,0 +1,8 @@ +rofi -show combi \ + -modi "test:./test_script.sh" \ + -combi-modi "test,window,drun" -eh 2 \ + -drun-display-format "[({generic})]"$'\n'"{name}" \ + -combi-display-format "[[{mode}]]{linebreak}{element}" \ + -combi-no-linebreak-str " " \ + -combi-no-linebreak-modi "drun" \ + -markup-combi 1