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.calendar reimplemented and renamed to widget.cal; util.quake: simpler geometri...
authorLuca CPZ <luca.cpz@gmail.com>
Fri, 14 Sep 2018 10:09:11 +0000 (12:09 +0200)
committerLuca CPZ <luca.cpz@gmail.com>
Fri, 14 Sep 2018 10:09:11 +0000 (12:09 +0200)
util/markup.lua
util/quake.lua
widget/cal.lua [new file with mode: 0644]
widget/calendar.lua [deleted file]
widget/contrib/task.lua
wiki

index 98013318d6f87284a4bcb1444b40696a5ed7c83e..6d1331eb7672c1917d4877096058131c21602caf 100644 (file)
@@ -7,55 +7,55 @@
 
 --]]
 
-local string       = { format = string.format }
+local format = string.format
 local setmetatable = setmetatable
 
 -- Lain markup util submodule
 -- lain.util.markup
 local markup = { fg = {}, bg = {} }
 
--- Convenience tags.
-function markup.bold(text)      return '<b>'     .. text .. '</b>'     end
-function markup.italic(text)    return '<i>'     .. text .. '</i>'     end
-function markup.strike(text)    return '<s>'     .. text .. '</s>'     end
-function markup.underline(text) return '<u>'     .. text .. '</u>'     end
-function markup.monospace(text) return '<tt>'    .. text .. '</tt>'    end
-function markup.big(text)       return '<big>'   .. text .. '</big>'   end
-function markup.small(text)     return '<small>' .. text .. '</small>' end
+-- Convenience tags
+function markup.bold(text)      return format("<b>%s</b>",         text) end
+function markup.italic(text)    return format("<i>%s</i>",         text) end
+function markup.strike(text)    return format("<s>%s</s>",         text) end
+function markup.underline(text) return format("<u>%s</u>",         text) end
+function markup.monospace(text) return format("<tt>%s</tt>",       text) end
+function markup.big(text)       return format("<big>%s</big>",     text) end
+function markup.small(text)     return format("<small>%s</small>", text) end
 
--- Set the font.
+-- Set the font
 function markup.font(font, text)
-  return '<span font="'  .. font  .. '">' .. text ..'</span>'
+  return format("<span font='%s'>%s</span>", font, text)
 end
 
--- Set the foreground.
+-- Set the foreground
 function markup.fg.color(color, text)
-  return '<span foreground="' .. color .. '">' .. text .. '</span>'
+  return format("<span foreground='%s'>%s</span>", fg, bg, text)
 end
 
--- Set the background.
+-- Set the background
 function markup.bg.color(color, text)
-  return '<span background="' .. color .. '">' .. text .. '</span>'
+  return format("<span background='%s'>%s</span>", fg, bg, text)
 end
 
--- Set foreground and background.
+-- Set foreground and background
 function markup.color(fg, bg, text)
-  return string.format('<span foreground="%s" background="%s">%s</span>', fg, bg, text)
+  return format("<span foreground='%s' background='%s'>%s</span>", fg, bg, text)
 end
 
--- Set font and foreground.
+-- Set font and foreground
 function markup.fontfg(font, fg, text)
-  return string.format('<span font="%s" foreground="%s">%s</span>', font, fg, text)
+  return format("<span font='%s' foreground='%s'>%s</span>", font, fg, text)
 end
 
--- Set font and background.
+-- Set font and background
 function markup.fontbg(font, bg, text)
-  return string.format('<span font="%s" background="%s">%s</span>', font, bg, text)
+  return format("<span font='%s' background='%s'>%s</span>", font, bg, text)
 end
 
--- Set font, foreground and background.
+-- Set font, foreground and background
 function markup.fontcolor(font, fg, bg, text)
-  return string.format('<span font="%s" foreground="%s" background="%s">%s</span>', font, fg, bg, text)
+  return format("<span font='%s' foreground='%s' background='%s'>%s</span>", font, fg, bg, text)
 end
 
 -- link markup.{fg,bg}(...) calls to markup.{fg,bg}.color(...)
index e3237320a7990dae8828fa4a973bad7ce40f41fc..64aaca5f956117e112e31b6b9ee4ede690283b86 100644 (file)
@@ -63,7 +63,7 @@ function quake:display()
     client.floating = true
     client.border_width = self.border
     client.size_hints_honor = false
-    client:geometry(self.geometry[self.screen] or self:compute_size())
+    client:geometry(self.geometry[self.screen.index] or self:compute_size())
 
     -- Set not sticky and on top
     client.sticky = false
@@ -95,12 +95,12 @@ end
 
 function quake:compute_size()
     -- skip if we already have a geometry for this screen
-    if not self.geometry[self.screen] then
+    if not self.geometry[self.screen.index] then
         local geom
         if not self.overlap then
-            geom = screen[self.screen].workarea
+            geom = screen[self.screen.index].workarea
         else
