Name change

This commit is contained in:
Adam Cooper 2025-02-27 09:28:02 -05:00
parent 3f23185a5c
commit d96b3a1258
30 changed files with 938 additions and 835 deletions

View file

@ -28,7 +28,7 @@ If you want to create a pull request, make sure that:
- Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines. - Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines.
- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions to or using lain.helpers_. If something is unclear, or you can not write it in such a way that it will be clear, explain it with a comment. - Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions to or using lina.helpers_. If something is unclear, or you can not write it in such a way that it will be clear, explina it with a comment.
- You test your changes before submitting to make sure that your code works and does not break other parts of the module. - You test your changes before submitting to make sure that your code works and does not break other parts of the module.

View file

@ -15,13 +15,13 @@ local rawget = rawget
local tsort = table.sort local tsort = table.sort
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
-- Lain helper functions for internal use -- Lina helper functions for internal use
-- lain.helpers -- lina.helpers
local helpers = {} local helpers = {}
helpers.lain_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] helpers.lina_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
helpers.icons_dir = helpers.lain_dir .. 'icons/' helpers.icons_dir = helpers.lina_dir .. 'icons/'
helpers.scripts_dir = helpers.lain_dir .. 'scripts/' helpers.scripts_dir = helpers.lina_dir .. 'scripts/'
-- {{{ Modules loader -- {{{ Modules loader

View file

@ -1,6 +1,6 @@
--[[ --[[
Lain Lina
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
Licensed under GNU General Public License v2 Licensed under GNU General Public License v2

View file

@ -1,6 +1,6 @@
--[[ --[[
Lain Lina
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
Layouts section Layouts section
@ -11,9 +11,9 @@
--]] --]]
local wrequire = require("lain.helpers").wrequire local wrequire = require("lina.helpers").wrequire
local setmetatable = setmetatable local setmetatable = setmetatable
local layout = { _NAME = "lain.layout" } local layout = { _NAME = "lina.layout" }
return setmetatable(layout, { __index = wrequire }) return setmetatable(layout, { __index = wrequire })

View file

@ -1,7 +1,7 @@
-- Module options: -- Module options:
local always_use_lpeg = false local always_use_lpeg = false
local register_global_module_table = false local register_global_module_table = false
local global_module_name = 'json' local global_module_name = "json"
--[==[ --[==[
@ -47,8 +47,7 @@ local pairs, type, tostring, tonumber, getmetatable, setmetatable =
local error, require, pcall, select = error, require, pcall, select local error, require, pcall, select = error, require, pcall, select
local floor, huge = math.floor, math.huge local floor, huge = math.floor, math.huge
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat = local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
string.rep, string.gsub, string.sub, string.byte, string.char, string.rep, string.gsub, string.sub, string.byte, string.char, string.find, string.len, string.format
string.find, string.len, string.format
local strmatch = string.match local strmatch = string.match
local concat = table.concat local concat = table.concat
@ -66,27 +65,31 @@ end
_ENV = nil -- blocking globals in Lua 5.2 and later _ENV = nil -- blocking globals in Lua 5.2 and later
pcall (function() pcall(function()
-- Enable access to blocked metatables. -- Enable access to blocked metatables.
-- Don't worry, this module doesn't change anything in them. -- Don't worry, this module doesn't change anything in them.
local debmeta = require "debug".getmetatable local debmeta = require("debug").getmetatable
if debmeta then getmetatable = debmeta end if debmeta then
getmetatable = debmeta
end
end) end)
json.null = setmetatable ({}, { json.null = setmetatable({}, {
__tojson = function () return "null" end __tojson = function()
return "null"
end,
}) })
local function isarray (tbl) local function isarray(tbl)
local max, n, arraylen = 0, 0, 0 local max, n, arraylen = 0, 0, 0
for k,v in pairs (tbl) do for k, v in pairs(tbl) do
if k == 'n' and type(v) == 'number' then if k == "n" and type(v) == "number" then
arraylen = v arraylen = v
if v > max then if v > max then
max = v max = v
end end
else else
if type(k) ~= 'number' or k < 1 or floor(k) ~= k then if type(k) ~= "number" or k < 1 or floor(k) ~= k then
return false return false
end end
if k > max then if k > max then
@ -102,16 +105,21 @@ local function isarray (tbl)
end end
local escapecodes = { local escapecodes = {
["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f", ['"'] = '\\"',
["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t" ["\\"] = "\\\\",
["\b"] = "\\b",
["\f"] = "\\f",
["\n"] = "\\n",
["\r"] = "\\r",
["\t"] = "\\t",
} }
local function escapeutf8 (uchar) local function escapeutf8(uchar)
local value = escapecodes[uchar] local value = escapecodes[uchar]
if value then if value then
return value return value
end end
local a, b, c, d = strbyte (uchar, 1, 4) local a, b, c, d = strbyte(uchar, 1, 4)
a, b, c, d = a or 0, b or 0, c or 0, d or 0 a, b, c, d = a or 0, b or 0, c or 0, d or 0
if a <= 0x7f then if a <= 0x7f then
value = a value = a
@ -125,49 +133,49 @@ local function escapeutf8 (uchar)
return "" return ""
end end
if value <= 0xffff then if value <= 0xffff then
return strformat ("\\u%.4x", value) return strformat("\\u%.4x", value)
elseif value <= 0x10ffff then elseif value <= 0x10ffff then
-- encode as UTF-16 surrogate pair -- encode as UTF-16 surrogate pair
value = value - 0x10000 value = value - 0x10000
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400) local highsur, lowsur = 0xD800 + floor(value / 0x400), 0xDC00 + (value % 0x400)
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur) return strformat("\\u%.4x\\u%.4x", highsur, lowsur)
else else
return "" return ""
end end
end end
local function fsub (str, pattern, repl) local function fsub(str, pattern, repl)
-- gsub always builds a new string in a buffer, even when no match -- gsub always builds a new string in a buffer, even when no match
-- exists. First using find should be more efficient when most strings -- exists. First using find should be more efficient when most strings
-- don't contain the pattern. -- don't contain the pattern.
if strfind (str, pattern) then if strfind(str, pattern) then
return gsub (str, pattern, repl) return gsub(str, pattern, repl)
else else
return str return str
end end
end end
local function quotestring (value) local function quotestring(value)
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js -- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8) value = fsub(value, '[%z\1-\31"\\\127]', escapeutf8)
if strfind (value, "[\194\216\220\225\226\239]") then if strfind(value, "[\194\216\220\225\226\239]") then
value = fsub (value, "\194[\128-\159\173]", escapeutf8) value = fsub(value, "\194[\128-\159\173]", escapeutf8)
value = fsub (value, "\216[\128-\132]", escapeutf8) value = fsub(value, "\216[\128-\132]", escapeutf8)
value = fsub (value, "\220\143", escapeutf8) value = fsub(value, "\220\143", escapeutf8)
value = fsub (value, "\225\158[\180\181]", escapeutf8) value = fsub(value, "\225\158[\180\181]", escapeutf8)
value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8) value = fsub(value, "\226\128[\140-\143\168-\175]", escapeutf8)
value = fsub (value, "\226\129[\160-\175]", escapeutf8) value = fsub(value, "\226\129[\160-\175]", escapeutf8)
value = fsub (value, "\239\187\191", escapeutf8) value = fsub(value, "\239\187\191", escapeutf8)
value = fsub (value, "\239\191[\176-\191]", escapeutf8) value = fsub(value, "\239\191[\176-\191]", escapeutf8)
end end
return "\"" .. value .. "\"" return '"' .. value .. '"'
end end
json.quotestring = quotestring json.quotestring = quotestring
local function replace(str, o, n) local function replace(str, o, n)
local i, j = strfind (str, o, 1, true) local i, j = strfind(str, o, 1, true)
if i then if i then
return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1) return strsub(str, 1, i - 1) .. n .. strsub(str, j + 1, -1)
else else
return str return str
end end
@ -176,7 +184,7 @@ end
-- locale independent num2str and str2num functions -- locale independent num2str and str2num functions
local decpoint, numfilter local decpoint, numfilter
local function updatedecpoint () local function updatedecpoint()
decpoint = strmatch(tostring(0.5), "([^05+])") decpoint = strmatch(tostring(0.5), "([^05+])")
-- build a filter that can be used to remove group separators -- build a filter that can be used to remove group separators
numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+" numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
@ -184,11 +192,11 @@ end
updatedecpoint() updatedecpoint()
local function num2str (num) local function num2str(num)
return replace(fsub(tostring(num), numfilter, ""), decpoint, ".") return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
end end
local function str2num (str) local function str2num(str)
local num = tonumber(replace(str, ".", decpoint)) local num = tonumber(replace(str, ".", decpoint))
if not num then if not num then
updatedecpoint() updatedecpoint()
@ -197,25 +205,24 @@ local function str2num (str)
return num return num
end end
local function addnewline2 (level, buffer, buflen) local function addnewline2(level, buffer, buflen)
buffer[buflen+1] = "\n" buffer[buflen + 1] = "\n"
buffer[buflen+2] = strrep (" ", level) buffer[buflen + 2] = strrep(" ", level)
buflen = buflen + 2 buflen = buflen + 2
return buflen return buflen
end end
function json.addnewline (state) function json.addnewline(state)
if state.indent then if state.indent then
state.bufferlen = addnewline2 (state.level or 0, state.bufferlen = addnewline2(state.level or 0, state.buffer, state.bufferlen or #state.buffer)
state.buffer, state.bufferlen or #(state.buffer))
end end
end end
local encode2 -- forward declaration local encode2 -- forward declaration
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state) local function addpair(key, value, prev, indent, level, buffer, buflen, tables, globalorder, state)
local kt = type (key) local kt = type(key)
if kt ~= 'string' and kt ~= 'number' then if kt ~= "string" and kt ~= "number" then
return nil, "type '" .. kt .. "' is not supported as a key by JSON." return nil, "type '" .. kt .. "' is not supported as a key by JSON."
end end
if prev then if prev then
@ -223,16 +230,16 @@ local function addpair (key, value, prev, indent, level, buffer, buflen, tables,
buffer[buflen] = "," buffer[buflen] = ","
end end
if indent then if indent then
buflen = addnewline2 (level, buffer, buflen) buflen = addnewline2(level, buffer, buflen)
end end
buffer[buflen+1] = quotestring (key) buffer[buflen + 1] = quotestring(key)
buffer[buflen+2] = ":" buffer[buflen + 2] = ":"
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state) return encode2(value, indent, level, buffer, buflen + 2, tables, globalorder, state)
end end
local function appendcustom(res, buffer, state) local function appendcustom(res, buffer, state)
local buflen = state.bufferlen local buflen = state.bufferlen
if type (res) == 'string' then if type(res) == "string" then
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = res buffer[buflen] = res
end end
@ -246,8 +253,10 @@ local function exception(reason, value, state, buffer, buflen, defaultmessage)
return nil, defaultmessage return nil, defaultmessage
else else
state.bufferlen = buflen state.bufferlen = buflen
local ret, msg = handler (reason, value, state, defaultmessage) local ret, msg = handler(reason, value, state, defaultmessage)
if not ret then return nil, msg or defaultmessage end if not ret then
return nil, msg or defaultmessage
end
return appendcustom(ret, buffer, state) return appendcustom(ret, buffer, state)
end end
end end
@ -256,48 +265,50 @@ function json.encodeexception(_reason, _value, _state, defaultmessage)
return quotestring("<" .. defaultmessage .. ">") return quotestring("<" .. defaultmessage .. ">")
end end
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state) encode2 = function(value, indent, level, buffer, buflen, tables, globalorder, state)
local valtype = type (value) local valtype = type(value)
local valmeta = getmetatable (value) local valmeta = getmetatable(value)
valmeta = type (valmeta) == 'table' and valmeta -- only tables valmeta = type(valmeta) == "table" and valmeta -- only tables
local valtojson = valmeta and valmeta.__tojson local valtojson = valmeta and valmeta.__tojson
if valtojson then if valtojson then
if tables[value] then if tables[value] then
return exception('reference cycle', value, state, buffer, buflen) return exception("reference cycle", value, state, buffer, buflen)
end end
tables[value] = true tables[value] = true
state.bufferlen = buflen state.bufferlen = buflen
local ret, msg = valtojson (value, state) local ret, msg = valtojson(value, state)
if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end if not ret then
return exception("custom encoder failed", value, state, buffer, buflen, msg)
end
tables[value] = nil tables[value] = nil
buflen = appendcustom(ret, buffer, state) buflen = appendcustom(ret, buffer, state)
elseif value == nil then elseif value == nil then
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = "null" buffer[buflen] = "null"
elseif valtype == 'number' then elseif valtype == "number" then
local s local s
if value ~= value or value >= huge or -value >= huge then if value ~= value or value >= huge or -value >= huge then
-- This is the behaviour of the original JSON implementation. -- This is the behaviour of the original JSON implementation.
s = "null" s = "null"
else else
s = num2str (value) s = num2str(value)
end end
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = s buffer[buflen] = s
elseif valtype == 'boolean' then elseif valtype == "boolean" then
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = value and "true" or "false" buffer[buflen] = value and "true" or "false"
elseif valtype == 'string' then elseif valtype == "string" then
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = quotestring (value) buffer[buflen] = quotestring(value)
elseif valtype == 'table' then elseif valtype == "table" then
if tables[value] then if tables[value] then
return exception('reference cycle', value, state, buffer, buflen) return exception("reference cycle", value, state, buffer, buflen)
end end
tables[value] = true tables[value] = true
level = level + 1 level = level + 1
local isa, n = isarray (value) local isa, n = isarray(value)
if n == 0 and valmeta and valmeta.__jsontype == 'object' then if n == 0 and valmeta and valmeta.__jsontype == "object" then
isa = false isa = false
end end
local msg local msg
@ -305,8 +316,10 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = "[" buffer[buflen] = "["
for i = 1, n do for i = 1, n do
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state) buflen, msg = encode2(value[i], indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end if not buflen then
return nil, msg
end
if i < n then if i < n then
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = "," buffer[buflen] = ","
@ -327,62 +340,80 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
local v = value[k] local v = value[k]
if v ~= nil then if v ~= nil then
used[k] = true used[k] = true
buflen, _msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) buflen, _msg = addpair(k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
prev = true -- add a seperator before the next element prev = true -- add a seperator before the next element
end end
end end
for k,v in pairs (value) do for k, v in pairs(value) do
if not used[k] then if not used[k] then
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) buflen, msg = addpair(k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end if not buflen then
return nil, msg
end
prev = true -- add a seperator before the next element prev = true -- add a seperator before the next element
end end
end end
else -- unordered else -- unordered
for k,v in pairs (value) do for k, v in pairs(value) do
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) buflen, msg = addpair(k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
if not buflen then return nil, msg end if not buflen then
return nil, msg
end
prev = true -- add a seperator before the next element prev = true -- add a seperator before the next element
end end
end end
if indent then if indent then
buflen = addnewline2 (level - 1, buffer, buflen) buflen = addnewline2(level - 1, buffer, buflen)
end end
buflen = buflen + 1 buflen = buflen + 1
buffer[buflen] = "}" buffer[buflen] = "}"
end end
tables[value] = nil tables[value] = nil
else else
return exception ('unsupported type', value, state, buffer, buflen, return exception(
"type '" .. valtype .. "' is not supported by JSON.") "unsupported type",
value,
state,
buffer,
buflen,
"type '" .. valtype .. "' is not supported by JSON."
)
end end
return buflen return buflen
end end
function json.encode (value, state) function json.encode(value, state)
state = state or {} state = state or {}
local oldbuffer = state.buffer local oldbuffer = state.buffer
local buffer = oldbuffer or {} local buffer = oldbuffer or {}
state.buffer = buffer state.buffer = buffer
updatedecpoint() updatedecpoint()
local ret, msg = encode2 (value, state.indent, state.level or 0, local ret, msg = encode2(
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state) value,
state.indent,
state.level or 0,
buffer,
state.bufferlen or 0,
state.tables or {},
state.keyorder,
state
)
if not ret then if not ret then
error (msg, 2) error(msg, 2)
elseif oldbuffer == buffer then elseif oldbuffer == buffer then
state.bufferlen = ret state.bufferlen = ret
return true return true
else else
state.bufferlen = nil state.bufferlen = nil
state.buffer = nil state.buffer = nil
return concat (buffer) return concat(buffer)
end end
end end
local function loc (str, where) local function loc(str, where)
local line, pos, linepos = 1, 1, 0 local line, pos, linepos = 1, 1, 0
while true do while true do
pos = strfind (str, "\n", pos, true) pos = strfind(str, "\n", pos, true)
if pos and pos < where then if pos and pos < where then
line = line + 1 line = line + 1
linepos = pos linepos = pos
@ -394,24 +425,30 @@ local function loc (str, where)
return "line " .. line .. ", column " .. (where - linepos) return "line " .. line .. ", column " .. (where - linepos)
end end
local function unterminated (str, what, where) local function unterminated(str, what, where)
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where) return nil, strlen(str) + 1, "unterminated " .. what .. " at " .. loc(str, where)
end end
local function scanwhite (str, pos) local function scanwhite(str, pos)
while true do while true do
pos = strfind (str, "%S", pos) pos = strfind(str, "%S", pos)
if not pos then return nil end if not pos then
local sub2 = strsub (str, pos, pos + 1) return nil
if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then end
local sub2 = strsub(str, pos, pos + 1)
if sub2 == "\239\187" and strsub(str, pos + 2, pos + 2) == "\191" then
-- UTF-8 Byte Order Mark -- UTF-8 Byte Order Mark
pos = pos + 3 pos = pos + 3
elseif sub2 == "//" then elseif sub2 == "//" then
pos = strfind (str, "[\n\r]", pos + 2) pos = strfind(str, "[\n\r]", pos + 2)
if not pos then return nil end if not pos then
return nil
end
elseif sub2 == "/*" then elseif sub2 == "/*" then
pos = strfind (str, "*/", pos + 2) pos = strfind(str, "*/", pos + 2)
if not pos then return nil end if not pos then
return nil
end
pos = pos + 2 pos = pos + 2
else else
return pos return pos
@ -420,59 +457,64 @@ local function scanwhite (str, pos)
end end
local escapechars = { local escapechars = {
["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f", ['"'] = '"',
["n"] = "\n", ["r"] = "\r", ["t"] = "\t" ["\\"] = "\\",
["/"] = "/",
["b"] = "\b",
["f"] = "\f",
["n"] = "\n",
["r"] = "\r",
["t"] = "\t",
} }
local function unichar (value) local function unichar(value)
if value < 0 then if value < 0 then
return nil return nil
elseif value <= 0x007f then elseif value <= 0x007f then
return strchar (value) return strchar(value)
elseif value <= 0x07ff then elseif value <= 0x07ff then
return strchar (0xc0 + floor(value/0x40), return strchar(0xc0 + floor(value / 0x40), 0x80 + (floor(value) % 0x40))
0x80 + (floor(value) % 0x40))
elseif value <= 0xffff then elseif value <= 0xffff then
return strchar (0xe0 + floor(value/0x1000), return strchar(0xe0 + floor(value / 0x1000), 0x80 + (floor(value / 0x40) % 0x40), 0x80 + (floor(value) % 0x40))
0x80 + (floor(value/0x40) % 0x40),
0x80 + (floor(value) % 0x40))
elseif value <= 0x10ffff then elseif value <= 0x10ffff then
return strchar (0xf0 + floor(value/0x40000), return strchar(
0x80 + (floor(value/0x1000) % 0x40), 0xf0 + floor(value / 0x40000),
0x80 + (floor(value/0x40) % 0x40), 0x80 + (floor(value / 0x1000) % 0x40),
0x80 + (floor(value) % 0x40)) 0x80 + (floor(value / 0x40) % 0x40),
0x80 + (floor(value) % 0x40)
)
else else
return nil return nil
end end
end end
local function scanstring (str, pos) local function scanstring(str, pos)
local lastpos = pos + 1 local lastpos = pos + 1
local buffer, n = {}, 0 local buffer, n = {}, 0
while true do while true do
local nextpos = strfind (str, "[\"\\]", lastpos) local nextpos = strfind(str, '["\\]', lastpos)
if not nextpos then if not nextpos then
return unterminated (str, "string", pos) return unterminated(str, "string", pos)
end end
if nextpos > lastpos then if nextpos > lastpos then
n = n + 1 n = n + 1
buffer[n] = strsub (str, lastpos, nextpos - 1) buffer[n] = strsub(str, lastpos, nextpos - 1)
end end
if strsub (str, nextpos, nextpos) == "\"" then if strsub(str, nextpos, nextpos) == '"' then
lastpos = nextpos + 1 lastpos = nextpos + 1
break break
else else
local escchar = strsub (str, nextpos + 1, nextpos + 1) local escchar = strsub(str, nextpos + 1, nextpos + 1)
local value local value
if escchar == "u" then if escchar == "u" then
value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16) value = tonumber(strsub(str, nextpos + 2, nextpos + 5), 16)
if value then if value then
local value2 local value2
if 0xD800 <= value and value <= 0xDBff then if 0xD800 <= value and value <= 0xDBff then
-- we have the high surrogate of UTF-16. Check if there is a -- we have the high surrogate of UTF-16. Check if there is a
-- low surrogate escaped nearby to combine them. -- low surrogate escaped nearby to combine them.
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then if strsub(str, nextpos + 6, nextpos + 7) == "\\u" then
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16) value2 = tonumber(strsub(str, nextpos + 8, nextpos + 11), 16)
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000 value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
else else
@ -480,7 +522,7 @@ local function scanstring (str, pos)
end end
end end
end end
value = value and unichar (value) value = value and unichar(value)
if value then if value then
if value2 then if value2 then
lastpos = nextpos + 12 lastpos = nextpos + 12
@ -501,7 +543,7 @@ local function scanstring (str, pos)
if n == 1 then if n == 1 then
return buffer[1], lastpos return buffer[1], lastpos
elseif n > 1 then elseif n > 1 then
return concat (buffer), lastpos return concat(buffer), lastpos
else else
return "", lastpos return "", lastpos
end end
@ -509,40 +551,52 @@ end
local scanvalue -- forward declaration local scanvalue -- forward declaration
local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta) local function scantable(what, closechar, str, startpos, nullval, objectmeta, arraymeta)
local tbl, n = {}, 0 local tbl, n = {}, 0
local pos = startpos + 1 local pos = startpos + 1
if what == 'object' then if what == "object" then
setmetatable (tbl, objectmeta) setmetatable(tbl, objectmeta)
else else
setmetatable (tbl, arraymeta) setmetatable(tbl, arraymeta)
end end
while true do while true do
pos = scanwhite (str, pos) pos = scanwhite(str, pos)
if not pos then return unterminated (str, what, startpos) end if not pos then
local char = strsub (str, pos, pos) return unterminated(str, what, startpos)
end
local char = strsub(str, pos, pos)
if char == closechar then if char == closechar then
return tbl, pos + 1 return tbl, pos + 1
end end
local val1, err local val1, err
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) val1, pos, err = scanvalue(str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end if err then
pos = scanwhite (str, pos) return nil, pos, err
if not pos then return unterminated (str, what, startpos) end end
char = strsub (str, pos, pos) pos = scanwhite(str, pos)
if not pos then
return unterminated(str, what, startpos)
end
char = strsub(str, pos, pos)
if char == ":" then if char == ":" then
if val1 == nil then if val1 == nil then
return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")" return nil, pos, "cannot use nil as table index (at " .. loc(str, pos) .. ")"
end
pos = scanwhite(str, pos + 1)
if not pos then
return unterminated(str, what, startpos)
end end
pos = scanwhite (str, pos + 1)
if not pos then return unterminated (str, what, startpos) end
local val2 local val2
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) val2, pos, err = scanvalue(str, pos, nullval, objectmeta, arraymeta)
if err then return nil, pos, err end if err then
return nil, pos, err
end
tbl[val1] = val2 tbl[val1] = val2
pos = scanwhite (str, pos) pos = scanwhite(str, pos)
if not pos then return unterminated (str, what, startpos) end if not pos then
char = strsub (str, pos, pos) return unterminated(str, what, startpos)
end
char = strsub(str, pos, pos)
else else
n = n + 1 n = n + 1
tbl[n] = val1 tbl[n] = val1
@ -553,30 +607,30 @@ local function scantable (what, closechar, str, startpos, nullval, objectmeta, a
end end
end end
scanvalue = function (str, pos, nullval, objectmeta, arraymeta) scanvalue = function(str, pos, nullval, objectmeta, arraymeta)
pos = pos or 1 pos = pos or 1
pos = scanwhite (str, pos) pos = scanwhite(str, pos)
if not pos then if not pos then
return nil, strlen (str) + 1, "no valid JSON value (reached the end)" return nil, strlen(str) + 1, "no valid JSON value (reached the end)"
end end
local char = strsub (str, pos, pos) local char = strsub(str, pos, pos)
if char == "{" then if char == "{" then
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta) return scantable("object", "}", str, pos, nullval, objectmeta, arraymeta)
elseif char == "[" then elseif char == "[" then
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta) return scantable("array", "]", str, pos, nullval, objectmeta, arraymeta)
elseif char == "\"" then elseif char == '"' then
return scanstring (str, pos) return scanstring(str, pos)
else else
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos) local pstart, pend = strfind(str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
if pstart then if pstart then
local number = str2num (strsub (str, pstart, pend)) local number = str2num(strsub(str, pstart, pend))
if number then if number then
return number, pend + 1 return number, pend + 1
end end
end end
pstart, pend = strfind (str, "^%a%w*", pos) pstart, pend = strfind(str, "^%a%w*", pos)
if pstart then if pstart then
local name = strsub (str, pstart, pend) local name = strsub(str, pstart, pend)
if name == "true" then if name == "true" then
return true, pend + 1 return true, pend + 1
elseif name == "false" then elseif name == "false" then
@ -585,7 +639,7 @@ scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
return nullval, pend + 1 return nullval, pend + 1
end end
end end
return nil, pos, "no valid JSON value at " .. loc (str, pos) return nil, pos, "no valid JSON value at " .. loc(str, pos)
end end
end end
@ -593,125 +647,132 @@ local function optionalmetatables(...)
if select("#", ...) > 0 then if select("#", ...) > 0 then
return ... return ...
else else
return {__jsontype = 'object'}, {__jsontype = 'array'} return { __jsontype = "object" }, { __jsontype = "array" }
end end
end end
function json.decode (str, pos, nullval, ...) function json.decode(str, pos, nullval, ...)
local objectmeta, arraymeta = optionalmetatables(...) local objectmeta, arraymeta = optionalmetatables(...)
return scanvalue (str, pos, nullval, objectmeta, arraymeta) return scanvalue(str, pos, nullval, objectmeta, arraymeta)
end end
function json.use_lpeg () function json.use_lpeg()
local g = require ("lpeg") local g = require("lpeg")
if g.version() == "0.11" then if g.version() == "0.11" then
error "due to a bug in LPeg 0.11, it cannot be used for JSON matching" error("due to a bug in LPeg 0.11, it cannot be used for JSON matching")
end end
local pegmatch = g.match local pegmatch = g.match
local P, S, R = g.P, g.S, g.R local P, S, R = g.P, g.S, g.R
local function ErrorCall (str, pos, msg, state) local function ErrorCall(str, pos, msg, state)
if not state.msg then if not state.msg then
state.msg = msg .. " at " .. loc (str, pos) state.msg = msg .. " at " .. loc(str, pos)
state.pos = pos state.pos = pos
end end
return false return false
end end
local function Err (msg) local function Err(msg)
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall) return g.Cmt(g.Cc(msg) * g.Carg(2), ErrorCall)
end end
local function ErrorUnterminatedCall (str, pos, what, state) local function ErrorUnterminatedCall(str, pos, what, state)
return ErrorCall (str, pos - 1, "unterminated " .. what, state) return ErrorCall(str, pos - 1, "unterminated " .. what, state)
end end
local SingleLineComment = P"//" * (1 - S"\n\r")^0 local SingleLineComment = P("//") * (1 - S("\n\r")) ^ 0
local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/" local MultiLineComment = P("/*") * (1 - P("*/")) ^ 0 * P("*/")
local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0 local Space = (S(" \n\r\t") + P("\239\187\191") + SingleLineComment + MultiLineComment) ^ 0
local function ErrUnterminated (what) local function ErrUnterminated(what)
return g.Cmt (g.Cc (what) * g.Carg (2), ErrorUnterminatedCall) return g.Cmt(g.Cc(what) * g.Carg(2), ErrorUnterminatedCall)
end end
local PlainChar = 1 - S"\"\\\n\r" local PlainChar = 1 - S('"\\\n\r')
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars local EscapeSequence = (P("\\") * g.C(S('"\\/bfnrt') + Err("unsupported escape sequence"))) / escapechars
local HexDigit = R("09", "af", "AF") local HexDigit = R("09", "af", "AF")
local function UTF16Surrogate (_match, _pos, high, low) local function UTF16Surrogate(_match, _pos, high, low)
high, low = tonumber (high, 16), tonumber (low, 16) high, low = tonumber(high, 16), tonumber(low, 16)
if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000) return true, unichar((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
else else
return false return false
end end
end end
local function UTF16BMP (hex) local function UTF16BMP(hex)
return unichar (tonumber (hex, 16)) return unichar(tonumber(hex, 16))
end end
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit)) local U16Sequence = (P("\\u") * g.C(HexDigit * HexDigit * HexDigit * HexDigit))
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP local UnicodeEscape = g.Cmt(U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence / UTF16BMP
local Char = UnicodeEscape + EscapeSequence + PlainChar local Char = UnicodeEscape + EscapeSequence + PlainChar
local String = P"\"" * (g.Cs (Char ^ 0) * P"\"" + ErrUnterminated "string") local String = P('"') * (g.Cs(Char ^ 0) * P('"') + ErrUnterminated("string"))
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0)) local Integer = P("-") ^ -1 * (P("0") + (R("19") * R("09") ^ 0))
local Fractal = P"." * R"09"^0 local Fractal = P(".") * R("09") ^ 0
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1 local Exponent = (S("eE")) * (S("+-")) ^ -1 * R("09") ^ 1
local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num local Number = (Integer * Fractal ^ -1 * Exponent ^ -1) / str2num
local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1) local Constant = P("true") * g.Cc(true) + P("false") * g.Cc(false) + P("null") * g.Carg(1)
local SimpleValue = Number + String + Constant local SimpleValue = Number + String + Constant
local ArrayContent, ObjectContent local ArrayContent, ObjectContent
-- The functions parsearray and parseobject parse only a single value/pair -- The functions parsearray and parseobject parse only a single value/pair
-- at a time and store them directly to avoid hitting the LPeg limits. -- at a time and store them directly to avoid hitting the LPeg limits.
local function parsearray (str, pos, nullval, state) local function parsearray(str, pos, nullval, state)
local obj, cont local obj, cont
local start = pos local start = pos
local npos local npos
local t, nt = {}, 0 local t, nt = {}, 0
repeat repeat
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state) obj, cont, npos = pegmatch(ArrayContent, str, pos, nullval, state)
if cont == 'end' then if cont == "end" then
return ErrorUnterminatedCall (str, start, "array", state) return ErrorUnterminatedCall(str, start, "array", state)
end end
pos = npos pos = npos
if cont == 'cont' or cont == 'last' then if cont == "cont" or cont == "last" then
nt = nt + 1 nt = nt + 1
t[nt] = obj t[nt] = obj
end end
until cont ~= 'cont' until cont ~= "cont"
return pos, setmetatable (t, state.arraymeta) return pos, setmetatable(t, state.arraymeta)
end end
local function parseobject (str, pos, nullval, state) local function parseobject(str, pos, nullval, state)
local obj, key, cont local obj, key, cont
local start = pos local start = pos
local npos local npos
local t = {} local t = {}
repeat repeat
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state) key, obj, cont, npos = pegmatch(ObjectContent, str, pos, nullval, state)
if cont == 'end' then if cont == "end" then
return ErrorUnterminatedCall (str, start, "object", state) return ErrorUnterminatedCall(str, start, "object", state)
end end
pos = npos pos = npos
if cont == 'cont' or cont == 'last' then if cont == "cont" or cont == "last" then
t[key] = obj t[key] = obj
end end
until cont ~= 'cont' until cont ~= "cont"
return pos, setmetatable (t, state.objectmeta) return pos, setmetatable(t, state.objectmeta)
end end
local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) local Array = P("[") * g.Cmt(g.Carg(1) * g.Carg(2), parsearray)
local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) local Object = P("{") * g.Cmt(g.Carg(1) * g.Carg(2), parseobject)
local Value = Space * (Array + Object + SimpleValue) local Value = Space * (Array + Object + SimpleValue)
local ExpectedValue = Value + Space * Err "value expected" local ExpectedValue = Value + Space * Err("value expected")
local ExpectedKey = String + Err "key expected" local ExpectedKey = String + Err("key expected")
local End = P(-1) * g.Cc'end' local End = P(-1) * g.Cc("end")
local ErrInvalid = Err "invalid JSON" local ErrInvalid = Err("invalid JSON")
ArrayContent = (Value * Space * (P"," * g.Cc'cont' + P"]" * g.Cc'last'+ End + ErrInvalid) + g.Cc(nil) * (P"]" * g.Cc'empty' + End + ErrInvalid)) * g.Cp() ArrayContent = (
local Pair = g.Cg (Space * ExpectedKey * Space * (P":" + Err "colon expected") * ExpectedValue) Value * Space * (P(",") * g.Cc("cont") + P("]") * g.Cc("last") + End + ErrInvalid)
ObjectContent = (g.Cc(nil) * g.Cc(nil) * P"}" * g.Cc'empty' + End + (Pair * Space * (P"," * g.Cc'cont' + P"}" * g.Cc'last' + End + ErrInvalid) + ErrInvalid)) * g.Cp() + g.Cc(nil) * (P("]") * g.Cc("empty") + End + ErrInvalid)
local DecodeValue = ExpectedValue * g.Cp () ) * g.Cp()
local Pair = g.Cg(Space * ExpectedKey * Space * (P(":") + Err("colon expected")) * ExpectedValue)
ObjectContent = (
g.Cc(nil) * g.Cc(nil) * P("}") * g.Cc("empty")
+ End
+ (Pair * Space * (P(",") * g.Cc("cont") + P("}") * g.Cc("last") + End + ErrInvalid) + ErrInvalid)
) * g.Cp()
local DecodeValue = ExpectedValue * g.Cp()
jsonlpeg.version = json.version jsonlpeg.version = json.version
jsonlpeg.encode = json.encode jsonlpeg.encode = json.encode
@ -721,10 +782,10 @@ function json.use_lpeg ()
jsonlpeg.encodeexception = json.encodeexception jsonlpeg.encodeexception = json.encodeexception
jsonlpeg.using_lpeg = true jsonlpeg.using_lpeg = true
function jsonlpeg.decode (str, pos, nullval, ...) function jsonlpeg.decode(str, pos, nullval, ...)
local state = {} local state = {}
state.objectmeta, state.arraymeta = optionalmetatables(...) state.objectmeta, state.arraymeta = optionalmetatables(...)
local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state) local obj, retpos = pegmatch(DecodeValue, str, pos, nullval, state)
if state.msg then if state.msg then
return nil, state.pos, state.msg return nil, state.pos, state.msg
else else
@ -733,7 +794,9 @@ function json.use_lpeg ()
end end
-- cache result of this function: -- cache result of this function:
json.use_lpeg = function () return jsonlpeg end json.use_lpeg = function()
return jsonlpeg
end
jsonlpeg.use_lpeg = json.use_lpeg jsonlpeg.use_lpeg = json.use_lpeg
return jsonlpeg return jsonlpeg
@ -744,4 +807,3 @@ if always_use_lpeg then
end end
return json return json

