diff options
Diffstat (limited to 'src/filtering.c')
-rw-r--r-- | src/filtering.c | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/src/filtering.c b/src/filtering.c index b7597a2f2..fe0f76cb8 100644 --- a/src/filtering.c +++ b/src/filtering.c @@ -26,6 +26,7 @@ #include "compat/reallocarray.h" #include "ui/ui.h" #include "utils/dynarray.h" +#include "utils/matcher.h" #include "utils/path.h" #include "utils/regexp.h" #include "utils/str.h" @@ -38,6 +39,7 @@ static void reset_filter(filter_t *filter); static int is_newly_filtered(FileView *view, const dir_entry_t *entry, void *arg); +static void replace_matcher(matcher_t **matcher, const char expr[]); static int file_is_filtered(FileView *view, const char filename[], int is_dir, int apply_local_filter); static int get_unfiltered_pos(const FileView *const view, int pos); @@ -61,7 +63,7 @@ filters_view_reset(FileView *view) view->prev_invert = view->invert; (void)replace_string(&view->prev_manual_filter, ""); - reset_filter(&view->manual_filter); + replace_matcher(&view->manual_filter, ""); (void)replace_string(&view->prev_auto_filter, ""); reset_filter(&view->auto_filter); @@ -220,7 +222,8 @@ remove_filename_filter(FileView *view) return; } - (void)replace_string(&view->prev_manual_filter, view->manual_filter.raw); + (void)replace_string(&view->prev_manual_filter, + matcher_get_expr(view->manual_filter)); (void)replace_string(&view->prev_auto_filter, view->auto_filter.raw); view->prev_invert = view->invert; @@ -233,7 +236,7 @@ remove_filename_filter(FileView *view) int filename_filter_is_empty(FileView *view) { - return filter_is_empty(&view->manual_filter) + return matcher_is_empty(view->manual_filter) && filter_is_empty(&view->auto_filter); } @@ -241,7 +244,7 @@ void filename_filter_clear(FileView *view) { filter_clear(&view->auto_filter); - filter_clear(&view->manual_filter); + replace_matcher(&view->manual_filter, ""); view->invert = 1; } @@ -253,12 +256,25 @@ restore_filename_filter(FileView *view) return; } - (void)filter_set(&view->manual_filter, view->prev_manual_filter); + replace_matcher(&view->manual_filter, view->prev_manual_filter); + (void)filter_set(&view->auto_filter, view->prev_auto_filter); view->invert = view->prev_invert; ui_view_schedule_reload(view); } +/* Changes *matcher to have the value of the expr. The operation is assumed to + * succeed, but it's not guaranteed. */ +static void +replace_matcher(matcher_t **matcher, const char expr[]) +{ + char *error; + + matcher_free(*matcher); + *matcher = matcher_alloc(expr, FILTER_DEF_CASE_SENSITIVITY, 0, "", &error); + free(error); +} + void toggle_filter_inversion(FileView *view) { @@ -288,6 +304,8 @@ file_is_filtered(FileView *view, const char filename[], int is_dir, { /* FIXME: some very long file names won't be matched against some regexps. */ char name_with_slash[NAME_MAX + 1 + 1]; + char path[PATH_MAX + sizeof(name_with_slash)]; + if(is_dir) { append_slash(filename, name_with_slash, sizeof(name_with_slash)); @@ -305,19 +323,22 @@ file_is_filtered(FileView *view, const char filename[], int is_dir, return 0; } - if(filter_is_empty(&view->manual_filter)) + if(matcher_is_empty(view->manual_filter)) { return 1; } - if(filter_matches(&view->manual_filter, filename) > 0) + if(matcher_is_full_path(view->manual_filter)) { - return !view->invert; - } - else - { - return view->invert; + const size_t nchars = copy_str(path, sizeof(path) - 1, view->curr_dir); + path[nchars - 1U] = '/'; + copy_str(path + nchars, sizeof(path) - nchars, filename); + filename = path; } + + return matcher_matches(view->manual_filter, filename) + ? !view->invert + : view->invert; } void |