mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
[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
This commit is contained in:
parent
96c7ab0fff
commit
b4bbce4af5
6 changed files with 70 additions and 3 deletions
|
@ -170,5 +170,8 @@ Settings config = {
|
|||
.drun_reload_desktop_cache = FALSE,
|
||||
|
||||
/** Benchmarks */
|
||||
.benchmark_ui = FALSE
|
||||
.benchmark_ui = FALSE,
|
||||
|
||||
/** normalize match */
|
||||
.normalize_match = FALSE
|
||||
};
|
||||
|
|
|
@ -372,6 +372,14 @@ Default: *true*
|
|||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
\fB\fC\-normalize\-match\fR
|
||||
|
||||
.PP
|
||||
Normalize the string before matching, so o will match ö, and é matches e.
|
||||
This is not a perfect implementation, but works.
|
||||
For now it disabled highlighting of the matched part.
|
||||
|
||||
.PP
|
||||
\fB\fC\-no\-lazy\-grab\fR
|
||||
|
||||
|
|
|
@ -214,6 +214,12 @@ Show the indicator that shows what part of the string is matched.
|
|||
|
||||
Default: *true*
|
||||
|
||||
`-normalize-match`
|
||||
|
||||
Normalize the string before matching, so o will match ö, and é matches e.
|
||||
This is not a perfect implementation, but works.
|
||||
For now it disabled highlighting of the matched part.
|
||||
|
||||
`-no-lazy-grab`
|
||||
|
||||
Disables lazy grab, this forces the keyboard being grabbed before gui is shown.
|
||||
|
|
|
@ -203,6 +203,8 @@ typedef struct
|
|||
|
||||
/** Benchmark */
|
||||
gboolean benchmark_ui;
|
||||
|
||||
gboolean normalize_match;
|
||||
} Settings;
|
||||
/** Global Settings structure. */
|
||||
extern Settings config;
|
||||
|
|
|
@ -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,11 +490,20 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue