@@ -66,7 +66,7 @@ typedef struct {
6666 GRegex * newline_re ;
6767
6868 GRegex * filename_re ;
69- GPatternSpec * filename_glob_pattern ;
69+ GList * filename_glob_patterns ;
7070
7171 GMutex hit_list_lock ;
7272 GList * hit_list ; // holds FileSearchResults
@@ -445,6 +445,7 @@ search_thread_data_new (NemoSearchEngineAdvanced *engine,
445445 }
446446 } else {
447447 gchar * text , * normalized , * cased ;
448+ gchar * * words ;
448449
449450 text = nemo_query_get_file_pattern (query );
450451 normalized = g_utf8_normalize (text , -1 , G_NORMALIZE_NFD );
@@ -455,7 +456,37 @@ search_thread_data_new (NemoSearchEngineAdvanced *engine,
455456 cased = g_strdup (normalized );
456457 }
457458
458- data -> filename_glob_pattern = g_pattern_spec_new (cased );
459+ /* In (< 6.6), whitespace between words was treated as AND, and implied a filename
460+ * must include *this* AND *that* AND *other*. To preserve this behavior, split
461+ * the search text and wrap segments individually (*segment*) if no wildcard characters
462+ * already included, and generate a GPatternSpec for each segment. */
463+ words = g_strsplit_set (cased , " \t\r\n" , -1 );
464+ data -> filename_glob_patterns = NULL ;
465+
466+ for (gint i = 0 ; words [i ] != NULL ; i ++ ) {
467+ if (words [i ][0 ] != '\0' ) {
468+ g_autofree gchar * word_pattern = NULL ;
469+
470+ if (strchr (words [i ], '*' ) == NULL && strchr (words [i ], '?' ) == NULL ) {
471+ word_pattern = g_strdup_printf ("*%s*" , words [i ]);
472+ } else {
473+ word_pattern = g_strdup (words [i ]);
474+ }
475+
476+ DEBUG ("pattern is '%s'" , word_pattern );
477+
478+ data -> filename_glob_patterns = g_list_prepend (data -> filename_glob_patterns ,
479+ g_pattern_spec_new (word_pattern ));
480+ }
481+ }
482+
483+ g_strfreev (words );
484+
485+ data -> filename_glob_patterns = g_list_reverse (data -> filename_glob_patterns );
486+
487+ if (data -> filename_glob_patterns == NULL ) {
488+ data -> filename_glob_patterns = g_list_prepend (NULL , g_pattern_spec_new ("*" ));
489+ }
459490
460491 g_free (text );
461492 g_free (normalized );
@@ -540,7 +571,7 @@ search_thread_data_free (SearchThreadData *data)
540571 g_clear_pointer (& data -> content_re , g_regex_unref );
541572 g_clear_pointer (& data -> newline_re , g_regex_unref );
542573 g_clear_pointer (& data -> filename_re , g_regex_unref );
543- g_clear_pointer ( & data -> filename_glob_pattern , g_pattern_spec_free );
574+ g_list_free_full ( data -> filename_glob_patterns , ( GDestroyNotify ) g_pattern_spec_free );
544575 g_timer_destroy (data -> timer );
545576 g_mutex_clear (& data -> hit_list_lock );
546577
@@ -1011,7 +1042,17 @@ visit_directory (GFile *dir, SearchThreadData *data)
10111042 }
10121043
10131044 gchar * cased_reversed = g_utf8_strreverse (cased , -1 );
1014- hit = g_pattern_spec_match (data -> filename_glob_pattern , strlen (cased ), cased , cased_reversed );
1045+ gsize len = strlen (cased );
1046+
1047+ hit = TRUE;
1048+ for (GList * l = data -> filename_glob_patterns ; l != NULL ; l = l -> next ) {
1049+ GPatternSpec * pattern = l -> data ;
1050+ if (!g_pattern_spec_match (pattern , len , cased , cased_reversed )) {
1051+ hit = FALSE;
1052+ break ;
1053+ }
1054+ }
1055+
10151056 g_free (cased );
10161057 g_free (cased_reversed );
10171058 }
0 commit comments