Commit 2c5b7175 authored by Jacek Sowiński's avatar Jacek Sowiński

Much more powerful filtering of priorities

Now it is possible to do things like:

`ls (>C)`  # gives items with A-B priorities
`ls (<=D)` # gives items with D-Z priorities
`ls (!E)`  # gives all items except those with E priority (also possible
           # with `ls -- -(E)`

and maybe most importantly:
`ls (<Z)` # gives items without priority

PS Don't forget about escaping parentheses when calling from CLI
parent b207a64b
......@@ -53,6 +53,8 @@ class ExpressionCommand(Command):
for arg in args:
if re.match(Filter.ORDINAL_TAG_MATCH, arg):
argfilter = Filter.OrdinalTagFilter(arg)
elif re.match(Filter.PRIORITY_MATCH, arg):
argfilter = Filter.PriorityFilter(arg)
elif len(arg) > 1 and arg[0] == '-':
# when a word starts with -, exclude it
argfilter = Filter.GrepFilter(arg[1:])
......
......@@ -151,6 +151,8 @@ class LimitFilter(Filter):
def filter(self, p_todos):
return p_todos[:self.limit] if self.limit >= 0 else p_todos
OPERATOR_MATCH = r"(?P<operator><=?|=|>=?|!)?"
class OrdinalFilter(Filter):
"""
Base class for ordinal filters.
......@@ -189,7 +191,7 @@ class OrdinalFilter(Filter):
return False
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):(?P<operator><=?|=|>=?|!)?(?P<value>\S+)"
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):" + OPERATOR_MATCH + r"(?P<value>\S+)"
class OrdinalTagFilter(OrdinalFilter):
def __init__(self, p_expression):
......@@ -231,3 +233,24 @@ class OrdinalTagFilter(OrdinalFilter):
return self.compare_operands(operand1, operand2)
PRIORITY_MATCH = r"\(" + OPERATOR_MATCH + r"(?P<value>[A-Z]{1})\)"
class PriorityFilter(OrdinalFilter):
def __init__(self, p_expression):
super(PriorityFilter, self).__init__(p_expression, PRIORITY_MATCH)
def match(self, p_todo):
"""
Performs a match on a priority in the todo.
It gets priority from p_todo and compares it with user-entered
expression based on the given operator (default ==). It does that however
in reversed order to obtain more intuitive result. Example: (>B) will
match todos with priority (A).
Items without priority are designated with corresponding operand set to
'ZZ', because python doesn't allow NoneType() and str() comparisons.
"""
operand1 = self.value
operand2 = p_todo.priority() or 'ZZ'
return self.compare_operands(operand1, operand2)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment