dotfiles from arch
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
local m = require 'lpeglabel'
|
||||
local matcher = require 'glob.matcher'
|
||||
|
||||
local function prop(name, pat)
|
||||
return m.Cg(m.Cc(true), name) * pat
|
||||
end
|
||||
|
||||
local function object(type, pat)
|
||||
return m.Ct(
|
||||
m.Cg(m.Cc(type), 'type') *
|
||||
m.Cg(pat, 'value')
|
||||
)
|
||||
end
|
||||
|
||||
local function expect(p, err)
|
||||
return p + m.T(err)
|
||||
end
|
||||
|
||||
local parser = m.P {
|
||||
'Main',
|
||||
['Sp'] = m.S(' \t')^0,
|
||||
['Slash'] = m.P('/')^1,
|
||||
['Main'] = m.Ct(m.V'Sp' * m.P'{' * m.V'Pattern' * (',' * expect(m.V'Pattern', 'Miss exp after ","'))^0 * m.P'}')
|
||||
+ m.Ct(m.V'Pattern')
|
||||
+ m.T'Main Failed'
|
||||
,
|
||||
['Pattern'] = m.Ct(m.V'Sp' * prop('neg', m.P'!') * expect(m.V'Unit', 'Miss exp after "!"'))
|
||||
+ m.Ct(m.V'Unit')
|
||||
,
|
||||
['NeedRoot'] = prop('root', (m.P'.' * m.V'Slash' + m.V'Slash')),
|
||||
['Unit'] = m.V'Sp' * m.V'NeedRoot'^-1 * expect(m.V'Exp', 'Miss exp') * m.V'Sp',
|
||||
['Exp'] = m.V'Sp' * (m.V'FSymbol' + object('/', m.V'Slash') + m.V'Word')^0 * m.V'Sp',
|
||||
['Word'] = object('word', m.Ct((m.V'CSymbol' + m.V'Char' - m.V'FSymbol')^1)),
|
||||
['CSymbol'] = object('*', m.P'*')
|
||||
+ object('?', m.P'?')
|
||||
+ object('[]', m.V'Range')
|
||||
,
|
||||
['SimpleChar'] = m.P(1) - m.S',{}[]*?/',
|
||||
['EscChar'] = m.P'\\' / '' * m.P(1),
|
||||
['Char'] = object('char', m.Cs((m.V'EscChar' + m.V'SimpleChar')^1)),
|
||||
['FSymbol'] = object('**', m.P'**'),
|
||||
['RangeWord'] = 1 - m.P']',
|
||||
['Range'] = m.P'[' * m.Ct(m.V'RangeUnit'^0) * m.P']'^-1,
|
||||
['RangeUnit'] = m.Ct(m.C(m.V'RangeWord') * m.P'-' * m.C(m.V'RangeWord'))
|
||||
+ m.V'RangeWord',
|
||||
}
|
||||
|
||||
local mt = {}
|
||||
mt.__index = mt
|
||||
mt.__name = 'glob'
|
||||
|
||||
function mt:addPattern(pat)
|
||||
if type(pat) ~= 'string' then
|
||||
return
|
||||
end
|
||||
self.pattern[#self.pattern+1] = pat
|
||||
if self.options.ignoreCase then
|
||||
pat = pat:lower()
|
||||
end
|
||||
local states, err = parser:match(pat)
|
||||
if not states then
|
||||
self.errors[#self.errors+1] = {
|
||||
pattern = pat,
|
||||
message = err
|
||||
}
|
||||
return
|
||||
end
|
||||
for _, state in ipairs(states) do
|
||||
if state.neg then
|
||||
self.refused[#self.refused+1] = matcher(state)
|
||||
else
|
||||
self.passed[#self.passed+1] = matcher(state)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function mt:setOption(op, val)
|
||||
if val == nil then
|
||||
val = true
|
||||
end
|
||||
self.options[op] = val
|
||||
end
|
||||
|
||||
function mt:__call(path)
|
||||
if self.options.ignoreCase then
|
||||
path = path:lower()
|
||||
end
|
||||
path = path:gsub('^[/\\]+', '')
|
||||
for _, refused in ipairs(self.refused) do
|
||||
if refused(path) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
for _, passed in ipairs(self.passed) do
|
||||
if passed(path) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return function (pattern, options)
|
||||
local self = setmetatable({
|
||||
pattern = {},
|
||||
options = {},
|
||||
passed = {},
|
||||
refused = {},
|
||||
errors = {},
|
||||
}, mt)
|
||||
|
||||
if type(pattern) == 'table' then
|
||||
for _, pat in ipairs(pattern) do
|
||||
self:addPattern(pat)
|
||||
end
|
||||
else
|
||||
self:addPattern(pattern)
|
||||
end
|
||||
|
||||
if type(options) == 'table' then
|
||||
for op, val in pairs(options) do
|
||||
self:setOption(op, val)
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
Reference in New Issue
Block a user