bspwm/examples/external_rules/lua/ruld
2014-01-21 20:48:49 +01:00

135 lines
2.8 KiB
Lua
Executable file

#! /usr/bin/env lua
local p = require("posix")
local port = 54321
local short = "hp:"
local long = {
{"help", "none", 'h'},
{"port", "required", 'p'},
}
local rules = {}
for opt, optarg, optind, longind in p.getopt(arg, short, long) do
if opt == '?' then
print("Unrecognized option")
os.exit(1)
elseif opt == 'h' then
print("Usage: ruld [-h|-p PORT]")
os.exit(0)
elseif opt == 'p' then
port = optarg
end
end
function eval(exp, env)
local f
local value = "return " .. exp
if env then
f = load(value, nil, nil, env)
else
f = load(value)
end
return f and f()
end
function test(env)
local rsp = ""
for index = #rules, 1, -1 do
local entry = rules[index]
if eval(entry[1], env) then
local delay, duration
if entry[3] then
delay = entry[3].delay
duration = entry[3].duration
if delay and delay > 0 then
entry[3].delay = delay - 1
end
if ((not delay) or delay == 0) and duration and duration > 0 then
entry[3].duration = duration - 1
end
end
if (((not delay) or delay == 0) and ((not duration) or duration > 0)) then
if #rsp > 0 then
rsp = rsp .. " " .. entry[2]
else
rsp = entry[2]
end
end
if duration and duration <= 1 then
table.remove(rules, index)
end
end
end
return rsp
end
local fd = p.socket(p.AF_INET, p.SOCK_STREAM, 0)
p.setsockopt(fd, p.SOL_SOCKET, p.SO_REUSEADDR, 1)
p.bind(fd, {family=p.AF_INET, addr="127.0.0.1", port=port})
p.listen(fd, p.SOMAXCONN)
local running = true
while running do
ret_fd = p.accept(fd)
if ret_fd then
local msg = p.recv(ret_fd, p.BUFSIZ)
if msg then
local cmd, data = nil
sep = msg:find(" ")
if sep then
cmd = msg:sub(1, sep - 1)
data = msg:sub(sep + 1)
else
cmd = msg
end
if cmd == "test" then
local env = eval(data)
if env then
rsp = test(env)
p.send(ret_fd, rsp)
end
elseif cmd == "add" then
local value = eval(data)
if value then
table.insert(rules, value)
end
elseif cmd == "remove" then
if data == "tail" then
table.remove(rules, #rules)
elseif data == "head" then
table.remove(rules, 1)
else
for index = #rules, 1, -1 do
if rules[index][1]:find(data) then
table.remove(rules, index)
end
end
end
elseif cmd == "quit" then
running = false
elseif cmd == "list" then
local rsp = ""
for index, entry in pairs(rules) do
rsp = rsp .. string.format("%s => %s", entry[1], entry[2])
if entry[3] then
if entry[3].delay then
rsp = rsp .. string.format(" @%i", entry[3].delay)
end
if entry[3].duration then
rsp = rsp .. string.format(" +%i", entry[3].duration)
end
end
if index < #rules then
rsp = rsp .. "\n"
end
end
p.send(ret_fd, rsp)
end
end
p.close(ret_fd)
end
end
p.close(fd)