mirror of https://github.com/davatorium/rofi.git
Merge remote-tracking branch 'upstream/master' into fast-ascii-filtering
Conflicts: source/dialogs/dmenu.c source/helper.c source/rofi.c
This commit is contained in:
commit
a53061b890
|
@ -110,8 +110,6 @@ Settings config = {
|
||||||
.fixed_num_lines = FALSE,
|
.fixed_num_lines = FALSE,
|
||||||
/** Do not use history */
|
/** Do not use history */
|
||||||
.disable_history = FALSE,
|
.disable_history = FALSE,
|
||||||
/** Use levenshtein sorting when matching */
|
|
||||||
.levenshtein_sort = FALSE,
|
|
||||||
/** Case sensitivity of the search */
|
/** Case sensitivity of the search */
|
||||||
.case_sensitive = FALSE,
|
.case_sensitive = FALSE,
|
||||||
/** Separator to use for dmenu mode */
|
/** Separator to use for dmenu mode */
|
||||||
|
@ -129,7 +127,9 @@ Settings config = {
|
||||||
/** Modi to combine into one view. */
|
/** Modi to combine into one view. */
|
||||||
.combi_modi = "window,run",
|
.combi_modi = "window,run",
|
||||||
/** Fuzzy matching. */
|
/** Fuzzy matching. */
|
||||||
.fuzzy = FALSE,
|
.fuzzy = FALSE,
|
||||||
|
.glob = FALSE,
|
||||||
|
.tokenize = TRUE,
|
||||||
/** Monitor */
|
/** Monitor */
|
||||||
.monitor = -1,
|
.monitor = -1,
|
||||||
/** set line margin */
|
/** set line margin */
|
||||||
|
|
|
@ -210,8 +210,6 @@ typedef struct _Settings
|
||||||
unsigned int fixed_num_lines;
|
unsigned int fixed_num_lines;
|
||||||
/** Do not use history */
|
/** Do not use history */
|
||||||
unsigned int disable_history;
|
unsigned int disable_history;
|
||||||
/** Use levenshtein sorting when matching */
|
|
||||||
unsigned int levenshtein_sort;
|
|
||||||
/** Search case sensitivity */
|
/** Search case sensitivity */
|
||||||
unsigned int case_sensitive;
|
unsigned int case_sensitive;
|
||||||
/** Separator to use for dmenu mode */
|
/** Separator to use for dmenu mode */
|
||||||
|
@ -230,6 +228,8 @@ typedef struct _Settings
|
||||||
char *combi_modi;
|
char *combi_modi;
|
||||||
/** Fuzzy match */
|
/** Fuzzy match */
|
||||||
unsigned int fuzzy;
|
unsigned int fuzzy;
|
||||||
|
unsigned int glob;
|
||||||
|
unsigned int tokenize;
|
||||||
/** Monitors */
|
/** Monitors */
|
||||||
int monitor;
|
int monitor;
|
||||||
/** Line margin */
|
/** Line margin */
|
||||||
|
|
|
@ -181,8 +181,21 @@ char **tokenize ( const char *input, int case_sensitive )
|
||||||
|
|
||||||
char *saveptr = NULL, *token;
|
char *saveptr = NULL, *token;
|
||||||
char **retv = NULL;
|
char **retv = NULL;
|
||||||
|
if ( !config.tokenize ) {
|
||||||
|
retv = g_malloc0 ( sizeof ( char* ) * 2 );
|
||||||
|
if ( config.glob ) {
|
||||||
|
token = g_strconcat ( input, "*", NULL );
|
||||||
|
retv[0] = token_collate_key ( token, case_sensitive );
|
||||||
|
g_free ( token ); token = NULL;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
retv[0] = token_collate_key ( input, case_sensitive );
|
||||||
|
}
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
// First entry is always full (modified) stringtext.
|
// First entry is always full (modified) stringtext.
|
||||||
int num_tokens = 0;
|
int num_tokens = 0;
|
||||||
|
|
||||||
// Copy the string, 'strtok_r' modifies it.
|
// Copy the string, 'strtok_r' modifies it.
|
||||||
char *str = g_strdup ( input );
|
char *str = g_strdup ( input );
|
||||||
|
@ -190,8 +203,15 @@ char **tokenize ( const char *input, int case_sensitive )
|
||||||
// Iterate over tokens.
|
// Iterate over tokens.
|
||||||
// strtok should still be valid for utf8.
|
// strtok should still be valid for utf8.
|
||||||
for ( token = strtok_r ( str, " ", &saveptr ); token != NULL; token = strtok_r ( NULL, " ", &saveptr ) ) {
|
for ( token = strtok_r ( str, " ", &saveptr ); token != NULL; token = strtok_r ( NULL, " ", &saveptr ) ) {
|
||||||
retv = g_realloc ( retv, sizeof ( char* ) * ( num_tokens + 2 ) );
|
retv = g_realloc ( retv, sizeof ( char* ) * ( num_tokens + 2 ) );
|
||||||
retv[num_tokens] = token_collate_key ( token, case_sensitive );
|
if ( config.glob ) {
|
||||||
|
char *t = token_collate_key ( token, case_sensitive );
|
||||||
|
retv[num_tokens] = g_strconcat ( t, "*", NULL );
|
||||||
|
g_free ( t );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
retv[num_tokens] = token_collate_key ( token, case_sensitive );
|
||||||
|
}
|
||||||
retv[num_tokens + 1] = NULL;
|
retv[num_tokens + 1] = NULL;
|
||||||
num_tokens++;
|
num_tokens++;
|
||||||
}
|
}
|
||||||
|
@ -402,11 +422,30 @@ static int normal_token_match ( char **tokens, const char *input, int not_ascii,
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int glob_token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive )
|
||||||
|
{
|
||||||
|
int match = 1;
|
||||||
|
char *compk = not_ascii ? token_collate_key ( input, case_sensitive ) : (char *) input;
|
||||||
|
|
||||||
|
// Do a tokenized match.
|
||||||
|
if ( tokens ) {
|
||||||
|
for ( int j = 0; match && tokens[j]; j++ ) {
|
||||||
|
match = g_pattern_match_simple ( tokens[j], compk );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (not_ascii) g_free ( compk );
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive,
|
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive,
|
||||||
__attribute__( ( unused ) ) unsigned int index,
|
__attribute__( ( unused ) ) unsigned int index,
|
||||||
__attribute__( ( unused ) ) Switcher *data )
|
__attribute__( ( unused ) ) Switcher *data )
|
||||||
{
|
{
|
||||||
if ( config.fuzzy ) {
|
if ( config.glob ) {
|
||||||
|
return glob_token_match ( tokens, input, not_ascii, case_sensitive );
|
||||||
|
}
|
||||||
|
else if ( config.fuzzy ) {
|
||||||
return fuzzy_token_match ( tokens, input, not_ascii, case_sensitive );
|
return fuzzy_token_match ( tokens, input, not_ascii, case_sensitive );
|
||||||
}
|
}
|
||||||
return normal_token_match ( tokens, input, not_ascii, case_sensitive );
|
return normal_token_match ( tokens, input, not_ascii, case_sensitive );
|
||||||
|
|
|
@ -141,59 +141,6 @@ static inline MainLoopEvent wait_for_xevent_or_timeout ( Display *display, int x
|
||||||
* Levenshtein Sorting.
|
* Levenshtein Sorting.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int lev_sort ( const void *p1, const void *p2, void *arg )
|
|
||||||
{
|
|
||||||
const int *a = p1;
|
|
||||||
const int *b = p2;
|
|
||||||
int *distances = arg;
|
|
||||||
|
|
||||||
return distances[*a] - distances[*b];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dist ( const char *s, const char *t, int *d, int ls, int lt, int i, int j )
|
|
||||||
{
|
|
||||||
if ( d[i * ( lt + 1 ) + j] >= 0 ) {
|
|
||||||
return d[i * ( lt + 1 ) + j];
|
|
||||||
}
|
|
||||||
|
|
||||||
int x;
|
|
||||||
if ( i == ls ) {
|
|
||||||
x = lt - j;
|
|
||||||
}
|
|
||||||
else if ( j == lt ) {
|
|
||||||
x = ls - i;
|
|
||||||
}
|
|
||||||
else if ( s[i] == t[j] ) {
|
|
||||||
x = dist ( s, t, d, ls, lt, i + 1, j + 1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x = dist ( s, t, d, ls, lt, i + 1, j + 1 );
|
|
||||||
|
|
||||||
int y;
|
|
||||||
if ( ( y = dist ( s, t, d, ls, lt, i, j + 1 ) ) < x ) {
|
|
||||||
x = y;
|
|
||||||
}
|
|
||||||
if ( ( y = dist ( s, t, d, ls, lt, i + 1, j ) ) < x ) {
|
|
||||||
x = y;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
return d[i * ( lt + 1 ) + j] = x;
|
|
||||||
}
|
|
||||||
static int levenshtein ( const char *s, const char *t )
|
|
||||||
{
|
|
||||||
int ls = strlen ( s ), lt = strlen ( t );
|
|
||||||
size_t array_length = ( ls + 1 ) * ( lt + 1 );
|
|
||||||
|
|
||||||
// For some reason Coverity does not get that I initialize the
|
|
||||||
// array in for loop.
|
|
||||||
int d[array_length];
|
|
||||||
for ( size_t i = 0; i < array_length; i++ ) {
|
|
||||||
d[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dist ( s, t, d, ls, lt, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// State of the menu.
|
// State of the menu.
|
||||||
|
|
||||||
|
@ -224,7 +171,6 @@ typedef struct MenuState
|
||||||
textbox *case_indicator;
|
textbox *case_indicator;
|
||||||
textbox **boxes;
|
textbox **boxes;
|
||||||
scrollbar *scrollbar;
|
scrollbar *scrollbar;
|
||||||
int *distance;
|
|
||||||
unsigned int *line_map;
|
unsigned int *line_map;
|
||||||
|
|
||||||
unsigned int num_lines;
|
unsigned int num_lines;
|
||||||
|
@ -307,8 +253,6 @@ static void menu_free_state ( MenuState *state )
|
||||||
|
|
||||||
g_free ( state->boxes );
|
g_free ( state->boxes );
|
||||||
g_free ( state->line_map );
|
g_free ( state->line_map );
|
||||||
g_free ( state->distance );
|
|
||||||
|
|
||||||
g_free ( state->lines_not_ascii );
|
g_free ( state->lines_not_ascii );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,15 +676,9 @@ static void menu_refilter ( MenuState *state )
|
||||||
// If each token was matched, add it to list.
|
// If each token was matched, add it to list.
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
state->line_map[j] = i;
|
state->line_map[j] = i;
|
||||||
if ( config.levenshtein_sort ) {
|
|
||||||
state->distance[i] = levenshtein ( state->text->text, state->lines[i] );
|
|
||||||
}
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( config.levenshtein_sort ) {
|
|
||||||
g_qsort_with_data ( state->line_map, j, sizeof ( int ), lev_sort, state->distance );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup + bookkeeping.
|
// Cleanup + bookkeeping.
|
||||||
state->filtered_lines = j;
|
state->filtered_lines = j;
|
||||||
|
@ -1003,7 +941,6 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
||||||
.prev_key = 0,
|
.prev_key = 0,
|
||||||
.last_button_press = 0,
|
.last_button_press = 0,
|
||||||
.last_offset = 0,
|
.last_offset = 0,
|
||||||
.distance = NULL,
|
|
||||||
.quit = FALSE,
|
.quit = FALSE,
|
||||||
.skip_absorb = FALSE,
|
.skip_absorb = FALSE,
|
||||||
.filtered_lines = 0,
|
.filtered_lines = 0,
|
||||||
|
@ -1123,9 +1060,6 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
||||||
scrollbar_set_max_value ( state.scrollbar, state.num_lines );
|
scrollbar_set_max_value ( state.scrollbar, state.num_lines );
|
||||||
// filtered list
|
// filtered list
|
||||||
state.line_map = g_malloc0_n ( state.num_lines, sizeof ( unsigned int ) );
|
state.line_map = g_malloc0_n ( state.num_lines, sizeof ( unsigned int ) );
|
||||||
if ( config.levenshtein_sort ) {
|
|
||||||
state.distance = (int *) g_malloc0_n ( state.num_lines, sizeof ( int ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// resize window vertically to suit
|
// resize window vertically to suit
|
||||||
// Subtract the margin of the last row.
|
// Subtract the margin of the last row.
|
||||||
|
@ -1418,7 +1352,6 @@ void error_dialog ( const char *msg, int markup )
|
||||||
.last_button_press = 0,
|
.last_button_press = 0,
|
||||||
.last_offset = 0,
|
.last_offset = 0,
|
||||||
.num_lines = 0,
|
.num_lines = 0,
|
||||||
.distance = NULL,
|
|
||||||
.quit = FALSE,
|
.quit = FALSE,
|
||||||
.skip_absorb = FALSE,
|
.skip_absorb = FALSE,
|
||||||
.filtered_lines = 0,
|
.filtered_lines = 0,
|
||||||
|
|
|
@ -666,7 +666,6 @@ void textbox_setup ( Display *display )
|
||||||
|
|
||||||
void textbox_cleanup ( void )
|
void textbox_cleanup ( void )
|
||||||
{
|
{
|
||||||
printf ( "cleanup\n" );
|
|
||||||
if ( p_context ) {
|
if ( p_context ) {
|
||||||
g_object_unref ( p_context );
|
g_object_unref ( p_context );
|
||||||
p_context = NULL;
|
p_context = NULL;
|
||||||
|
|
|
@ -113,7 +113,6 @@ static XrmOption xrmOptions[] = {
|
||||||
{ xrm_String, "run-shell-command", { .str = &config.run_shell_command }, NULL },
|
{ xrm_String, "run-shell-command", { .str = &config.run_shell_command }, NULL },
|
||||||
|
|
||||||
{ xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL },
|
{ xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL },
|
||||||
{ xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL },
|
|
||||||
{ xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL },
|
{ xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL },
|
||||||
{ xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL },
|
{ xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL },
|
||||||
{ xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, NULL },
|
{ xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, NULL },
|
||||||
|
@ -122,6 +121,8 @@ static XrmOption xrmOptions[] = {
|
||||||
{ xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL },
|
{ xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL },
|
||||||
{ xrm_String, "combi-modi", { .str = &config.combi_modi }, NULL },
|
{ xrm_String, "combi-modi", { .str = &config.combi_modi }, NULL },
|
||||||
{ xrm_Boolean, "fuzzy", { .num = &config.fuzzy }, NULL },
|
{ xrm_Boolean, "fuzzy", { .num = &config.fuzzy }, NULL },
|
||||||
|
{ xrm_Boolean, "glob", { .num = &config.glob }, NULL },
|
||||||
|
{ xrm_Boolean, "tokenize", { .num = &config.tokenize }, NULL },
|
||||||
{ xrm_Number, "monitor", { .snum = &config.monitor }, NULL },
|
{ xrm_Number, "monitor", { .snum = &config.monitor }, NULL },
|
||||||
/* Alias for dmenu compatibility. */
|
/* Alias for dmenu compatibility. */
|
||||||
{ xrm_SNumber, "m", { .snum = &config.monitor }, NULL },
|
{ xrm_SNumber, "m", { .snum = &config.monitor }, NULL },
|
||||||
|
|
Loading…
Reference in New Issue