about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/ranger.pod8
-rw-r--r--ranger/config/commands.py27
-rw-r--r--ranger/container/directory.py26
3 files changed, 52 insertions, 9 deletions
diff --git a/doc/ranger.pod b/doc/ranger.pod
index c556c63c..211aea11 100644
--- a/doc/ranger.pod
+++ b/doc/ranger.pod
@@ -830,6 +830,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
  flat level
  grep pattern
@@ -990,6 +991,13 @@ this command without any parameter will reset the fitler.
 
 This command is based on the I<scout> 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<pattern>
 
 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 4e82fb0f..1f59ee90 100644
--- a/ranger/config/commands.py
+++ b/ranger/config/commands.py
@@ -1187,6 +1187,33 @@ class scout(Command):
         return count == 1
 
 
+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()
+
+
 class grep(Command):
     """:grep <string>
 
diff --git a/ranger/container/directory.py b/ranger/container/directory.py
index 7bef379d..7d39daaf 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
 
 def walklevel(some_dir, level):
@@ -78,6 +83,7 @@ class Directory(FileSystemObject, Accumulator, Loadable):
     files_all = None
     filter = None
     temporary_filter = None
+    inode_type_filter = None
     marked_items = None
     scroll_begin = 0
 
@@ -197,8 +203,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