Merge pull request #2600 from Elv13/extract_rules
Extract the awful.rules logic into a gears module
This commit is contained in:
commit
df0cdbed61
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
|
||||
--- A table which content will be used to set the target object properties.
|
||||
--
|
||||
-- foo
|
||||
--
|
||||
-- @rulecomponent properties
|
||||
-- @param table
|
||||
-- @see callbacks
|
||||
|
||||
--TODO add ^
|
||||
-- @DOC_text_gears_matcher_properties_EXAMPLE@
|
||||
|
||||
--- A list of callback function to call *after* the properties have been apploed.
|
||||
-- @rulecomponent callbacks
|
||||
-- @param table
|
||||
-- @see properties
|
||||
|
||||
--- A table which content will be compared to the target object current properties.
|
||||
--
|
||||
-- @rulecomponent rule
|
||||
-- @param table
|
||||
-- @see rule_any
|
||||
-- @see except
|
||||
|
||||
--- Similar to `rule`, but each entry is a table with multiple values.
|
||||
--
|
||||
--
|
||||
-- @rulecomponent rule_any
|
||||
-- @param table
|
||||
-- @see rule
|
||||
-- @see except_any
|
||||
|
||||
--- The negative equivalent of `rule`.
|
||||
--
|
||||
-- @rulecomponent except
|
||||
-- @param table
|
||||
-- @see rule
|
||||
-- @see except_any
|
||||
|
||||
--- The negative equivalent of `rule_any`.
|
||||
--
|
||||
-- @rulecomponent except_any
|
||||
-- @param table
|
||||
-- @see rule
|
||||
-- @see except
|
|
@ -71,8 +71,10 @@ new_type("clientlayout", "Client layouts", false, "param")
|
|||
new_type("sourcefunction", "List source functions", false)
|
||||
-- Document some callback prototypes
|
||||
new_type("callback", "Callback functions prototype", false, "Parameters")
|
||||
-- awful.rules sources
|
||||
-- gears.matcher / awful.rules sources
|
||||
new_type("rulesources", "Rule sources", false, "param")
|
||||
-- gears.matcher / awful.rules rule components
|
||||
new_type("rulecomponent", "Rule components", false, "Type")
|
||||
-- Filter functions for the taglist/tasklist/layoutlist
|
||||
new_type("filterfunction", "List filters", false)
|
||||
-- Extra client properties available only in awful.rules/spawn constructs
|
||||
|
@ -120,6 +122,7 @@ file = {
|
|||
'../lib/awful/init.lua',
|
||||
'../lib/awful/remote.lua',
|
||||
'../lib/awful/startup_notification.lua',
|
||||
'../lib/awful/mouse/drag_to_tag.lua',
|
||||
'../lib/gears/init.lua',
|
||||
'../lib/wibox/layout/init.lua',
|
||||
'../lib/wibox/container/init.lua',
|
||||
|
|
|
@ -43,7 +43,7 @@ end
|
|||
|
||||
--- Give focus on tag selection change.
|
||||
--
|
||||
-- @param tag A tag object
|
||||
-- @tparam tag t A tag object
|
||||
local function check_focus_tag(t)
|
||||
local s = t.screen
|
||||
if (not s) or (not s.valid) then return end
|
||||
|
|
|
@ -119,8 +119,8 @@ local gtable = require("gears.table")
|
|||
local a_place = require("awful.placement")
|
||||
local protected_call = require("gears.protected_call")
|
||||
local aspawn = require("awful.spawn")
|
||||
local gsort = require("gears.sort")
|
||||
local gdebug = require("gears.debug")
|
||||
local gmatcher = require("gears.matcher")
|
||||
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
||||
|
||||
local rules = {}
|
||||
|
@ -128,26 +128,14 @@ local rules = {}
|
|||
--- This is the global rules table.
|
||||
rules.rules = {}
|
||||
|
||||
local crules = gmatcher()
|
||||
|
||||
--- Check if a client matches a rule.
|
||||
-- @client c The client.
|
||||
-- @tab rule The rule to check.
|
||||
-- @treturn bool True if it matches, false otherwise.
|
||||
function rules.match(c, rule)
|
||||
if not rule then return false end
|
||||
for field, value in pairs(rule) do
|
||||
if c[field] then
|
||||
if type(c[field]) == "string" then
|
||||
if not c[field]:match(value) and c[field] ~= value then
|
||||
return false
|
||||
end
|
||||
elseif c[field] ~= value then
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
return crules:_match(c, rule)
|
||||
end
|
||||
|
||||
--- Check if a client matches any part of a rule.
|
||||
|
@ -155,19 +143,7 @@ end
|
|||
-- @tab rule The rule to check.
|
||||
-- @treturn bool True if at least one rule is matched, false otherwise.
|
||||
function rules.match_any(c, rule)
|
||||
if not rule then return false end
|
||||
for field, values in pairs(rule) do
|
||||
if c[field] then
|
||||
for _, value in ipairs(values) do
|
||||
if c[field] == value then
|
||||
return true
|
||||
elseif type(c[field]) == "string" and c[field]:match(value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
return crules:_match_any(c, rule)
|
||||
end
|
||||
|
||||
--- Does a given rule entry match a client?
|
||||
|
@ -176,8 +152,7 @@ end
|
|||
-- `except_any`).
|
||||
-- @treturn bool
|
||||
function rules.matches(c, entry)
|
||||
return (rules.match(c, entry.rule) or rules.match_any(c, entry.rule_any)) and
|
||||
(not rules.match(c, entry.except) and not rules.match_any(c, entry.except_any))
|
||||
return crules:matches_rule(c, entry)
|
||||
end
|
||||
|
||||
--- Get list of matching rules for a client.
|
||||
|
@ -186,13 +161,7 @@ end
|
|||
-- "except_any" keys.
|
||||
-- @treturn table The list of matched rules.
|
||||
function rules.matching_rules(c, _rules)
|
||||
local result = {}
|
||||
for _, entry in ipairs(_rules) do
|
||||
if (rules.matches(c, entry)) then
|
||||
table.insert(result, entry)
|
||||
end
|
||||
end
|
||||
return result
|
||||
return crules:matching_rules(c, _rules)
|
||||
end
|
||||
|
||||
--- Check if a client matches a given set of rules.
|
||||
|
@ -201,22 +170,22 @@ end
|
|||
-- `except` and `except_any` keys.
|
||||
-- @treturn bool True if at least one rule is matched, false otherwise.
|
||||
function rules.matches_list(c, _rules)
|
||||
for _, entry in ipairs(_rules) do
|
||||
if (rules.matches(c, entry)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
return crules:matches_rules(c, _rules)
|
||||
end
|
||||
|
||||
--- Remove a source.
|
||||
-- @tparam string name The source name.
|
||||
-- @treturn boolean If the source was removed,
|
||||
function rules.remove_rule_source(name)
|
||||
return crules:remove_matching_source(name)
|
||||
end
|
||||
|
||||
|
||||
-- Contains the sources.
|
||||
-- The elements are ordered "first in, first executed". Thus, the higher the
|
||||
-- index, the higher the priority. Each entry is a table with a `name` and a
|
||||
-- `callback` field. This table is exposed for debugging purpose. The API
|
||||
-- is private and should be modified using the public accessors.
|
||||
local rule_sources = {}
|
||||
local rule_source_sort = gsort.topological()
|
||||
--- Apply awful.rules.rules to a client.
|
||||
-- @client c The client.
|
||||
function rules.apply(c)
|
||||
return crules:apply(c)
|
||||
end
|
||||
|
||||
--- Add a new rule source.
|
||||
--
|
||||
|
@ -257,73 +226,13 @@ local rule_source_sort = gsort.topological()
|
|||
-- @tparam[opt={}] table precede A list of names of sources this source have a
|
||||
-- priority over.
|
||||
-- @treturn boolean Returns false if a dependency conflict was found.
|
||||
function rules.add_rule_source(name, callback, depends_on, precede)
|
||||
depends_on = depends_on or {}
|
||||
precede = precede or {}
|
||||
assert(type( depends_on ) == "table")
|
||||
assert(type( precede ) == "table")
|
||||
-- @function awful.rules.add_rule_source
|
||||
|
||||
for _, v in ipairs(rule_sources) do
|
||||
-- Names must be unique
|
||||
assert(
|
||||
v.name ~= name,
|
||||
"Name must be unique, but '" .. name .. "' was already registered."
|
||||
)
|
||||
function rules.add_rule_source(name, cb, ...)
|
||||
local function callback(_, ...)
|
||||
cb(...)
|
||||
end
|
||||
|
||||
local new_sources = rule_source_sort:clone()
|
||||
|
||||
new_sources:prepend(name, precede )
|
||||
new_sources:append (name, depends_on )
|
||||
|
||||
local res, err = new_sources:sort()
|
||||
|
||||
if err then
|
||||
gdebug.print_warning("Failed to add the rule source: "..err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Only replace the source once the additions have been proven safe
|
||||
rule_source_sort = new_sources
|
||||
|
||||
local callbacks = {}
|
||||
|
||||
-- Get all callbacks for *existing* sources.
|
||||
-- It is important to remember that names can be used in the sorting even
|
||||
-- if the source itself doesn't (yet) exists.
|
||||
for _, v in ipairs(rule_sources) do
|
||||
callbacks[v.name] = v.callback
|
||||
end
|
||||
|
||||
rule_sources = {}
|
||||
callbacks[name] = callback
|
||||
|
||||
for _, v in ipairs(res) do
|
||||
if callbacks[v] then
|
||||
table.insert(rule_sources, 1, {
|
||||
callback = callbacks[v],
|
||||
name = v
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Remove a source.
|
||||
-- @tparam string name The source name.
|
||||
-- @treturn boolean If the source was removed
|
||||
function rules.remove_rule_source(name)
|
||||
rule_source_sort:remove(name)
|
||||
|
||||
for k, v in ipairs(rule_sources) do
|
||||
if v.name == name then
|
||||
table.remove(rule_sources, k)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
return crules:add_matching_function(name, callback, ...)
|
||||
end
|
||||
|
||||
-- Add the rules properties
|
||||
|
@ -414,17 +323,6 @@ end
|
|||
|
||||
rules.add_rule_source("awful.spawn_once", apply_singleton_rules, {"awful.spawn"}, {"awful.rules"})
|
||||
|
||||
--- Apply awful.rules.rules to a client.
|
||||
-- @client c The client.
|
||||
function rules.apply(c)
|
||||
local callbacks, props = {}, {}
|
||||
for _, v in ipairs(rule_sources) do
|
||||
v.callback(c, props, callbacks)
|
||||
end
|
||||
|
||||
rules.execute(c, props, callbacks)
|
||||
end
|
||||
|
||||
local function add_to_tag(c, t)
|
||||
if not t then return end
|
||||
|
||||
|
@ -621,7 +519,9 @@ end
|
|||
-- @client c The client.
|
||||
-- @tab props Properties to apply.
|
||||
-- @tab[opt] callbacks Callbacks to apply.
|
||||
function rules.execute(c, props, callbacks)
|
||||
-- @function awful.rules.execute
|
||||
|
||||
crules._execute = function(_, c, props, callbacks)
|
||||
-- This has to be done first, as it will impact geometry related props.
|
||||
if props.titlebars_enabled and (type(props.titlebars_enabled) ~= "function"
|
||||
or props.titlebars_enabled(c,props)) then
|
||||
|
@ -734,6 +634,8 @@ function rules.execute(c, props, callbacks)
|
|||
end
|
||||
end
|
||||
|
||||
function rules.execute(...) crules:_execute(...) end
|
||||
|
||||
-- TODO v5 deprecate this
|
||||
function rules.completed_with_payload_callback(c, props, callbacks)
|
||||
rules.execute(c, props, callbacks)
|
||||
|
@ -741,6 +643,8 @@ end
|
|||
|
||||
client.connect_signal("manage", rules.apply)
|
||||
|
||||
--@DOC_rule_COMMON@
|
||||
|
||||
return rules
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
|
@ -0,0 +1,318 @@
|
|||
--- A module to build a set of properties based on a graph of rules.
|
||||
--
|
||||
-- Sources
|
||||
-- =======
|
||||
--
|
||||
-- This module holds the business logic used by `awful.rules`. It provides an
|
||||
-- object on which one can add sets of rules or, alternatively, functions.
|
||||
-- In this module, the sets of rules or custom functions are called sources.
|
||||
--
|
||||
-- The sources are used to build a property table. Once all sources are
|
||||
-- evaluated, the `:apply()` method will set the properties on the target
|
||||
-- object.
|
||||
--
|
||||
-- Sources can have dependencies between them and the property table can only
|
||||
-- be built if the sources graph can be resolved.
|
||||
--
|
||||
-- Rules
|
||||
-- =====
|
||||
--
|
||||
-- The `rules` sources themselves are composed, as the name imply, of a set of
|
||||
-- rule. A rule is a table with a `properties` *or* `callbacks` attribute along
|
||||
-- with either `rule` or `rule_any`. It is also possible to add an `except` or
|
||||
-- `except_any` attribute to narrow the scope in which the rule is applied.
|
||||
-- Here's a basic example of a minimal `gears.matcher`.
|
||||
--
|
||||
-- @DOC_text_gears_matcher_default_EXAMPLE@
|
||||
--
|
||||
-- More examples are available in `awful.rules`.
|
||||
--
|
||||
-- @author Julien Danjou <julien@danjou.info>
|
||||
-- @copyright 2009 Julien Danjou
|
||||
-- @see awful.rules
|
||||
-- @module gears.matcher
|
||||
|
||||
local gtable = require("gears.table")
|
||||
local gsort = require("gears.sort")
|
||||
local gdebug = require("gears.debug")
|
||||
local protected_call = require("gears.protected_call")
|
||||
|
||||
local matcher = {}
|
||||
|
||||
-- Check if an object matches a rule.
|
||||
-- @param o The object.
|
||||
-- #tparam table rule The rule to check.
|
||||
-- @treturn boolean True if it matches, false otherwise.
|
||||
function matcher:_match(o, rule)
|
||||
if not rule then return false end
|
||||
for field, value in pairs(rule) do
|
||||
if o[field] then
|
||||
if type(o[field]) == "string" then
|
||||
if not o[field]:match(value) and o[field] ~= value then
|
||||
return false
|
||||
end
|
||||
elseif o[field] ~= value then
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check if an object matches any part of a rule.
|
||||
-- @param o The object.
|
||||
-- #tparam table rule The rule to check.
|
||||
-- @treturn boolean True if at least one rule is matched, false otherwise.
|
||||
function matcher:_match_any(o, rule)
|
||||
if not rule then return false end
|
||||
for field, values in pairs(rule) do
|
||||
if o[field] then
|
||||
for _, value in ipairs(values) do
|
||||
if o[field] == value then
|
||||
return true
|
||||
elseif type(o[field]) == "string" and o[field]:match(value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Does a given rule entry match an object?
|
||||
-- @param o The object.
|
||||
-- @tparam table entry Rule entry (with keys `rule`, `rule_any`, `except` and/or
|
||||
-- `except_any`).
|
||||
-- @treturn boolean If `o` matches `entry`.
|
||||
function matcher:matches_rule(o, entry)
|
||||
local match = self:_match(o, entry.rule) or self:_match_any(o, entry.rule_any)
|
||||
return match
|
||||
and (not self:_match(o, entry.except))
|
||||
and (not self:_match_any(o, entry.except_any))
|
||||
end
|
||||
|
||||
--- Get list of matching rules for an object.
|
||||
--
|
||||
-- If the `rules` argument is not provided, the rules added with
|
||||
-- `add_matching_rules` will be used.
|
||||
--
|
||||
-- @param o The object.
|
||||
-- @tparam[opt=nil] table rules The rules to check. List with "rule", "rule_any",
|
||||
-- "except" and "except_any" keys.
|
||||
-- @treturn table The list of matched rules.
|
||||
function matcher:matching_rules(o, rules)
|
||||
local result = {}
|
||||
for _, entry in ipairs(rules) do
|
||||
if self:matches_rule(o, entry) then
|
||||
table.insert(result, entry)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--- Check if an object matches a given set of rules.
|
||||
-- @param o The object.
|
||||
-- @tparam table rules The rules to check. List of tables with `rule`,
|
||||
-- `rule_any`, `except` and `except_any` keys.
|
||||
-- @treturn boolean True if at least one rule is matched, false otherwise.
|
||||
function matcher:matches_rules(o, rules)
|
||||
for _, entry in ipairs(rules) do
|
||||
if self:matches_rule(o, entry) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function default_rules_callback(self, o, props, callbacks, rules)
|
||||
for _, entry in ipairs(self:matching_rules(o, rules)) do
|
||||
gtable.crush(props, entry.properties or {})
|
||||
|
||||
if entry.callback then
|
||||
table.insert(callbacks, entry.callback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Add a set of matching rules.
|
||||
--
|
||||
-- @tparam string name The provider name. It must be unique.
|
||||
-- @tparam table rules A set of rules (see how they work at the top of this
|
||||
-- page).
|
||||
-- @tparam[opt={}] table depends_on A list of names of sources this source
|
||||
-- depends on (sources that must be executed *before* `name`).
|
||||
-- @tparam[opt={}] table precede A list of names of sources this source has a
|
||||
-- priority over.
|
||||
-- @treturn boolean Returns false if a dependency conflict was found.
|
||||
function matcher:add_matching_rules(name, rules, depends_on, precede)
|
||||
local function matching_fct(_self, c, props, callbacks)
|
||||
default_rules_callback(_self, c, props, callbacks, rules)
|
||||
end
|
||||
|
||||
self._matching_rules[name] = rules
|
||||
|
||||
return self:add_matching_function(name, matching_fct, depends_on, precede)
|
||||
end
|
||||
|
||||
--- Add a matching function.
|
||||
--
|
||||
-- @tparam string name The provider name. It must be unique.
|
||||
-- @tparam function callback The callback that is called to produce properties.
|
||||
-- @tparam gears.matcher callback.self The matcher object.
|
||||
-- @param callback.o The object.
|
||||
-- @tparam table callback.properties The current properties. The callback should
|
||||
-- add to and overwrite properties in this table.
|
||||
-- @tparam table callback.callbacks A table of all callbacks scheduled to be
|
||||
-- executed after the main properties are applied.
|
||||
-- @tparam[opt={}] table depends_on A list of names of sources this source depends on
|
||||
-- (sources that must be executed *before* `name`).
|
||||
-- @tparam[opt={}] table precede A list of names of sources this source has a
|
||||
-- priority over.
|
||||
-- @treturn boolean Returns false if a dependency conflict was found.
|
||||
function matcher:add_matching_function(name, callback, depends_on, precede)
|
||||
depends_on = depends_on or {}
|
||||
precede = precede or {}
|
||||
assert(type( depends_on ) == "table")
|
||||
assert(type( precede ) == "table")
|
||||
|
||||
for _, v in ipairs(self._matching_source) do
|
||||
-- Names must be unique
|
||||
assert(
|
||||
v.name ~= name,
|
||||
"Name must be unique, but '" .. name .. "' was already registered."
|
||||
)
|
||||
end
|
||||
|
||||
local new_sources = self._rule_source_sort:clone()
|
||||
|
||||
new_sources:prepend(name, precede )
|
||||
new_sources:append (name, depends_on )
|
||||
|
||||
local res, err = new_sources:sort()
|
||||
|
||||
if err then
|
||||
gdebug.print_warning("Failed to add the rule source: "..err)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Only replace the source once the additions has been proven to be safe.
|
||||
self._rule_source_sort = new_sources
|
||||
|
||||
local callbacks = {}
|
||||
|
||||
-- Get all callbacks for *existing* sources.
|
||||
-- It is important to remember that names can be used in the sorting even
|
||||
-- if the source itself doesn't (yet) exist.
|
||||
for _, v in ipairs(self._matching_source) do
|
||||
callbacks[v.name] = v.callback
|
||||
end
|
||||
|
||||
self._matching_source = {}
|
||||
callbacks[name] = callback
|
||||
|
||||
for _, v in ipairs(res) do
|
||||
if callbacks[v] then
|
||||
table.insert(self._matching_source, 1, {
|
||||
callback = callbacks[v],
|
||||
name = v
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Remove a source.
|
||||
--
|
||||
-- This removes sources added with `add_matching_function` or
|
||||
-- `add_matching_rules`.
|
||||
--
|
||||
-- @tparam string name The source name.
|
||||
-- @treturn boolean If the source has been removed.
|
||||
function matcher:remove_matching_source(name)
|
||||
self._rule_source_sort:remove(name)
|
||||
|
||||
for k, v in ipairs(self._matching_source) do
|
||||
if v.name == name then
|
||||
table.remove(self._matching_source, k)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
self._matching_rules[name] = nil
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
--- Apply awful.rules.rules to an object.
|
||||
--
|
||||
-- Calling this will apply all properties provided by the matching functions
|
||||
-- and rules.
|
||||
--
|
||||
-- @param o The object.
|
||||
function matcher:apply(o)
|
||||
local callbacks, props = {}, {}
|
||||
for _, v in ipairs(self._matching_source) do
|
||||
v.callback(self, o, props, callbacks)
|
||||
end
|
||||
|
||||
self:_execute(o, props, callbacks)
|
||||
end
|
||||
|
||||
-- Execute the rules for the object `o`.
|
||||
-- @param o The object.
|
||||
-- @tparam table props A list of properties to apply.
|
||||
-- @tparam table callbacks A list of callback to execute with the object `o` as
|
||||
-- sole argument. The callbacks are executed *before* applying the properties.
|
||||
-- @see gears.matcher.apply
|
||||
function matcher:_execute(o, props, callbacks)
|
||||
-- Apply all callbacks.
|
||||
if callbacks then
|
||||
for _, callback in pairs(callbacks) do
|
||||
protected_call(callback, o)
|
||||
end
|
||||
end
|
||||
|
||||
for property, value in pairs(props) do
|
||||
if type(value) == "function" then
|
||||
value = value(o, props)
|
||||
end
|
||||
|
||||
if type(o[property]) == "function" then
|
||||
o[property](o, value)
|
||||
else
|
||||
o[property] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local module = {}
|
||||
|
||||
--- Create a new rule solver object.
|
||||
-- @function gears.matcher
|
||||
-- @return A new rule solver object.
|
||||
|
||||
local function new()
|
||||
local ret = {}
|
||||
|
||||
-- Contains the sources.
|
||||
-- The elements are ordered "first in, first executed". Thus, the higher the
|
||||
-- index, the higher the priority. Each entry is a table with a `name` and a
|
||||
-- `callback` field. This table is exposed for debugging purpose. The API
|
||||
-- is private and should only be modified using the public accessors.
|
||||
ret._matching_source = {}
|
||||
ret._rule_source_sort = gsort.topological()
|
||||
ret._matching_rules = {}
|
||||
|
||||
gtable.crush(ret, matcher, true)
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
--@DOC_rule_COMMON@
|
||||
|
||||
--@DOC_object_COMMON@
|
||||
|
||||
return setmetatable(module, {__call = new})
|
|
@ -0,0 +1,80 @@
|
|||
--DOC_HIDE --DOC_NO_USAGE --DOC_GEN_OUTPUT
|
||||
local gears = {matcher = require("gears.matcher")} --DOC_HIDE
|
||||
|
||||
local o = {
|
||||
foo = "bar",
|
||||
answer = 42,
|
||||
}
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
-- This rule will match
|
||||
local rule1 = {
|
||||
rule = {
|
||||
answer = 42,
|
||||
},
|
||||
properties = {
|
||||
name = "baz",
|
||||
},
|
||||
}
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
-- This rule will **not** match
|
||||
local rule2 = {
|
||||
-- When the rule properties are strings, the Lua
|
||||
--pattern matching is used.
|
||||
rule = {
|
||||
foo = "[f]+",
|
||||
},
|
||||
properties = {
|
||||
name = "foobar",
|
||||
},
|
||||
}
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
local rules = {
|
||||
rule1,
|
||||
rule2,
|
||||
}
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
local matcher = gears.matcher()
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
local function first_source(self, object, props, callbacks) --luacheck: no unused args
|
||||
assert(self:matching_rules(object, rules)[1] == rule1) --DOC_HIDE
|
||||
assert(#self:matching_rules(object, rules) == 1) --DOC_HIDE
|
||||
assert(self:matches_rule(object, rule1)) --DOC_HIDE
|
||||
assert(not self:matches_rule(object, rule2)) --DOC_HIDE
|
||||
|
||||
-- In this callback, you can add new elements to the props and
|
||||
-- callbacks tables. It is not recommended the modify `object` in
|
||||
-- this callback.
|
||||
if object.answer == 42 then
|
||||
props.is_everything = true
|
||||
end
|
||||
end
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
-- This will add a custom function to add properties to the rules.
|
||||
matcher:add_matching_function("first", first_source, {}, {})
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
-- This will add the `rules` to this matcher.
|
||||
matcher:add_matching_rules("second", rules, {"first"}, {})
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
-- Apply the properties to `o`
|
||||
matcher:apply(o)
|
||||
|
||||
assert(o.is_everything) --DOC_HIDE
|
||||
assert(o.name == "baz") --DOC_HIDE
|
||||
matcher:remove_matching_source("first") --DOC_HIDE
|
||||
matcher:remove_matching_source("second") --DOC_HIDE
|
|
@ -0,0 +1,24 @@
|
|||
--DOC_HIDE
|
||||
local gears = {matcher = require("gears.matcher")} --DOC_HIDE
|
||||
|
||||
local o = { --DOC_HIDE
|
||||
foo = "bar", --DOC_HIDE
|
||||
answer = 42, --DOC_HIDE
|
||||
} --DOC_HIDE
|
||||
|
||||
local rules = {
|
||||
{
|
||||
rule = {
|
||||
answer = 42,
|
||||
},
|
||||
properties = {
|
||||
name = "baz",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
--DOC_NEWLINE
|
||||
|
||||
local matcher = gears.matcher()--DOC_HIDE
|
||||
matcher:add_matching_rules("second", rules, {"first"}, {}) --DOC_HIDE
|
||||
matcher:apply(o) --DOC_HIDE
|
Loading…
Reference in New Issue