helpers.lua 4.6 KB

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