]> git.madduck.net Git - etc/awesome.git/blob - helpers.lua

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:

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