summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2020-09-30 21:56:37 +0200
committerDave Davenport <qball@gmpclient.org>2020-09-30 21:56:37 +0200
commitb4bbce4af5593486ce322bfaa55ef83f75a8b7a6 (patch)
tree7bcd88273ca3f3e81cc68775215d6b8c3303db46 /source
parent96c7ab0fffa7dee1090c72fbe0763bcb9f75667a (diff)
[Helper] Add -normalize-match option.
Decomposes string and remove accent characters before matching. This makes o match ö, é match e and more. It is not a perfect implementation but works. Currently disables the match highlighting. Fixes: #1119
Diffstat (limited to 'source')
-rw-r--r--source/helper.c50
-rw-r--r--source/xrmoptions.c2
2 files changed, 50 insertions, 2 deletions
diff --git a/source/helper.c b/source/helper.c
index a7bfa3e8..0a5e86ca 100644
--- a/source/helper.c
+++ b/source/helper.c
@@ -180,10 +180,43 @@ static gchar *fuzzy_to_regex ( const char * input )
return retv;
}
+static char *utf8_helper_simplify_string ( const char *s)
+{
+ gunichar buf2[G_UNICHAR_MAX_DECOMPOSITION_LENGTH] = {0,};
+ char buf[6] = {0,};
+ // Compose the string in maximally composed form.
+ char * str = g_malloc0((g_utf8_strlen(s,0)*6+2));
+ char *striter = str;
+ for ( const char *iter = s; iter && *iter; iter = g_utf8_next_char ( iter )) {
+ gunichar uc = g_utf8_get_char ( iter );
+ int l = 0;
+ gsize dl = g_unichar_fully_decompose ( uc, FALSE, buf2, G_UNICHAR_MAX_DECOMPOSITION_LENGTH) ;
+ if ( dl ) {
+ l = g_unichar_to_utf8 ( buf2[0], buf);
+ } else {
+ l = g_unichar_to_utf8 ( uc, buf);
+ }
+ memcpy(striter, buf, l);
+ striter+=l;
+ }
+
+ return str;
+}
+
// Macro for quickly generating regex for matching.
static inline GRegex * R ( const char *s, int case_sensitive )
{
+ if ( config.normalize_match ) {
+ char *str = utf8_helper_simplify_string ( s );
+
+ GRegex *r = g_regex_new ( str, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL );
+
+ g_free ( str );
+ return r;
+ } else {
return g_regex_new ( s, G_REGEX_OPTIMIZE | ( ( case_sensitive ) ? 0 : G_REGEX_CASELESS ), 0, NULL );
+
+ }
}
static rofi_int_matcher * create_regex ( const char *input, int case_sensitive )
@@ -380,6 +413,10 @@ int find_arg_char ( const char * const key, char *val )
PangoAttrList *helper_token_match_get_pango_attr ( RofiHighlightColorStyle th, rofi_int_matcher**tokens, const char *input, PangoAttrList *retv )
{
+ // Disable highlighting for normalize match, not supported atm.
+ if ( config.normalize_match ) {
+ return retv;
+ }
// Do a tokenized match.
if ( tokens ) {
for ( int j = 0; tokens[j]; j++ ) {
@@ -453,10 +490,19 @@ int helper_token_match ( rofi_int_matcher* const *tokens, const char *input )
int match = TRUE;
// Do a tokenized match.
if ( tokens ) {
+ if ( config.normalize_match ) {
+ char *r = utf8_helper_simplify_string(input);
+ for ( int j = 0; match && tokens[j]; j++ ) {
+ match = g_regex_match ( tokens[j]->regex, r, 0, NULL );
+ match ^= tokens[j]->invert;
+ }
+ g_free(r);
+ } else {
for ( int j = 0; match && tokens[j]; j++ ) {
- match = g_regex_match ( tokens[j]->regex, input, 0, NULL );
- match ^= tokens[j]->invert;
+ match = g_regex_match ( tokens[j]->regex, input, 0, NULL );
+ match ^= tokens[j]->invert;
}
+ }
}
return match;
}
diff --git a/source/xrmoptions.c b/source/xrmoptions.c
index aff2ec9b..9e4289d0 100644
--- a/source/xrmoptions.c
+++ b/source/xrmoptions.c
@@ -231,6 +231,8 @@ static XrmOption xrmOptions[] = {
"DRUN: build and use a cache with desktop file content.", CONFIG_DEFAULT },
{ xrm_Boolean, "drun-reload-desktop-cache", { .snum = &config.drun_reload_desktop_cache }, NULL,
"DRUN: If enabled, reload the cache with desktop file content.", CONFIG_DEFAULT },
+ { xrm_Boolean, "normalize-match", { .snum = &config.normalize_match }, NULL,
+ "Normalize string when matching (implies -no-show-match).", CONFIG_DEFAULT },
};
/** Dynamic array of extra options */