summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--doc/ranger.14
-rw-r--r--doc/ranger.pod6
-rw-r--r--ranger/config/rc.conf1
-rw-r--r--ranger/core/filter_stack.py20
4 files changed, 31 insertions, 0 deletions
diff --git a/doc/ranger.1 b/doc/ranger.1
index 8423d068..060686b8 100644
--- a/doc/ranger.1
+++ b/doc/ranger.1
@@ -672,6 +672,10 @@ Apply the typefilter \*(L"symlink\*(R".
 .IP ".|" 14
 Combine the two topmost filters from the filter stack in the \*(L"\s-1OR\*(R"\s0
 relationship, instead of the \*(L"\s-1AND\*(R"\s0 used implicitly.
+.IP ".&" 14
+Explicitly combine the two topmost filters in the \*(L"\s-1AND\*(R"\s0
+relationship. Usually not needed though might be useful in more
+complicated scenarios.
 .IP ".!" 14
 Negate the topmost filter.
 .IP ".r" 14
diff --git a/doc/ranger.pod b/doc/ranger.pod
index 6e7075a7..48e6a41e 100644
--- a/doc/ranger.pod
+++ b/doc/ranger.pod
@@ -641,6 +641,12 @@ Apply the typefilter "symlink".
 Combine the two topmost filters from the filter stack in the "OR"
 relationship, instead of the "AND" used implicitly.
 
+=item .&
+
+Explicitly combine the two topmost filters in the "AND"
+relationship. Usually not needed though might be useful in more
+complicated scenarios.
+
 =item .!
 
 Negate the topmost filter.
diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf
index 14706dce..b112dc2c 100644
--- a/ranger/config/rc.conf
+++ b/ranger/config/rc.conf
@@ -563,6 +563,7 @@ map .d filter_stack add type d
 map .f filter_stack add type f
 map .l filter_stack add type l
 map .| filter_stack add or
+map .& filter_stack add and
 map .! filter_stack add not
 map .r console filter_stack rotate
 map .c filter_stack clear
diff --git a/ranger/core/filter_stack.py b/ranger/core/filter_stack.py
index f5b00014..ff9f4080 100644
--- a/ranger/core/filter_stack.py
+++ b/ranger/core/filter_stack.py
@@ -98,6 +98,26 @@ class OrFilter(BaseFilter):
         return self.subfilters
 
 
+@filter_combinator("and")
+class AndFilter(BaseFilter):
+    def __init__(self, stack):
+        self.subfilters = [stack[-2], stack[-1]]
+
+        stack.pop()
+        stack.pop()
+
+        stack.append(self)
+
+    def __call__(self, fobj):
+        return accept_file(fobj, self.subfilters)
+
+    def __str__(self):
+        return "<Filter: {}>".format(" and ".join(map(str, self.subfilters)))
+
+    def decompose(self):
+        return self.subfilters
+
+
 @filter_combinator("not")
 class NotFilter(BaseFilter):
     def __init__(self, stack):