View file

@ -1,6 +1,6 @@
--[[ --[[
Lain Lina
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
Utilities section Utilities section
@ -19,43 +19,51 @@ local tonumber = tonumber
local wrequire = require("lina.helpers").wrequire local wrequire = require("lina.helpers").wrequire
local setmetatable = setmetatable local setmetatable = setmetatable
-- Lain utilities submodule -- Lina utilities submodule
-- lain.util -- lina.util
local util = { _NAME = "lain.util" } local util = { _NAME = "lina.util" }
-- Like awful.menu.clients, but only show clients of currently selected tags -- Like awful.menu.clients, but only show clients of currently selected tags
function util.menu_clients_current_tags(menu, args) function util.menu_clients_current_tags(menu, args)
-- List of currently selected tags. -- List of currently selected tags.
local cls_tags = awful.screen.focused().selected_tags local cls_tags = awful.screen.focused().selected_tags
if cls_tags == nil then return nil end if cls_tags == nil then
return nil
end
-- Final list of menu items. -- Final list of menu items.
local cls_t = {} local cls_t = {}
-- For each selected tag get all clients of that tag and add them to -- For each selected tag get all clients of that tag and add them to
-- the menu. A click on a menu item will raise that client. -- the menu. A click on a menu item will raise that client.
for i = 1,#cls_tags do for i = 1, #cls_tags do
local t = cls_tags[i] local t = cls_tags[i]
local cls = t:clients() local cls = t:clients()
for _, c in pairs(cls) do for _, c in pairs(cls) do
cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "", cls_t[#cls_t + 1] = {
function () awful.util.escape(c.name) or "",
function()
c.minimized = false c.minimized = false
client.focus = c client.focus = c
c:raise() c:raise()
end, end,
c.icon } c.icon,
}
end end
end end
-- No clients? Then quit. -- No clients? Then quit.
if #cls_t <= 0 then return nil end if #cls_t <= 0 then
return nil
end
-- menu may contain some predefined values, otherwise start with a -- menu may contain some predefined values, otherwise start with a
-- fresh menu. -- fresh menu.
if not menu then menu = {} end if not menu then
menu = {}
end
-- Set the list of items and show the menu. -- Set the list of items and show the menu.
menu.items = cls_t menu.items = cls_t
@ -79,7 +87,9 @@ end
-- https://github.com/lcpz/lain/issues/195 -- https://github.com/lcpz/lain/issues/195
function util.mc(c, width_f, height_f) function util.mc(c, width_f, height_f)
c = c or util.magnified_client c = c or util.magnified_client
if not c then return end if not c then
return
end
c.floating = true c.floating = true
local s = awful.screen.focused() local s = awful.screen.focused()
@ -91,12 +101,14 @@ function util.mc(c, width_f, height_f)
g.x = mg.x + (mg.width - g.width) / 2 g.x = mg.x + (mg.width - g.width) / 2
g.y = mg.y + (mg.height - g.height) / 2 g.y = mg.y + (mg.height - g.height) / 2
if c then c:geometry(g) end -- if c is still a valid object if c then
c:geometry(g)
end -- if c is still a valid object
end end
-- Non-empty tag browsing -- Non-empty tag browsing
-- direction in {-1, 1} <-> {previous, next} non-empty tag -- direction in {-1, 1} <-> {previous, next} non-empty tag
function util.tag_view_nonempty(direction,sc) function util.tag_view_nonempty(direction, sc)
direction = direction or 1 direction = direction or 1
local s = sc or awful.screen.focused() local s = sc or awful.screen.focused()
local tags = s.tags local tags = s.tags
@ -133,29 +145,35 @@ end
-- Add a new tag -- Add a new tag
function util.add_tag(layout) function util.add_tag(layout)
awful.prompt.run { awful.prompt.run({
prompt = "New tag name: ", prompt = "New tag name: ",
textbox = awful.screen.focused().mypromptbox.widget, textbox = awful.screen.focused().mypromptbox.widget,
exe_callback = function(name) exe_callback = function(name)
if not name or #name == 0 then return end if not name or #name == 0 then
awful.tag.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile }):view_only() return
end end
} awful.tag
.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile })
:view_only()
end,
})
end end
-- Rename current tag -- Rename current tag
function util.rename_tag() function util.rename_tag()
awful.prompt.run { awful.prompt.run({
prompt = "Rename tag: ", prompt = "Rename tag: ",
textbox = awful.screen.focused().mypromptbox.widget, textbox = awful.screen.focused().mypromptbox.widget,
exe_callback = function(new_name) exe_callback = function(new_name)
if not new_name or #new_name == 0 then return end if not new_name or #new_name == 0 then
return
end
local t = awful.screen.focused().selected_tag local t = awful.screen.focused().selected_tag
if t then if t then
t.name = new_name t.name = new_name
end end
end end,
} })
end end
-- Move current tag -- Move current tag
@ -173,7 +191,9 @@ end
-- Any rule set on the tag shall be broken -- Any rule set on the tag shall be broken
function util.delete_tag() function util.delete_tag()
local t = awful.screen.focused().selected_tag local t = awful.screen.focused().selected_tag
if not t then return end if not t then
return
end
t:delete() t:delete()
end end

