--- /dev/null
+
+--[[
+
+ Licensed under GNU General Public License v2
+ * (c) 2013, Luke Bonham
+
+--]]
+
+local debug = require("debug")
+
+local capi = { timer = timer }
+local io = { open = io.open,
+<<<<<<< HEAD
+ lines = io.lines }
+=======
+ lines = io.lines,
+ popen = io.popen }
+>>>>>>> upstream/master
+local rawget = rawget
+
+-- 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(table, key)
+ local module = rawget(table, key)
+ return module or require(table._NAME .. '.' .. key)
+end
+
+-- }}}
+
+-- {{{ File operations
+
+-- see if the file exists and is readable
+function helpers.file_exists(file)
+ local f = io.open(file)
+ if f then
+ local s = f:read()
+ f:close()
+ f = s
+ end
+ return f ~= nil
+end
+
+-- get all lines from a file, returns an empty
+-- list/table if the file does not exist
+function helpers.lines_from(file)
+ if not helpers.file_exists(file) then return {} end
+ lines = {}
+ for line in io.lines(file) do
+ lines[#lines + 1] = line
+ end
+ return lines
+end
+
+-- get first line of a file, return nil if
+-- the file does not exist
+function helpers.first_line(file)
+ return helpers.lines_from(file)[1]
+end
+
+-- get first non empty line from a file,
+-- returns nil otherwise
+function helpers.first_nonempty_line(file)
+ for k,v in pairs(helpers.lines_from(file)) do
+ if #v then return v end
+ end
+ return nil
+end
+
+-- }}}
+
+-- {{{ Timer maker
+
+helpers.timer_table = {}
+
+function helpers.newtimer(name, timeout, fun, nostart)
+ helpers.timer_table[name] = capi.timer({ timeout = timeout })
+ helpers.timer_table[name]:connect_signal("timeout", fun)
+ helpers.timer_table[name]:start()
+ if not nostart then
+ helpers.timer_table[name]:emit_signal("timeout")
+ end
+end
+
+-- }}}
+
+<<<<<<< HEAD
+=======
+-- {{{ Pipe operations
+
+-- read the full output of a pipe (command)
+function helpers.read_pipe(cmd)
+ local f = assert(io.popen(cmd))
+ local output = f:read("*all")
+ f:close()
+ return output
+end
+
+-- }}}
+
+>>>>>>> upstream/master
+-- {{{ 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
+
+-- }}}
+
+return helpers
--- /dev/null
+
+--[[
+
+ Lain
+ Layouts, widgets and utilities for Awesome WM
+
+ Users contributed widgets section
+
+ Licensed under GNU General Public License v2
+<<<<<<< HEAD
+ * (c) 2013, Luke Bonham
+=======
+ * (c) 2013, Luke Bonham
+>>>>>>> upstream/master
+
+--]]
+
+local wrequire = require("lain.helpers").wrequire
+local setmetatable = setmetatable
+
+local widgets = { _NAME = "lain.widgets.contrib" }
+
+return setmetatable(widgets, { __index = wrequire })
--- /dev/null
+
+--[[
+
+ Licensed under GNU General Public License v2
+ * (c) 2014, anticlockwise <http://github.com/anticlockwise>
+
+--]]
+
+local helpers = require("lain.helpers")
+local async = require("lain.asyncshell")
+
+local escape_f = require("awful.util").escape
+local naughty = require("naughty")
+local wibox = require("wibox")
+
+local io = { popen = io.popen }
+local os = { execute = os.execute,
+ getenv = os.getenv }
+local string = { format = string.format,
+ gmatch = string.gmatch }
+
+local setmetatable = setmetatable
+
+local moc = {}
+
+local function worker(args)
+ local args = args or {}
+ local timeout = args.timeout or 2
+ local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
+ local cover_size = args.cover_size or 100
+ local default_art = args.default_art or ""
+<<<<<<< HEAD
+=======
+ local followmouse = args.followmouse or false
+>>>>>>> upstream/master
+ local settings = args.settings or function() end
+
+ local mpdcover = helpers.scripts_dir .. "mpdcover"
+
+ moc.widget = wibox.widget.textbox('')
+
+ moc_notification_preset = {
+ title = "Now playing",
+ timeout = 6
+ }
+
+ helpers.set_map("current moc track", nil)
+
+ function moc.update()
+ -- mocp -i will produce output like:
+ -- Artist: Travis
+ -- Album: The Man Who
+ -- etc.
+ async.request("mocp -i", function(f)
+ moc_now = {
+ state = "N/A",
+ file = "N/A",
+ artist = "N/A",
+ title = "N/A",
+ album = "N/A",
+ elapsed = "N/A",
+ total = "N/A"
+ }
+
+<<<<<<< HEAD
+ for line in f:lines() do
+=======
+ for line in string.gmatch(f, "[^\n]+") do
+>>>>>>> upstream/master
+ for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
+ if k == "State" then moc_now.state = v
+ elseif k == "File" then moc_now.file = v
+ elseif k == "Artist" then moc_now.artist = escape_f(v)
+ elseif k == "SongTitle" then moc_now.title = escape_f(v)
+ elseif k == "Album" then moc_now.album = escape_f(v)
+ elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v)
+ elseif k == "TotalTime" then moc_now.total = escape_f(v)
+ end
+ end
+ end
+
+ moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist,
+ moc_now.album, moc_now.total, moc_now.title)
+ widget = moc.widget
+ settings()
+
+ if moc_now.state == "PLAY" then
+ if moc_now.title ~= helpers.get_map("current moc track") then
+ helpers.set_map("current moc track", moc_now.title)
+ os.execute(string.format("%s %q %q %d %q", mpdcover, "",
+ moc_now.file, cover_size, default_art))
+
+<<<<<<< HEAD
+=======
+ if followmouse then
+ moc_notification_preset.screen = mouse.screen
+ end
+
+>>>>>>> upstream/master
+ moc.id = naughty.notify({
+ preset = moc_notification_preset,
+ icon = "/tmp/mpdcover.png",
+ replaces_id = moc.id,
+ }).id
+ end
+ elseif moc_now.state ~= "PAUSE" then
+ helpers.set_map("current moc track", nil)
+ end
+ end)
+ end
+
+ helpers.newtimer("moc", timeout, moc.update)
+
+ return setmetatable(moc, { __index = moc.widget })
+end
+
+return setmetatable(moc, { __call = function(_, ...) return worker(...) end })
--- /dev/null
+
+--[[
+
+ Licensed under GNU General Public License v2
+ * (c) 2013, Jan Xie
+
+--]]
+
+local icons_dir = require("lain.helpers").icons_dir
+
+local awful = require("awful")
+local beautiful = require("beautiful")
+local naughty = require("naughty")
+
+<<<<<<< HEAD
+=======
+local mouse = mouse
+>>>>>>> upstream/master
+local io = io
+local string = { len = string.len }
+local tonumber = tonumber
+
+local setmetatable = setmetatable
+
+-- Taskwarrior notification
+-- lain.widgets.contrib.task
+local task = {}
+
+local task_notification = nil
+
+function task:hide()
+ if task_notification ~= nil then
+ naughty.destroy(task_notification)
+ task_notification = nil
+ end
+end
+
+<<<<<<< HEAD
+function task:show()
+=======
+function task:show(scr_pos)
+>>>>>>> upstream/master
+ task:hide()
+
+ local f, c_text
+
+<<<<<<< HEAD
+=======
+ if task.followmouse then
+ local scrp = mouse.screen
+ else
+ local scrp = scr_pos or task.scr_pos
+ end
+
+>>>>>>> upstream/master
+ f = io.popen('task')
+ c_text = "<span font='"
+ .. task.font .. " "
+ .. task.font_size .. "'>"
+ .. f:read("*all"):gsub("\n*$", "")
+ .. "</span>"
+ f:close()
+
+ task_notification = naughty.notify({ title = "[task next]",
+ text = c_text,
+ icon = task.notify_icon,
+ position = task.position,
+ fg = task.fg,
+ bg = task.bg,
+ timeout = task.timeout,
+<<<<<<< HEAD
+=======
+ screen = scrp
+>>>>>>> upstream/master
+ })
+end
+
+function task:prompt_add()
+ awful.prompt.run({ prompt = "Add task: " },
+ mypromptbox[mouse.screen].widget,
+ function (...)
+ local f = io.popen("task add " .. ...)
+ c_text = "\n<span font='"
+ .. task.font .. " "
+ .. task.font_size .. "'>"
+ .. f:read("*all")
+ .. "</span>"
+ f:close()
+
+ naughty.notify({
+ text = c_text,
+ icon = task.notify_icon,
+ position = task.position,
+ fg = task.fg,
+ bg = task.bg,
+ timeout = task.timeout,
+ })
+ end,
+ nil,
+ awful.util.getdir("cache") .. "/history_task_add")
+end
+
+function task:prompt_search()
+ awful.prompt.run({ prompt = "Search task: " },
+ mypromptbox[mouse.screen].widget,
+ function (...)
+ local f = io.popen("task " .. ...)
+ c_text = f:read("*all"):gsub(" \n*$", "")
+ f:close()
+
+ if string.len(c_text) == 0
+ then
+ c_text = "No results found."
+ else
+ c_text = "<span font='"
+ .. task.font .. " "
+ .. task.font_size .. "'>"
+ .. c_text
+ .. "</span>"
+ end
+
+ naughty.notify({
+ title = "[task next " .. ... .. "]",
+ text = c_text,
+ icon = task.notify_icon,
+ position = task.position,
+ fg = task.fg,
+ bg = task.bg,
+ timeout = task.timeout,
+<<<<<<< HEAD
+=======
+ screen = mouse.screen
+>>>>>>> upstream/master
+ })
+ end,
+ nil,
+ awful.util.getdir("cache") .. "/history_task")
+end
+
+function task:attach(widget, args)
+<<<<<<< HEAD
+ local args = args or {}
+
+ task.font_size = tonumber(args.font_size) or 12
+ task.font = beautiful.font:sub(beautiful.font:find(""),
+ beautiful.font:find(" "))
+ task.fg = args.fg or beautiful.fg_normal or "#FFFFFF"
+ task.bg = args.bg or beautiful.bg_normal or "#FFFFFF"
+ task.position = args.position or "top_right"
+ task.timeout = args.timeout or 7
+=======
+ local args = args or {}
+
+ task.font_size = tonumber(args.font_size) or 12
+ task.font = beautiful.font:sub(beautiful.font:find(""),
+ beautiful.font:find(" "))
+ task.fg = args.fg or beautiful.fg_normal or "#FFFFFF"
+ task.bg = args.bg or beautiful.bg_normal or "#FFFFFF"
+ task.position = args.position or "top_right"
+ task.timeout = args.timeout or 7
+ task.scr_pos = args.scr_pos or 1
+ task.followmouse = args.followmouse or false
+>>>>>>> upstream/master
+
+ task.notify_icon = icons_dir .. "/taskwarrior/task.png"
+ task.notify_icon_small = icons_dir .. "/taskwarrior/tasksmall.png"
+
+<<<<<<< HEAD
+ widget:connect_signal("mouse::enter", function () task:show() end)
+=======
+ widget:connect_signal("mouse::enter", function () task:show(task.scr_pos) end)
+>>>>>>> upstream/master
+ widget:connect_signal("mouse::leave", function () task:hide() end)
+end
+
+return setmetatable(task, { __call = function(_, ...) return create(...) end })