summaryrefslogtreecommitdiffstats
path: root/source/helper.c
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-08-25 08:43:40 +0200
committerDave Davenport <qball@gmpclient.org>2016-08-25 21:17:58 +0200
commit20e55e1e4e7a084e2e86c16e5b3f0497a14773a4 (patch)
treee3a45cbbbf93135bcafbdced2878bac0282d2fe6 /source/helper.c
parenta657f81145465df1d8a75bedb1b56a0e99d541e0 (diff)
Add fuzzy matching, make a -matching option.
* -matching *method* option instead of -regex, -glob, -fuzzy. * Re-add fuzzy matching pattern. * When there are substrings in regex, only highlight those matches. Fixes: #447
Diffstat (limited to 'source/helper.c')
-rw-r--r--source/helper.c91
1 files changed, 72 insertions, 19 deletions
diff --git a/source/helper.c b/source/helper.c
index 6908f1ef..9e420c91 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -168,28 +168,58 @@ static gchar *glob_to_regex ( const char *input )
}
return r;
}
+static gchar *fuzzy_to_regex ( const char * input )
+{
+ GString *str = g_string_new ( "" );
+ gchar *r = g_regex_escape_string ( input, -1 );
+ gchar *iter;
+ int first = 1;
+ for ( iter = r; iter && *iter != '\0'; iter = g_utf8_next_char ( iter ) ) {
+ if ( first ) {
+ g_string_append ( str, "(" );
+ }
+ else {
+ g_string_append ( str, ".*(" );
+ }
+ g_string_append_unichar ( str, g_utf8_get_char ( iter ) );
+ g_string_append ( str, ")" );
+ first = 0;
+ }
+ g_free ( r );
+ char *retv = str->str;
+ g_string_free ( str, FALSE );
+ return retv;
+}
static GRegex * create_regex ( const char *input, int case_sensitive )
{
#define R( s ) g_regex_new ( s, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL )
GRegex * retv = NULL;
- if ( config.glob ) {
- gchar *r = glob_to_regex ( input );
+ gchar *r;
+ switch ( config.matching_method )
+ {
+ case MM_GLOB:
+ r = glob_to_regex ( input );
retv = R ( r );
g_free ( r );
- }
- else if ( config.regex ) {
+ break;
+ case MM_REGEX:
retv = R ( input );
if ( retv == NULL ) {
- gchar *r = g_regex_escape_string ( input, -1 );
+ r = g_regex_escape_string ( input, -1 );
retv = R ( r );
g_free ( r );
}
- }
- else{
- // TODO; regex should be default?
- gchar *r = g_regex_escape_string ( input, -1 );
+ break;
+ case MM_FUZZY:
+ r = fuzzy_to_regex ( input );
+ retv = R ( r );
+ g_free ( r );
+ break;
+ default:
+ r = g_regex_escape_string ( input, -1 );
retv = R ( r );
g_free ( r );
+ break;
}
return retv;
}
@@ -204,7 +234,7 @@ GRegex **tokenize ( const char *input, int case_sensitive )
}
char *saveptr = NULL, *token;
- GRegex **retv = NULL;
+ GRegex **retv = NULL;
if ( !config.tokenize ) {
retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
retv[0] = (GRegex *) create_regex ( input, case_sensitive );
@@ -346,14 +376,17 @@ PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input,
GMatchInfo *gmi = NULL;
g_regex_match ( (GRegex *) tokens[j], input, G_REGEX_MATCH_PARTIAL, &gmi );
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 );
- 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 );
+ int count = g_match_info_get_match_count ( gmi );
+ for ( int index = ( count > 1 ) ? 1 : 0; index < count; index++ ) {
+ int start, end;
+ g_match_info_fetch_pos ( gmi, index, &start, &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 );
@@ -362,7 +395,6 @@ PangoAttrList *token_match_get_pango_attr ( GRegex **tokens, const char *input,
return retv;
}
-
int token_match ( GRegex * const *tokens, const char *input )
{
int match = 1;
@@ -458,6 +490,27 @@ int config_sanity_check ( void )
int found_error = FALSE;
GString *msg = g_string_new (
"<big><b>The configuration failed to validate:</b></big>\n" );
+
+ if ( config.matching ) {
+ if ( g_strcmp0 ( config.matching, "regex" ) == 0 ) {
+ config.matching_method = MM_REGEX;
+ }
+ else if ( g_strcmp0 ( config.matching, "glob" ) == 0 ) {
+ config.matching_method = MM_GLOB;
+ }
+ else if ( g_strcmp0 ( config.matching, "fuzzy" ) == 0 ) {
+ config.matching_method = MM_FUZZY;
+ }
+ else if ( g_strcmp0 ( config.matching, "normal" ) == 0 ) {
+ config.matching_method = MM_NORMAL;;
+ }
+ else {
+ g_string_append_printf ( msg, "\t<b>config.matching</b>=%s is not a valid matching strategy.\nValid options are: glob, regex, fuzzy or normal.\n",
+ config.matching );
+ found_error = 1;
+ }
+ }
+
if ( config.element_height < 1 ) {
g_string_append_printf ( msg, "\t<b>config.element_height</b>=%d is invalid. An element needs to be atleast 1 line high.\n",
config.element_height );