View file

@ -10,8 +10,8 @@
local format = string.format local format = string.format
local setmetatable = setmetatable local setmetatable = setmetatable
-- Lain markup util submodule -- Lina markup util submodule
-- lain.util.markup -- lina.util.markup
local markup = { fg = {}, bg = {} } local markup = { fg = {}, bg = {} }
-- Convenience tags -- Convenience tags

View file

@ -8,10 +8,10 @@
--]] --]]
-- Menu iterator with Naughty notifications -- Menu iterator with Naughty notifications
-- lain.util.menu_iterator -- lina.util.menu_iterator
local naughty = require("naughty") local naughty = require("naughty")
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local atable = require("awful.util").table local atable = require("awful.util").table
local assert = assert local assert = assert
local pairs = pairs local pairs = pairs

View file

@ -10,8 +10,8 @@ local wibox = require("wibox")
local gears = require("gears") local gears = require("gears")
local beautiful = require("beautiful") local beautiful = require("beautiful")
-- Lain Cairo separators util submodule -- Lina Cairo separators util submodule
-- lain.util.separators -- lina.util.separators
local separators = { height = beautiful.separators_height or 0, width = beautiful.separators_width or 9 } local separators = { height = beautiful.separators_height or 0, width = beautiful.separators_width or 9 }
-- [[ Arrow -- [[ Arrow

View file

@ -6,13 +6,13 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local shell = require("awful.util").shell local shell = require("awful.util").shell
local wibox = require("wibox") local wibox = require("wibox")
local string = string local string = string
-- ALSA volume -- ALSA volume
-- lain.widget.alsa -- lina.widget.alsa
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -6,7 +6,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local awful = require("awful") local awful = require("awful")
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
@ -16,7 +16,7 @@ local type = type
local tonumber = tonumber local tonumber = tonumber
-- ALSA volume bar -- ALSA volume bar
-- lain.widget.alsabar -- lina.widget.alsabar
local function factory(args) local function factory(args)
local alsabar = { local alsabar = {

View file

@ -6,7 +6,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local fs = require("gears.filesystem") local fs = require("gears.filesystem")
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
@ -16,13 +16,13 @@ local ipairs = ipairs
local tonumber = tonumber local tonumber = tonumber
-- Battery infos -- Battery infos
-- lain.widget.bat -- lina.widget.bat
local function factory(args) local function factory(args)
local pspath = args.pspath or "/sys/class/power_supply/" local pspath = args.pspath or "/sys/class/power_supply/"
if not fs.is_dir(pspath) then if not fs.is_dir(pspath) then
naughty.notify { text = "lain.widget.bat: invalid power supply path", timeout = 0 } naughty.notify { text = "lina.widget.bat: invalid power supply path", timeout = 0 }
return return
end end

View file

@ -5,8 +5,8 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local markup = require("lain.util.markup") local markup = require("lina.util.markup")
local awful = require("awful") local awful = require("awful")
local naughty = require("naughty") local naughty = require("naughty")
local floor = math.floor local floor = math.floor
@ -19,7 +19,7 @@ local tonumber = tonumber
local tostring = tostring local tostring = tostring
-- Calendar notification -- Calendar notification
-- lain.widget.cal -- lina.widget.cal
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -1,6 +1,6 @@
--[[ --[[
Lain Lina
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
Users contributed widgets section Users contributed widgets section
@ -10,9 +10,9 @@
--]] --]]
local wrequire = require("lain.helpers").wrequire local wrequire = require("lina.helpers").wrequire
local setmetatable = setmetatable local setmetatable = setmetatable
local widget = { _NAME = "lain.widget.contrib" } local widget = { _NAME = "lina.widget.contrib" }
return setmetatable(widget, { __index = wrequire }) return setmetatable(widget, { __index = wrequire })

View file

@ -5,7 +5,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local shell = require("awful.util").shell local shell = require("awful.util").shell
local focused = require("awful.screen").focused local focused = require("awful.screen").focused
local escape_f = require("awful.util").escape local escape_f = require("awful.util").escape
@ -15,7 +15,7 @@ local os = os
local string = string local string = string
-- MOC audio player -- MOC audio player
-- lain.widget.contrib.moc -- lina.widget.contrib.moc
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -6,13 +6,13 @@
--]] --]]
local async = require("lain.helpers").async local async = require("lina.helpers").async
local awful = require("awful") local awful = require("awful")
local execute = os.execute local execute = os.execute
local type = type local type = type
-- Redshift -- Redshift
-- lain.widget.contrib.redshift -- lina.widget.contrib.redshift
local redshift = { active = false, pid = nil } local redshift = { active = false, pid = nil }
function redshift.start() function redshift.start()

View file

@ -5,14 +5,14 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local markup = require("lain.util").markup local markup = require("lina.util").markup
local awful = require("awful") local awful = require("awful")
local naughty = require("naughty") local naughty = require("naughty")
local mouse = mouse local mouse = mouse
-- Taskwarrior notification -- Taskwarrior notification
-- lain.widget.contrib.task -- lina.widget.contrib.task
local task = {} local task = {}
function task.hide() function task.hide()

View file

@ -6,7 +6,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local focused = require("awful.screen").focused local focused = require("awful.screen").focused
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
@ -15,7 +15,7 @@ local type = type
-- ThinkPad battery infos and widget creator -- ThinkPad battery infos and widget creator
-- http://www.thinkwiki.org/wiki/Tp_smapi -- http://www.thinkwiki.org/wiki/Tp_smapi
-- lain.widget.contrib.tp_smapi -- lina.widget.contrib.tp_smapi
local function factory(apipath) local function factory(apipath)
local tp_smapi = { local tp_smapi = {

View file

@ -6,13 +6,13 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local wibox = require("wibox") local wibox = require("wibox")
local math = math local math = math
local string = string local string = string
-- CPU usage -- CPU usage
-- lain.widget.cpu -- lina.widget.cpu
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -7,7 +7,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local Gio = require("lgi").Gio local Gio = require("lgi").Gio
local focused = require("awful.screen").focused local focused = require("awful.screen").focused
local wibox = require("wibox") local wibox = require("wibox")
@ -23,7 +23,7 @@ local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED
local query = query_size .. "," .. query_free .. "," .. query_used local query = query_size .. "," .. query_free .. "," .. query_used
-- File systems info -- File systems info
-- lain.widget.fs -- lina.widget.fs
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -5,7 +5,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
local awful = require("awful") local awful = require("awful")
@ -14,7 +14,7 @@ local type = type
local tonumber = tonumber local tonumber = tonumber
-- Mail IMAP check -- Mail IMAP check
-- lain.widget.imap -- lina.widget.imap
local function factory(args) local function factory(args)
args = args or {} args = args or {}
@ -34,18 +34,22 @@ local function factory(args)
local head_command = "curl --connect-timeout 3 -fsm 3" local head_command = "curl --connect-timeout 3 -fsm 3"
local request = "-X 'STATUS INBOX (MESSAGES RECENT UNSEEN)'" local request = "-X 'STATUS INBOX (MESSAGES RECENT UNSEEN)'"
if not server or not mail or not password then return end if not server or not mail or not password then
return
end
mail_notification_preset = { mail_notification_preset = {
icon = helpers.icons_dir .. "mail.png", icon = helpers.icons_dir .. "mail.png",
position = "top_left" position = "top_left",
} }
helpers.set_map(mail, 0) helpers.set_map(mail, 0)
if not is_plain then if not is_plain then
if type(password) == "string" or type(password) == "table" then if type(password) == "string" or type(password) == "table" then
helpers.async(password, function(f) password = f:gsub("\n", "") end) helpers.async(password, function(f)
password = f:gsub("\n", "")
end)
elseif type(password) == "function" then elseif type(password) == "function" then
imap.pwdtimer = helpers.newtimer(mail .. "-password", pwdtimeout, function() imap.pwdtimer = helpers.newtimer(mail .. "-password", pwdtimeout, function()
local retrieved_password, try_again = password() local retrieved_password, try_again = password()
@ -59,31 +63,48 @@ local function factory(args)
function imap.update() function imap.update()
-- do not update if the password has not been retrieved yet -- do not update if the password has not been retrieved yet
if type(password) ~= "string" then return end if type(password) ~= "string" then
return
end
local curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:'%s' %s -k", local curl = string.format(
head_command, server, port, mail, password, request) "%s --url imaps://%s:%s/INBOX -u %s:'%s' %s -k",
head_command,
server,
port,
mail,
password,
request
)
helpers.async(curl, function(f) helpers.async(curl, function(f)
imap_now = { ["MESSAGES"] = 0, ["RECENT"] = 0, ["UNSEEN"] = 0 } imap_now = { ["MESSAGES"] = 0, ["RECENT"] = 0, ["UNSEEN"] = 0 }
for s,d in f:gmatch("(%w+)%s+(%d+)") do imap_now[s] = tonumber(d) end for s, d in f:gmatch("(%w+)%s+(%d+)") do
imap_now[s] = tonumber(d)
end
mailcount = imap_now["UNSEEN"] -- backwards compatibility mailcount = imap_now["UNSEEN"] -- backwards compatibility
widget = imap.widget widget = imap.widget
settings() settings()
if notify == "on" and mailcount and mailcount >= 1 and mailcount > helpers.get_map(mail) then if notify == "on" and mailcount and mailcount >= 1 and mailcount > helpers.get_map(mail) then
if followtag then mail_notification_preset.screen = awful.screen.focused() end if followtag then
naughty.notify { mail_notification_preset.screen = awful.screen.focused()
end
naughty.notify({
preset = mail_notification_preset, preset = mail_notification_preset,
text = string.format("%s has <b>%d</b> new message%s", mail, mailcount, mailcount == 1 and "" or "s") text = string.format(
} "%s has <b>%d</b> new message%s",
mail,
mailcount,
mailcount == 1 and "" or "s"
),
})
end end
helpers.set_map(mail, imap_now["UNSEEN"]) helpers.set_map(mail, imap_now["UNSEEN"])
end) end)
end end
imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true) imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true)

View file

@ -1,6 +1,6 @@
--[[ --[[
Lain Lina
Layouts, widgets and utilities for Awesome WM Layouts, widgets and utilities for Awesome WM
Widgets section Widgets section
@ -11,9 +11,9 @@
--]] --]]
local wrequire = require("lain.helpers").wrequire local wrequire = require("lina.helpers").wrequire
local setmetatable = setmetatable local setmetatable = setmetatable
local widget = { _NAME = "lain.widget" } local widget = { _NAME = "lina.widget" }
return setmetatable(widget, { __index = wrequire }) return setmetatable(widget, { __index = wrequire })

View file

@ -6,12 +6,12 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local wibox = require("wibox") local wibox = require("wibox")
local gmatch, lines, floor = string.gmatch, io.lines, math.floor local gmatch, lines, floor = string.gmatch, io.lines, math.floor
-- Memory usage (ignoring caches) -- Memory usage (ignoring caches)
-- lain.widget.mem -- lina.widget.mem
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -6,7 +6,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local shell = require("awful.util").shell local shell = require("awful.util").shell
local escape_f = require("awful.util").escape local escape_f = require("awful.util").escape
local focused = require("awful.screen").focused local focused = require("awful.screen").focused
@ -16,7 +16,7 @@ local os = os
local string = string local string = string
-- MPD infos -- MPD infos
-- lain.widget.mpd -- lina.widget.mpd
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -6,13 +6,13 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
local string = string local string = string
-- Network infos -- Network infos
-- lain.widget.net -- lina.widget.net
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -5,14 +5,14 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local shell = require("awful.util").shell local shell = require("awful.util").shell
local wibox = require("wibox") local wibox = require("wibox")
local string = string local string = string
local type = type local type = type
-- PulseAudio volume -- PulseAudio volume
-- lain.widget.pulse -- lina.widget.pulse
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -6,7 +6,7 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local awful = require("awful") local awful = require("awful")
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
@ -16,7 +16,7 @@ local type = type
local tonumber = tonumber local tonumber = tonumber
-- PulseAudio volume bar -- PulseAudio volume bar
-- lain.widget.pulsebar -- lina.widget.pulsebar
local function factory(args) local function factory(args)
local pulsebar = { local pulsebar = {

View file

@ -6,12 +6,12 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local wibox = require("wibox") local wibox = require("wibox")
local open, match = io.open, string.match local open, match = io.open, string.match
-- System load -- System load
-- lain.widget.sysload -- lina.widget.sysload
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -5,12 +5,12 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local wibox = require("wibox") local wibox = require("wibox")
local tonumber = tonumber local tonumber = tonumber
-- {thermal,core} temperature info -- {thermal,core} temperature info
-- lain.widget.temp -- lina.widget.temp
local function factory(args) local function factory(args)
args = args or {} args = args or {}

View file

@ -5,8 +5,8 @@
--]] --]]
local helpers = require("lain.helpers") local helpers = require("lina.helpers")
local json = require("lain.util").dkjson local json = require("lina.util").dkjson
local focused = require("awful.screen").focused local focused = require("awful.screen").focused
local naughty = require("naughty") local naughty = require("naughty")
local wibox = require("wibox") local wibox = require("wibox")
@ -18,7 +18,7 @@ local tonumber = tonumber
-- OpenWeatherMap -- OpenWeatherMap
-- current weather and X-days forecast -- current weather and X-days forecast
-- lain.widget.weather -- lina.widget.weather
local function factory(args) local function factory(args)
args = args or {} args = args or {}