]> 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:

calendar: fix async hanging notifications; closes #289
[etc/awesome.git] / helpers.lua
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5       * (c) 2013, Luke Bonham                     
6                                                   
7 --]]
8
9
10 local debug      = require("debug")
11 local io         = { lines = io.lines,
12                      open  = io.open,
13                      popen = io.popen }
14 local rawget     = rawget
15 local table      = { sort  = table.sort }
16
17 local easy_async = require("awful.spawn").easy_async
18 local timer      = require("gears.timer")
19 local wibox      = require("wibox")
20
21 -- Lain helper functions for internal use
22 -- lain.helpers
23 local helpers = {}
24
25 helpers.lain_dir    = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
26 helpers.icons_dir   = helpers.lain_dir .. 'icons/'
27 helpers.scripts_dir = helpers.lain_dir .. 'scripts/'
28
29 -- {{{ Modules loader
30
31 function helpers.wrequire(table, key)
32     local module = rawget(table, key)
33     return module or require(table._NAME .. '.' .. key)
34 end
35
36 -- }}}
37
38 -- {{{ File operations
39
40 -- see if the file exists and is readable
41 function helpers.file_exists(file)
42   local f = io.open(file)
43   if f then
44       local s = f:read()
45       f:close()
46       f = s
47   end
48   return f ~= nil
49 end
50
51 -- get all lines from a file, returns an empty
52 -- list/table if the file does not exist
53 function helpers.lines_from(file)
54   if not helpers.file_exists(file) then return {} end
55   local lines = {}
56   for line in io.lines(file) do
57     lines[#lines + 1] = line
58   end
59   return lines
60 end
61
62 -- match all lines from a file, returns an empty
63 -- list/table if the file or match does not exist
64 function helpers.lines_match(regexp, file)
65         local lines = {}
66         for index,line in pairs(helpers.lines_from(file)) do
67                 if string.match(line, regexp) then
68                         lines[index] = line
69                 end
70         end
71         return lines
72 end
73
74 -- get first line of a file, return nil if
75 -- the file does not exist
76 function helpers.first_line(file)
77     return helpers.lines_from(file)[1]
78 end
79
80 -- get first non empty line from a file,
81 -- returns nil otherwise
82 function helpers.first_nonempty_line(file)
83   for k,v in pairs(helpers.lines_from(file)) do
84     if #v then return v end
85   end
86   return nil
87 end
88
89 -- }}}
90
91 -- {{{ Timer maker
92
93 helpers.timer_table = {}
94
95 function helpers.newtimer(name, timeout, fun, nostart, stoppable)
96     if not name or #name == 0 then return end
97     name = (stoppable and name) or timeout
98     if not helpers.timer_table[name] then
99         helpers.timer_table[name] = timer({ timeout = timeout })
100         helpers.timer_table[name]:start()
101     end
102     helpers.timer_table[name]:connect_signal("timeout", fun)
103     if not nostart then
104         helpers.timer_table[name]:emit_signal("timeout")
105     end
106     return stoppable and helpers.timer_table[name]
107 end
108
109 -- }}}
110
111 -- {{{ Pipe operations
112
113 -- return the full output of an input command (synchronous pipe)
114 -- @param cmd the input command
115 -- @return command output (string)
116 function helpers.read_pipe(cmd)
117    local f = io.popen(cmd)
118    local output = f:read("*all")
119    f:close()
120    return output
121 end
122
123 -- run a command and execute a function on its output (asynchronous pipe)
124 -- @param cmd the input command
125 -- @param callback function to execute on cmd output
126 -- @return cmd PID
127 function helpers.async(cmd, callback)
128     return easy_async(cmd,
129     function (stdout, stderr, reason, exit_code)
130         callback(stdout)
131     end)
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 a textbox with no spacing issues
181 function helpers.make_widget_textbox()
182     local w = wibox.widget.textbox()
183     local t = wibox.widget.base.make_widget(w)
184     t.widget = w
185     return t
186 end
187
188 -- }}}
189
190 return helpers