-            geom = screen[self.screen].geometry
+            geom = screen[self.screen.index].geometry
         end
         local width, height = self.width, self.height
         if width  <= 1 then width = math.floor(geom.width * width) - 2 * self.border end
@@ -112,9 +112,9 @@ function quake:compute_size()
         if     self.vert == "top"    then y = geom.y
         elseif self.vert == "bottom" then y = geom.height + geom.y - height
         else   y = geom.y + (geom.height - height)/2 end
-        self.geometry[self.screen] = { x = x, y = y, width = width, height = height }
+        self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height }
     end
-    return self.geometry[self.screen]
+    return self.geometry[self.screen.index]
 end
 
 function quake:new(config)
diff --git a/widget/cal.lua b/widget/cal.lua
new file mode 100644 (file)
index 0000000..7a81c68
--- /dev/null
@@ -0,0 +1,101 @@
+--[[
+
+     Licensed under GNU General Public License v2
+      * (c) 2018, Luca CPZ
+
+--]]
+
+local helpers  = require("lain.helpers")
+local markup   = require("lain.util.markup")
+local awful    = require("awful")
+local naughty  = require("naughty")
+local floor    = math.floor
+local os       = os
+local string   = string
+local ipairs   = ipairs
+local tconcat  = table.concat
+local tonumber = tonumber
+local tostring = tostring
+
+-- Calendar notification
+-- lain.widget.cal
+local function factory(args)
+    args = args or {}
+    local cal = {
+        weekStart           = args.weekStart or 2,
+        attach_to           = args.attach_to or {},
+        followtag           = args.followtag or false,
+        icons               = args.icons or helpers.icons_dir .. "cal/white/",
+        notification_preset = args.notification_preset or {
+            font = "Monospace 10", fg = "#FFFFFF", bg = "#000000"
+        }
+    }
+
+    function cal.hide()
+        if not cal.notification then return end
+        naughty.destroy(cal.notification)
+        cal.notification = nil
+    end
+
+    function cal.show(timeout, month, year)
+        local current_month, current_year = tonumber(os.date("%m")), tonumber(os.date("%Y"))
+        local is_current_month = (not month or not year) or (month == current_month and year == current_year)
+        local today = is_current_month and tonumber(os.date("%d")) -- otherwise nil and not highlighted
+        local t = os.time { year = year or current_year, month = month and month+1 or current_month+1, day = 0 }
+        local d = os.date("*t", t)
+        local mthDays, stDay, cmonth = d.day, (d.wday-d.day-cal.weekStart+1)%7, os.date("%B %Y", t)
+        local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - cmonth:len())/2)), markup.bold(cmonth)) }
+        for x = 0,6 do notifytable[#notifytable+1] = os.date("%a ", os.time { year=2006, month=1, day=x+cal.weekStart }) end
+        notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", stDay*4))
+        for x = 1,mthDays do
+            local strx = x ~= today and x or markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. " ")
+            strx = string.format("%s%s", string.rep(" ", 3 - tostring(x):len()), strx)
+            notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+stDay)%7==0 and x ~= mthDays and "\n" or "")
+        end
+
+        cal.notification_preset.text = tconcat(notifytable)
+        cal.hide()
+        cal.notification = naughty.notify {
+            preset  = cal.notification_preset,
+            icon    = cal.icon,
+            timeout = timeout or cal.notification_preset.timeout or 5
+        }
+        cal.month, cal.year = d.month, d.year
+    end
+
+    function cal.hover_on() cal.show(0) end
+    function cal.hover_off() cal.hide() end
+    function cal.prev()
+        cal.month = cal.month - 1
+        if cal.month == 0 then
+            cal.month = 12
+            cal.year = cal.year - 1
+        end
+        cal.show(0, cal.month, cal.year)
+    end
+    function cal.next()
+        cal.month = cal.month + 1
+        if cal.month == 13 then
+            cal.month = 1
+            cal.year = cal.year + 1
+        end
+        cal.show(0, cal.month, cal.year)
+    end
+
+    function cal.attach(widget)
+        widget:connect_signal("mouse::enter", cal.hover_on)
+        widget:connect_signal("mouse::leave", cal.hover_off)
+        widget:buttons(awful.util.table.join(
+                    awful.button({}, 1, cal.prev),
+                    awful.button({}, 3, cal.next),
+                    awful.button({}, 2, cal.hover_on),
+                    awful.button({}, 5, cal.prev),
+                    awful.button({}, 4, cal.next)))
+    end
+
+    for _, widget in ipairs(cal.attach_to) do cal.attach(widget) end
+
+    return cal
+end
+
+return factory
diff --git a/widget/calendar.lua b/widget/calendar.lua
deleted file mode 100644 (file)
index e7b330a..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
---[[
-
-     Licensed under GNU General Public License v2
-      * (c) 2013, Luca CPZ
-
---]]
-
-local helpers      = require("lain.helpers")
-local markup       = require("lain.util.markup")
-local awful        = require("awful")
-local naughty      = require("naughty")
-local mouse        = mouse
-local os           = os
-local string       = string
-local ipairs       = ipairs
-local tonumber     = tonumber
-local setmetatable = setmetatable
-
--- Calendar notification
--- lain.widget.calendar
-local calendar = { offset = 0 }
-
-function calendar.hide()
-    if not calendar.notification then return end
-    naughty.destroy(calendar.notification)
-    calendar.notification = nil
-end
-
-function calendar.show(t_out, inc_offset, scr)
-    local f, offs = nil, inc_offset or 0
-
-    calendar.notification_preset.screen = scr or (calendar.followtag and awful.screen.focused()) or 1
-    calendar.offset = calendar.offset + offs
-
-    local current_month = (offs == 0 or calendar.offset == 0)
-
-    if current_month then -- today highlighted
-        calendar.offset = 0
-        calendar.icon   = calendar.icons:len() > 0 and string.format("%s%s.png", calendar.icons, tonumber(os.date("%d")))
-        f               = calendar.cal
-    else -- no current month showing, no day to highlight
-       local year  = tonumber(os.date("%Y"))
-       local month = tonumber(os.date("%m")) + calendar.offset
-
-       while month > 12 do
-           month = month - 12
-           year = year + 1
-       end
-
-       while month < 1 do
-           month = month + 12
-           year = year - 1
-       end
-
-       calendar.icon = nil
-       f = string.format("%s %s %s", calendar.cal, month, year)
-    end
-
-    helpers.async(f, function(ws)
-        local fg, bg = calendar.notification_preset.fg, calendar.notification_preset.bg
-        calendar.notification_preset.text = ws:gsub("%c%[%d+[m]?%s?%d+%c%[%d+[m]?",
-        markup.bold(markup.color(bg, fg, os.date("%e")))):gsub("[\n%s]*$", "")
-
-        local widget_focused = true
-
-        if t_out == 0 and mouse.current_widgets then
-            widget_focused = false
-            for i, widget in ipairs(calendar.attach_to) do
-                for _,v in ipairs(mouse.current_widgets) do
-                    if widget == v then
-                        widget_focused = true
-                        break
-                    end
-                end
-            end
-        end
-
-        if widget_focused then
-            calendar.hide()
-            calendar.notification = naughty.notify({
-                preset  = calendar.notification_preset,
-                icon    = calendar.icon,
-                timeout = t_out or calendar.notification_preset.timeout or 5
-            })
-        end
-    end)
-end
-
-function calendar.hover_on() calendar.show(0) end
-function calendar.hover_off() calendar.hide() end
-function calendar.prev() calendar.show(0, -1) end
-function calendar.next() calendar.show(0, 1) end
-
-function calendar.attach(widget)
-    widget:connect_signal("mouse::enter", calendar.hover_on)
-    widget:connect_signal("mouse::leave", calendar.hover_off)
-    widget:buttons(awful.util.table.join(
-                awful.button({}, 1, calendar.prev),
-                awful.button({}, 3, calendar.next),
-                awful.button({}, 2, calendar.hover_on),
-                awful.button({}, 4, calendar.prev),
-                awful.button({}, 5, calendar.next)))
-end
-
-local function factory(args)
-    local args                   = args or {}
-    calendar.cal                 = args.cal or "/usr/bin/cal"
-    calendar.attach_to           = args.attach_to or {}
-    calendar.followtag           = args.followtag or false
-    calendar.icons               = args.icons or helpers.icons_dir .. "cal/white/"
-    calendar.notification_preset = args.notification_preset
-
-    if not calendar.notification_preset then
-        calendar.notification_preset = {
-            font = "Monospace 10",
-            fg   = "#FFFFFF",
-            bg   = "#000000"
-        }
-    end
-
-    for i, widget in ipairs(calendar.attach_to) do calendar.attach(widget) end
-end
-
-return setmetatable(calendar, { __call = function(_, ...) return factory(...) end })
index 6c327517406ec10d045e5887acd9296da9b8eaa2..7e1f3d899b634d4c904e812abf935c4edd2b38d6 100644 (file)
@@ -48,7 +48,7 @@ function task.show(scr)
                     preset = task.notification_preset,
                     title  = "task next",
                     text   = markup.font(task.notification_preset.font,
-                        awful.util.escape(f:gsub("\n*$", "")))
+                             awful.util.escape(f:gsub("\n*$", "")))
                 })
         end
     end)
diff --git a/wiki b/wiki
index 89f3d98e339f07545aec31e94a3ecf42245b6316..0d9b19badf44b16c27663dd4dc7f49699a51be73 160000 (submodule)
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 89f3d98e339f07545aec31e94a3ecf42245b6316
+Subproject commit 0d9b19badf44b16c27663dd4dc7f49699a51be73