From f9b4e8c0a31d38fb48ee0e61e17a9534f00fdd82 Mon Sep 17 00:00:00 2001 From: Milan Svoboda Date: Tue, 25 Nov 2014 21:43:18 +0100 Subject: implement filter_inode_type --- doc/ranger.pod | 8 ++++++++ ranger/config/commands.py | 26 ++++++++++++++++++++++++++ ranger/container/directory.py | 26 +++++++++++++++++--------- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/doc/ranger.pod b/doc/ranger.pod index 370bbb85..d6a6a5b0 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -817,6 +817,7 @@ ranger. For your convenience, this is a list of the "public" commands including edit [filename] eval [-q] python_code filter [string] + filter_inode_type [dfl] find pattern grep pattern load_copy_buffer @@ -955,6 +956,13 @@ this command without any parameter will reset the fitler. This command is based on the I command and supports all of its options. +=item filter_inode_type [dfl] + +Displays only the files of specified inode type. To display only directories, +use the 'd' parameter. To display only files, use the 'f' parameter. To display +only links, use the 'l' parameter. Parameters can be combined. To remove this +filter, use no parameter. + =item find I Search files in the current directory that contain the given (case-insensitive) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 953e2cc3..6e641219 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1281,3 +1281,29 @@ class flat(Command): self.fm.thisdir.flat = level self.fm.thisdir.load_content() + +class filter_inode_type(Command): + """ + :filter_inode_type [dfl] + + Displays only the files of specified inode type. Parameters + can be combined. + + d display directories + f display files + l display links + """ + + FILTER_DIRS = 'd' + FILTER_FILES = 'f' + FILTER_LINKS = 'l' + + def execute(self): + if not self.arg(1): + self.fm.thisdir.inode_type_filter = None + else: + self.fm.thisdir.inode_type_filter = lambda file: ( + True if ((self.FILTER_DIRS in self.arg(1) and file.is_directory) or + (self.FILTER_FILES in self.arg(1) and file.is_file and not file.is_link) or + (self.FILTER_LINKS in self.arg(1) and file.is_link)) else False) + self.fm.thisdir.refilter() diff --git a/ranger/container/directory.py b/ranger/container/directory.py index c6987a76..17cc90b7 100644 --- a/ranger/container/directory.py +++ b/ranger/container/directory.py @@ -36,13 +36,18 @@ def sort_naturally(path): def sort_naturally_icase(path): return path.basename_natural_lower -def accept_file(fname, directory, hidden_filter, name_filter): - if hidden_filter and hidden_filter.search(fname): - return False - if name_filter and not name_filter.search(fname): - return False - if directory.temporary_filter and not directory.temporary_filter.search(fname): - return False +def accept_file(file, filters): + """ + Returns True if file shall be shown, otherwise False. + Parameters: + file - an instance of FileSystemObject + filters - an array of lambdas, each expects a file and + returns True if file shall be shown, + otherwise False. + """ + for filter in filters: + if filter and not filter(file): + return False return True class Directory(FileSystemObject, Accumulator, Loadable): @@ -59,6 +64,7 @@ class Directory(FileSystemObject, Accumulator, Loadable): files_all = None filter = None temporary_filter = None + inode_type_filter = None marked_items = None scroll_begin = 0 @@ -178,8 +184,10 @@ class Directory(FileSystemObject, Accumulator, Loadable): else: hidden_filter = None - self.files = [f for f in self.files_all if accept_file( - f.basename, self, hidden_filter, self.filter)] + filters = [(lambda file: not hidden_filter.search(file.basename)) if hidden_filter else None, + (lambda file: self.filter.search(file.basename)) if self.filter else None, + self.inode_type_filter] + self.files = [f for f in self.files_all if accept_file(f, filters)] self.move_to_obj(self.pointed_obj) # XXX: Check for possible race conditions -- cgit 1.4.1-2-gfad0