madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

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