forked from lcpz/lain
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helpers.lua
203 lines (165 loc) · 4.51 KB
/
helpers.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
--[[
Licensed under GNU General Public License v2
* (c) 2013, Luca CPZ
--]]
local spawn = require("awful.spawn")
local timer = require("gears.timer")
local debug = require("debug")
local io = { lines = io.lines,
open = io.open }
local pairs = pairs
local rawget = rawget
local tsort = table.sort
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
-- Lain helper functions for internal use
-- lain.helpers
local helpers = {}
helpers.lain_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
helpers.icons_dir = helpers.lain_dir .. 'icons/'
helpers.scripts_dir = helpers.lain_dir .. 'scripts/'
-- {{{ Modules loader
function helpers.wrequire(t, k)
return rawget(t, k) or require(t._NAME .. '.' .. k)
end
-- }}}
-- {{{ File operations
-- check if the file exists and is readable
function helpers.file_exists(path)
local file = io.open(path, "rb")
if file then file:close() end
return file ~= nil
end
-- get a table with all lines from a file
function helpers.lines_from(path)
local lines = {}
for line in io.lines(path) do
lines[#lines + 1] = line
end
return lines
end
-- get a table with all lines from a file matching regexp
function helpers.lines_match(regexp, path)
local lines = {}
for line in io.lines(path) do
if string.match(line, regexp) then
lines[#lines + 1] = line
end
end
return lines
end
-- get first line of a file
function helpers.first_line(path)
local file, first = io.open(path, "rb"), nil
if file then
first = file:read("*l")
file:close()
end
return first
end
-- get first non empty line from a file
function helpers.first_nonempty_line(path)
for line in io.lines(path) do
if #line then return line end
end
return nil
end
-- }}}
-- {{{ Timer maker
helpers.timer_table = {}
function helpers.newtimer(name, timeout, fun, nostart, stoppable)
if not name or #name == 0 then return end
name = (stoppable and name) or timeout
if not helpers.timer_table[name] then
helpers.timer_table[name] = timer({ timeout = timeout })
helpers.timer_table[name]:start()
end
helpers.timer_table[name]:connect_signal("timeout", fun)
if not nostart then
helpers.timer_table[name]:emit_signal("timeout")
end
return stoppable and helpers.timer_table[name]
end
-- }}}
-- {{{ Pipe operations
-- run a command and execute a function on its output (asynchronous pipe)
-- @param cmd the input command
-- @param callback function to execute on cmd output
-- @return cmd PID
function helpers.async(cmd, callback)
return spawn.easy_async(cmd,
function (stdout, _, _, exit_code)
callback(stdout, exit_code)
end)
end
-- like above, but call spawn.easy_async with a shell
function helpers.async_with_shell(cmd, callback)
return spawn.easy_async_with_shell(cmd,
function (stdout, _, _, exit_code)
callback(stdout, exit_code)
end)
end
-- run a command and execute a function on its output line by line
function helpers.line_callback(cmd, callback)
return spawn.with_line_callback(cmd, {
stdout = function (line)
callback(line)
end,
})
end
-- }}}
-- {{{ A map utility
helpers.map_table = {}
function helpers.set_map(element, value)
helpers.map_table[element] = value
end
function helpers.get_map(element)
return helpers.map_table[element]
end
-- }}}
-- {{{ Misc
-- check if an element exist on a table
function helpers.element_in_table(element, tbl)
for _, i in pairs(tbl) do
if i == element then
return true
end
end
return false
end
-- iterate over table of records sorted by keys
function helpers.spairs(t)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys+1] = k end
tsort(keys)
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
-- create the partition of singletons of a given set
-- example: the trivial partition set of {a, b, c}, is {{a}, {b}, {c}}
function helpers.trivial_partition_set(set)
local ss = {}
for _,e in pairs(set) do
ss[#ss+1] = {e}
end
return ss
end
-- create the powerset of a given set
function helpers.powerset(s)
if not s then return {} end
local t = {{}}
for i = 1, #s do
for j = 1, #t do
t[#t+1] = {s[i],unpack(t[j])}
end
end
return t
end
-- }}}
return helpers