matcher: Add a "every" and "every_any" sections to the rules.

So far the "any" rules had a "OR" and "NOT" logic "gates", but not
an "AND".
This commit is contained in:
Emmanuel Lepage Vallee 2019-07-21 22:05:45 -04:00
parent 3e4f292906
commit b40083780e
2 changed files with 55 additions and 13 deletions

View File

@ -2,8 +2,6 @@
--- A table which content will be used to set the target object properties. --- A table which content will be used to set the target object properties.
-- --
-- foo
--
-- @rulecomponent properties -- @rulecomponent properties
-- @param table -- @param table
-- @see callbacks -- @see callbacks
@ -45,6 +43,13 @@
-- @see rule -- @see rule
-- @see except -- @see except
--- Matches when one of every "category" of components match.
--
-- @rulecomponent rule_every
-- @param table
-- @see rule
-- @see except
--- An identifier for this rule. --- An identifier for this rule.
-- --
-- It can be anything. It will be compared with the `==` operator. Strings are -- It can be anything. It will be compared with the `==` operator. Strings are

View File

@ -25,6 +25,8 @@
-- --
-- @DOC_text_gears_matcher_default_EXAMPLE@ -- @DOC_text_gears_matcher_default_EXAMPLE@
-- --
-- @DOC_text_gears_matcher_types_EXAMPLE@
--
-- More examples are available in `awful.rules`. -- More examples are available in `awful.rules`.
-- --
-- @author Julien Danjou <julien@danjou.info> -- @author Julien Danjou <julien@danjou.info>
@ -101,29 +103,63 @@ function matcher:_match(o, rule)
return true return true
end end
local function field_matcher(self, o, field, value)
local pm = self._private.prop_matchers[field]
if pm and pm(o, value, field) then
return true
elseif o[field] == value then
return true
elseif type(o[field]) == "string" and o[field]:match(value) then
return true
end
return false
end
-- Check if an object matches any part of a rule. -- Check if an object matches any part of a rule.
-- @param o The object. -- @param o The object.
-- #tparam table rule The rule to check. -- #tparam table rule The rule _match_anyto check.
-- @treturn boolean True if at least one rule is matched, false otherwise. -- @treturn boolean True if at least one rule is matched, false otherwise.
function matcher:_match_any(o, rule) function matcher:_match_any(o, rule)
if not rule then return false end if not rule then return false end
for field, values in pairs(rule) do for field, values in pairs(rule) do
if o[field] then if o[field] then
for _, value in ipairs(values) do for _, value in ipairs(values) do
local pm = self._private.prop_matchers[field] if field_matcher(self, o, field, value) then return true end
if pm and pm(o, value, field) then
return true
elseif o[field] == value then
return true
elseif type(o[field]) == "string" and o[field]:match(value) then
return true
end
end end
end end
end end
return false return false
end end
-- Check if an object matches at least one of every part of a rule.
--
-- @param o The object.
-- @tparam table rule The rule _match_anyto check.
-- @tparam boolean multi If the entries are table of choices.
-- @treturn boolean True if all rules are matched.
function matcher:_match_every(o, rule)
if not rule then return true end
for field, values in pairs(rule) do
local found = false
for _, value in ipairs(values) do
if not field_matcher(self, o, field, value) then
found = true
break
end
end
if not found then
return false
end
end
return true
end
--- Does a given rule entry match an object? --- Does a given rule entry match an object?
-- @param o The object. -- @param o The object.
-- @tparam table entry Rule entry (with keys `rule`, `rule_any`, `except` and/or -- @tparam table entry Rule entry (with keys `rule`, `rule_any`, `except` and/or
@ -133,8 +169,9 @@ end
function matcher:matches_rule(o, entry) function matcher:matches_rule(o, entry)
local match = self:_match(o, entry.rule) or self:_match_any(o, entry.rule_any) local match = self:_match(o, entry.rule) or self:_match_any(o, entry.rule_any)
return match return match
and (not self:_match(o, entry.except)) and self:_match_every (o, entry.rule_every)
and (not self:_match_any(o, entry.except_any)) and (not self:_match (o, entry.except ))
and (not self:_match_any (o, entry.except_any))
end end
--- Get list of matching rules for an object. --- Get list of matching rules for an object.