summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-05-26 08:39:33 +0200
committerDave Davenport <qball@gmpclient.org>2016-05-26 08:39:33 +0200
commit0e86050db8d3e20a93fada37724d9c8d59386c55 (patch)
tree835d1e58c9652b8d708a17074c6c922c74f60025
parent7aff2ae243f4d15875a5a6d567112400a727e642 (diff)
Fix combi mode 'bang' behaviour, improve levenshtein with combi
-rw-r--r--include/helper.h2
-rw-r--r--include/mode-private.h4
-rw-r--r--include/mode.h1
-rw-r--r--source/dialogs/combi.c50
-rw-r--r--source/dialogs/dmenu.c5
-rw-r--r--source/dialogs/drun.c9
-rw-r--r--source/dialogs/run.c3
-rw-r--r--source/dialogs/script.c1
-rw-r--r--source/dialogs/ssh.c1
-rw-r--r--source/dialogs/window.c11
-rw-r--r--source/helper.c17
-rw-r--r--source/mode.c8
-rw-r--r--source/textbox.c2
-rw-r--r--source/view.c16
14 files changed, 78 insertions, 52 deletions
diff --git a/include/helper.h b/include/helper.h
index e48b6d7f..81cd330c 100644
--- a/include/helper.h
+++ b/include/helper.h
@@ -97,7 +97,7 @@ int find_arg ( const char * const key );
*
* @returns 1 when matches, 0 otherwise
*/
-int token_match ( GRegex **tokens, const char *input);
+int token_match ( GRegex **tokens, const char *input );
/**
* @param cmd The command to execute.
*
diff --git a/include/mode-private.h b/include/mode-private.h
index 530827e8..31e92c98 100644
--- a/include/mode-private.h
+++ b/include/mode-private.h
@@ -27,6 +27,8 @@ typedef void ( *__mode_destroy )( Mode *sw );
typedef ModeMode ( *_mode_result )( Mode *sw, int menu_retv, char **input, unsigned int selected_line );
+typedef char* ( *_mode_preprocess_input )( Mode *sw, const char *input );
+
/**
* Structure defining a switcher.
* It consists of a name, callback and if enabled
@@ -57,6 +59,8 @@ struct rofi_mode
/** Get the 'completed' entry. */
_mode_get_completion _get_completion;
+ _mode_preprocess_input _preprocess_input;
+
/** Pointer to private data. */
void *private_data;
diff --git a/include/mode.h b/include/mode.h
index 672d74db..1a0d9b01 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -154,5 +154,6 @@ void mode_set_private_data ( Mode *mode, void *pd );
const char *mode_get_display_name ( const Mode *mode );
void mode_set_config ( Mode *mode );
+char * mode_preprocess_input ( Mode *mode, const char *input );
/*@}*/
#endif
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c
index 89c634b8..7cba5200 100644
--- a/source/dialogs/combi.c
+++ b/source/dialogs/combi.c
@@ -45,6 +45,7 @@ typedef struct
// List of switchers to combine.
unsigned int num_switchers;
Mode **switchers;
+ Mode *current;
} CombiModePrivateData;
static void combi_mode_parse_switchers ( Mode *sw )
@@ -178,34 +179,14 @@ static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned
static int combi_mode_match ( const Mode *sw, GRegex **tokens, unsigned int index )
{
CombiModePrivateData *pd = mode_get_private_data ( sw );
-// if ( config.regex || config.glob ) {
- // Bang support only works in text mode.
- for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
- if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) {
- return mode_token_match ( pd->switchers[i], tokens, index - pd->starts[i] );
- }
+ for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
+ if ( pd->current != NULL && pd->switchers[i] != pd->current ) {
+ continue;
}
- /* @TODO fix this
- }
- else{
- for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
- if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) {
- if ( tokens && tokens[0][0] == '!' ) {
- if ( tokens[0][1] == mode_get_name ( pd->switchers[i] )[0] ) {
- return mode_token_match ( pd->switchers[i], &tokens[1], not_ascii, case_sensitive,
- index - pd->starts[i] );
- }
- return 0;
- }
- else {
- return mode_token_match ( pd->switchers[i], tokens, not_ascii, case_sensitive,
- index - pd->starts[i] );
- }
- }
+ if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) {
+ return mode_token_match ( pd->switchers[i], tokens, index - pd->starts[i] );
}
}
- */
- abort ();
return 0;
}
static char * combi_mgrv ( const Mode *sw, unsigned int selected_line, int *state, int get_entry )
@@ -247,6 +228,24 @@ static char * combi_get_completion ( const Mode *sw, unsigned int index )
return NULL;
}
+static char * combi_preprocess_input ( Mode *sw, const char *input )
+{
+ CombiModePrivateData *pd = mode_get_private_data ( sw );
+ pd->current = NULL;
+ if ( input != NULL && input[0] == '!' && strlen ( input ) > 1 ) {
+ for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
+ if ( input[1] == mode_get_name ( pd->switchers[i] )[0] ) {
+ pd->current = pd->switchers[i];
+ if ( input[2] == '\0' ) {
+ return NULL;
+ }
+ return g_strdup ( &input[2] );
+ }
+ }
+ }
+ return g_strdup ( input );
+}
+
#include "mode-private.h"
Mode combi_mode =
{
@@ -259,6 +258,7 @@ Mode combi_mode =
._token_match = combi_mode_match,
._get_completion = combi_get_completion,
._get_display_value = combi_mgrv,
+ ._preprocess_input = combi_preprocess_input,
.private_data = NULL,
.free = NULL
};
diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c
index 4d4cdbbc..c7b016aa 100644
--- a/source/dialogs/dmenu.c
+++ b/source/dialogs/dmenu.c
@@ -350,6 +350,7 @@ Mode dmenu_mode =
._token_match = dmenu_token_match,
._get_display_value = get_display_data,
._get_completion = NULL,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
@@ -509,7 +510,7 @@ int dmenu_switcher_dialog ( void )
char *select = NULL;
find_arg_str ( "-select", &select );
if ( select != NULL ) {
- GRegex **tokens = tokenize ( select, config.case_sensitive );
+ GRegex **tokens = tokenize ( select, config.case_sensitive );
unsigned int i = 0;
for ( i = 0; i < cmd_list_length; i++ ) {
if ( token_match ( tokens, cmd_list[i] ) ) {
@@ -520,7 +521,7 @@ int dmenu_switcher_dialog ( void )
tokenize_free ( tokens );
}
if ( find_arg ( "-dump" ) >= 0 ) {
- GRegex **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive );
+ GRegex **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive );
unsigned int i = 0;
for ( i = 0; i < cmd_list_length; i++ ) {
if ( token_match ( tokens, cmd_list[i] ) ) {
diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c
index 39fee13f..fcab4f0e 100644
--- a/source/dialogs/drun.c
+++ b/source/dialogs/drun.c
@@ -378,24 +378,24 @@ static char *drun_get_completion ( const Mode *sw, unsigned int index )
}
}
-static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index)
+static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index )
{
DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data );
int match = 1;
if ( tokens ) {
for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) {
- int test = 0;
+ int test = 0;
GRegex *ftokens[2] = { tokens[j], NULL };
if ( !test && rmpd->entry_list[index].name &&
token_match ( ftokens, rmpd->entry_list[index].name ) ) {
test = 1;
}
if ( !test && rmpd->entry_list[index].generic_name &&
- token_match ( ftokens, rmpd->entry_list[index].generic_name) ) {
+ token_match ( ftokens, rmpd->entry_list[index].generic_name ) ) {
test = 1;
}
- if ( !test && token_match ( ftokens, rmpd->entry_list[index].exec) ) {
+ if ( !test && token_match ( ftokens, rmpd->entry_list[index].exec ) ) {
test = 1;
}
if ( test == 0 ) {
@@ -423,6 +423,7 @@ Mode drun_mode =
._token_match = drun_token_match,
._get_completion = drun_get_completion,
._get_display_value = _get_display_value,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
diff --git a/source/dialogs/run.c b/source/dialogs/run.c
index 51db25d9..523a0b4e 100644
--- a/source/dialogs/run.c
+++ b/source/dialogs/run.c
@@ -421,7 +421,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_
static int run_token_match ( const Mode *sw, GRegex **tokens, unsigned int index )
{
const RunModePrivateData *rmpd = (const RunModePrivateData *) sw->private_data;
- return token_match ( tokens, rmpd->cmd_list[index]);
+ return token_match ( tokens, rmpd->cmd_list[index] );
}
#include "mode-private.h"
@@ -436,6 +436,7 @@ Mode run_mode =
._token_match = run_token_match,
._get_display_value = _get_display_value,
._get_completion = NULL,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
diff --git a/source/dialogs/script.c b/source/dialogs/script.c
index 3abb2aba..bac6e1b8 100644
--- a/source/dialogs/script.c
+++ b/source/dialogs/script.c
@@ -200,6 +200,7 @@ Mode *script_switcher_parse_setup ( const char *str )
sw->_destroy = script_mode_destroy;
sw->_token_match = script_token_match;
sw->_get_completion = NULL,
+ sw->_preprocess_input = NULL,
sw->_get_display_value = _get_display_value;
return sw;
diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c
index 3bf38f8e..331e5431 100644
--- a/source/dialogs/ssh.c
+++ b/source/dialogs/ssh.c
@@ -498,6 +498,7 @@ Mode ssh_mode =
._token_match = ssh_token_match,
._get_display_value = _get_display_value,
._get_completion = NULL,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
diff --git a/source/dialogs/window.c b/source/dialogs/window.c
index a2918bb7..56ff8d01 100644
--- a/source/dialogs/window.c
+++ b/source/dialogs/window.c
@@ -338,19 +338,19 @@ static int window_match ( const Mode *sw, GRegex **tokens, unsigned int index )
// e.g. when searching 'title element' and 'class element'
GRegex *ftokens[2] = { tokens[j], NULL };
if ( !test && c->title != NULL && c->title[0] != '\0' ) {
- test = token_match ( ftokens, c->title);
+ test = token_match ( ftokens, c->title );
}
if ( !test && c->class != NULL && c->class[0] != '\0' ) {
- test = token_match ( ftokens, c->class);
+ test = token_match ( ftokens, c->class );
}
if ( !test && c->role != NULL && c->role[0] != '\0' ) {
- test = token_match ( ftokens, c->role);
+ test = token_match ( ftokens, c->role );
}
if ( !test && c->name != NULL && c->name[0] != '\0' ) {
- test = token_match ( ftokens, c->name);
+ test = token_match ( ftokens, c->name );
}
if ( test == 0 ) {
@@ -653,7 +653,6 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, in
return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL;
}
-
#include "mode-private.h"
Mode window_mode =
{
@@ -666,6 +665,7 @@ Mode window_mode =
._token_match = window_match,
._get_display_value = _get_display_value,
._get_completion = NULL,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
@@ -680,6 +680,7 @@ Mode window_mode_cd =
._token_match = window_match,
._get_display_value = _get_display_value,
._get_completion = NULL,
+ ._preprocess_input = NULL,
.private_data = NULL,
.free = NULL
};
diff --git a/source/helper.c b/source/helper.c
index 1897516f..88fed23b 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -196,11 +196,11 @@ static GRegex * create_regex ( const char *input, int case_sensitive )
}
GRegex **tokenize ( const char *input, int case_sensitive )
{
- if ( input == NULL || strlen(input) == 0 ) {
+ if ( input == NULL || strlen ( input ) == 0 ) {
return NULL;
}
- char *saveptr = NULL, *token;
+ char *saveptr = NULL, *token;
GRegex **retv = NULL;
if ( !config.tokenize ) {
retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
@@ -219,7 +219,7 @@ GRegex **tokenize ( const char *input, int case_sensitive )
const char * const sep = " ";
for ( token = strtok_r ( str, sep, &saveptr ); token != NULL; token = strtok_r ( NULL, sep, &saveptr ) ) {
retv = g_realloc ( retv, sizeof ( GRegex* ) * ( num_tokens + 2 ) );
- retv[num_tokens] = (GRegex*) create_regex ( token, case_sensitive );
+ retv[num_tokens] = (GRegex *) create_regex ( token, case_sensitive );
retv[num_tokens + 1] = NULL;
num_tokens++;
}
@@ -335,7 +335,6 @@ int find_arg_char ( const char * const key, char *val )
return FALSE;
}
-
PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input, PangoAttrList *retv )
{
// Do a tokenized match.
@@ -346,10 +345,12 @@ PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input,
while ( g_match_info_matches ( gmi ) ) {
int start, end;
g_match_info_fetch_pos ( gmi, 0, &start, &end );
- PangoAttribute *pa = pango_attr_underline_new ( PANGO_UNDERLINE_SINGLE );
- pa->start_index = start;
- pa->end_index = end;
+ PangoAttribute *pa = pango_attr_underline_new ( PANGO_UNDERLINE_SINGLE );
+ PangoAttribute *pa2 = pango_attr_weight_new ( PANGO_WEIGHT_BOLD );
+ pa2->start_index = pa->start_index = start;
+ pa2->end_index = pa->end_index = end;
pango_attr_list_insert ( retv, pa );
+ pango_attr_list_insert ( retv, pa2 );
g_match_info_next ( gmi, NULL );
}
g_match_info_free ( gmi );
@@ -358,7 +359,7 @@ PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input,
return retv;
}
-int token_match ( GRegex **tokens, const char *input)
+int token_match ( GRegex **tokens, const char *input )
{
int match = 1;
// Do a tokenized match.
diff --git a/source/mode.c b/source/mode.c
index 4233f100..48cf9477 100644
--- a/source/mode.c
+++ b/source/mode.c
@@ -116,4 +116,12 @@ void mode_set_config ( Mode *mode )
snprintf ( mode->cfg_name_key, 128, "display-%s", mode->name );
config_parser_add_option ( xrm_String, mode->cfg_name_key, (void * *) &( mode->display_name ), "The display name of this browser" );
}
+
+char * mode_preprocess_input ( Mode *mode, const char *input )
+{
+ if ( mode->_preprocess_input ) {
+ return mode->_preprocess_input ( mode, input );
+ }
+ return g_strdup ( input );
+}
/*@}*/
diff --git a/source/textbox.c b/source/textbox.c
index a5f24bed..425dbf44 100644
--- a/source/textbox.c
+++ b/source/textbox.c
@@ -607,7 +607,7 @@ gboolean textbox_append_char ( textbox *tb, char *pad, int pad_len )
}
// Filter When alt/ctrl is pressed do not accept the character.
- if ( !g_unichar_iscntrl(g_utf8_get_char(pad))){
+ if ( !g_unichar_iscntrl ( g_utf8_get_char ( pad ) ) ) {
tb->blink = 2;
textbox_insert ( tb, tb->cursor, pad, pad_len );
textbox_cursor ( tb, tb->cursor + pad_len );
diff --git a/source/view.c b/source/view.c
index 8473d859..6a565aab 100644
--- a/source/view.c
+++ b/source/view.c
@@ -464,7 +464,7 @@ static RofiViewState * __rofi_view_state_create ( void )
typedef struct _thread_state
{
RofiViewState *state;
- GRegex **tokens;
+ GRegex **tokens;
unsigned int start;
unsigned int stop;
unsigned int count;
@@ -500,7 +500,9 @@ static void filter_elements ( thread_state *t, G_GNUC_UNUSED gpointer user_data
if ( config.levenshtein_sort ) {
// This is inefficient, need to fix it.
char * str = mode_get_completion ( t->state->sw, i );
- t->state->distance[i] = levenshtein ( t->state->text->text, str );
+ char * input = mode_preprocess_input ( t->state->sw, t->state->text->text );
+ t->state->distance[i] = levenshtein ( input, str );
+ g_free(input);
g_free ( str );
}
t->count++;
@@ -925,7 +927,9 @@ static void rofi_view_draw ( RofiViewState *state, cairo_t *d )
int x_offset = state->border;
if ( state->rchanged ) {
- GRegex **tokens = tokenize ( state->text->text, config.case_sensitive );
+ char *input = mode_preprocess_input ( state->sw, state->text->text );
+ GRegex **tokens = tokenize ( input, config.case_sensitive );
+ g_free(input);
// Move, resize visible boxes and show them.
for ( i = 0; i < max_elements && ( i + offset ) < state->filtered_lines; i++ ) {
unsigned int ex = ( ( i ) / state->max_rows ) * ( element_width + config.line_margin );
@@ -1248,7 +1252,9 @@ static void rofi_view_refilter ( RofiViewState *state )
TICK_N ( "Filter start" );
if ( strlen ( state->text->text ) > 0 ) {
unsigned int j = 0;
- GRegex **tokens = tokenize ( state->text->text, config.case_sensitive );
+ gchar *input = mode_preprocess_input ( state->sw, state->text->text );
+ GRegex **tokens = tokenize ( input, config.case_sensitive );
+ g_free ( input );
/**
* On long lists it can be beneficial to parallelize.
* If number of threads is 1, no thread is spawn.
@@ -1632,7 +1638,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
state->finalize = finalize;
// Request the lines to show.
- state->num_lines = mode_get_num_entries ( sw );
+ state->num_lines = mode_get_num_entries ( sw );
TICK_N ( "Startup notification" );