Name change
This commit is contained in:
parent
3f23185a5c
commit
d96b3a1258
30 changed files with 938 additions and 835 deletions
|
@ -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 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.
|
||||
|
||||
|
|
10
helpers.lua
10
helpers.lua
|
@ -15,13 +15,13 @@ local rawget = rawget
|
|||
local tsort = table.sort
|
||||
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
|
||||
|
||||
-- Lain helper functions for internal use
|
||||
-- lain.helpers
|
||||
-- Lina helper functions for internal use
|
||||
-- lina.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/'
|
||||
helpers.lina_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
|
||||
helpers.icons_dir = helpers.lina_dir .. 'icons/'
|
||||
helpers.scripts_dir = helpers.lina_dir .. 'scripts/'
|
||||
|
||||
-- {{{ Modules loader
|
||||
|
||||
|
|
2
init.lua
2
init.lua
|
@ -1,6 +1,6 @@
|
|||
--[[
|
||||
|
||||
Lain
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Licensed under GNU General Public License v2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--[[
|
||||
|
||||
Lain
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Layouts section
|
||||
|
@ -11,9 +11,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local wrequire = require("lain.helpers").wrequire
|
||||
local wrequire = require("lina.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local layout = { _NAME = "lain.layout" }
|
||||
local layout = { _NAME = "lina.layout" }
|
||||
|
||||
return setmetatable(layout, { __index = wrequire })
|
||||
|
|
498
util/dkjson.lua
498
util/dkjson.lua
|
@ -1,7 +1,7 @@
|
|||
-- Module options:
|
||||
local always_use_lpeg = 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 floor, huge = math.floor, math.huge
|
||||
local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat =
|
||||
string.rep, string.gsub, string.sub, string.byte, string.char,
|
||||
string.find, string.len, string.format
|
||||
string.rep, string.gsub, string.sub, string.byte, string.char, string.find, string.len, string.format
|
||||
local strmatch = string.match
|
||||
local concat = table.concat
|
||||
|
||||
|
@ -66,27 +65,31 @@ end
|
|||
|
||||
_ENV = nil -- blocking globals in Lua 5.2 and later
|
||||
|
||||
pcall (function()
|
||||
pcall(function()
|
||||
-- Enable access to blocked metatables.
|
||||
-- Don't worry, this module doesn't change anything in them.
|
||||
local debmeta = require "debug".getmetatable
|
||||
if debmeta then getmetatable = debmeta end
|
||||
local debmeta = require("debug").getmetatable
|
||||
if debmeta then
|
||||
getmetatable = debmeta
|
||||
end
|
||||
end)
|
||||
|
||||
json.null = setmetatable ({}, {
|
||||
__tojson = function () return "null" end
|
||||
json.null = setmetatable({}, {
|
||||
__tojson = function()
|
||||
return "null"
|
||||
end,
|
||||
})
|
||||
|
||||
local function isarray (tbl)
|
||||
local function isarray(tbl)
|
||||
local max, n, arraylen = 0, 0, 0
|
||||
for k,v in pairs (tbl) do
|
||||
if k == 'n' and type(v) == 'number' then
|
||||
for k, v in pairs(tbl) do
|
||||
if k == "n" and type(v) == "number" then
|
||||
arraylen = v
|
||||
if v > max then
|
||||
max = v
|
||||
end
|
||||
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
|
||||
end
|
||||
if k > max then
|
||||
|
@ -102,16 +105,21 @@ local function isarray (tbl)
|
|||
end
|
||||
|
||||
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]
|
||||
if value then
|
||||
return value
|
||||
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
|
||||
if a <= 0x7f then
|
||||
value = a
|
||||
|
@ -125,49 +133,49 @@ local function escapeutf8 (uchar)
|
|||
return ""
|
||||
end
|
||||
if value <= 0xffff then
|
||||
return strformat ("\\u%.4x", value)
|
||||
return strformat("\\u%.4x", value)
|
||||
elseif value <= 0x10ffff then
|
||||
-- encode as UTF-16 surrogate pair
|
||||
value = value - 0x10000
|
||||
local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400)
|
||||
return strformat ("\\u%.4x\\u%.4x", highsur, lowsur)
|
||||
local highsur, lowsur = 0xD800 + floor(value / 0x400), 0xDC00 + (value % 0x400)
|
||||
return strformat("\\u%.4x\\u%.4x", highsur, lowsur)
|
||||
else
|
||||
return ""
|
||||
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
|
||||
-- exists. First using find should be more efficient when most strings
|
||||
-- don't contain the pattern.
|
||||
if strfind (str, pattern) then
|
||||
return gsub (str, pattern, repl)
|
||||
if strfind(str, pattern) then
|
||||
return gsub(str, pattern, repl)
|
||||
else
|
||||
return str
|
||||
end
|
||||
end
|
||||
|
||||
local function quotestring (value)
|
||||
local function quotestring(value)
|
||||
-- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js
|
||||
value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8)
|
||||
if strfind (value, "[\194\216\220\225\226\239]") then
|
||||
value = fsub (value, "\194[\128-\159\173]", escapeutf8)
|
||||
value = fsub (value, "\216[\128-\132]", escapeutf8)
|
||||
value = fsub (value, "\220\143", escapeutf8)
|
||||
value = fsub (value, "\225\158[\180\181]", escapeutf8)
|
||||
value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8)
|
||||
value = fsub (value, "\226\129[\160-\175]", escapeutf8)
|
||||
value = fsub (value, "\239\187\191", escapeutf8)
|
||||
value = fsub (value, "\239\191[\176-\191]", escapeutf8)
|
||||
value = fsub(value, '[%z\1-\31"\\\127]', escapeutf8)
|
||||
if strfind(value, "[\194\216\220\225\226\239]") then
|
||||
value = fsub(value, "\194[\128-\159\173]", escapeutf8)
|
||||
value = fsub(value, "\216[\128-\132]", escapeutf8)
|
||||
value = fsub(value, "\220\143", escapeutf8)
|
||||
value = fsub(value, "\225\158[\180\181]", escapeutf8)
|
||||
value = fsub(value, "\226\128[\140-\143\168-\175]", escapeutf8)
|
||||
value = fsub(value, "\226\129[\160-\175]", escapeutf8)
|
||||
value = fsub(value, "\239\187\191", escapeutf8)
|
||||
value = fsub(value, "\239\191[\176-\191]", escapeutf8)
|
||||
end
|
||||
return "\"" .. value .. "\""
|
||||
return '"' .. value .. '"'
|
||||
end
|
||||
json.quotestring = quotestring
|
||||
|
||||
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
|
||||
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
|
||||
return str
|
||||
end
|
||||
|
@ -176,7 +184,7 @@ end
|
|||
-- locale independent num2str and str2num functions
|
||||
local decpoint, numfilter
|
||||
|
||||
local function updatedecpoint ()
|
||||
local function updatedecpoint()
|
||||
decpoint = strmatch(tostring(0.5), "([^05+])")
|
||||
-- build a filter that can be used to remove group separators
|
||||
numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+"
|
||||
|
@ -184,11 +192,11 @@ end
|
|||
|
||||
updatedecpoint()
|
||||
|
||||
local function num2str (num)
|
||||
local function num2str(num)
|
||||
return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
|
||||
end
|
||||
|
||||
local function str2num (str)
|
||||
local function str2num(str)
|
||||
local num = tonumber(replace(str, ".", decpoint))
|
||||
if not num then
|
||||
updatedecpoint()
|
||||
|
@ -197,25 +205,24 @@ local function str2num (str)
|
|||
return num
|
||||
end
|
||||
|
||||
local function addnewline2 (level, buffer, buflen)
|
||||
buffer[buflen+1] = "\n"
|
||||
buffer[buflen+2] = strrep (" ", level)
|
||||
local function addnewline2(level, buffer, buflen)
|
||||
buffer[buflen + 1] = "\n"
|
||||
buffer[buflen + 2] = strrep(" ", level)
|
||||
buflen = buflen + 2
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.addnewline (state)
|
||||
function json.addnewline(state)
|
||||
if state.indent then
|
||||
state.bufferlen = addnewline2 (state.level or 0,
|
||||
state.buffer, state.bufferlen or #(state.buffer))
|
||||
state.bufferlen = addnewline2(state.level or 0, state.buffer, state.bufferlen or #state.buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local encode2 -- forward declaration
|
||||
|
||||
local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
local kt = type (key)
|
||||
if kt ~= 'string' and kt ~= 'number' then
|
||||
local function addpair(key, value, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
local kt = type(key)
|
||||
if kt ~= "string" and kt ~= "number" then
|
||||
return nil, "type '" .. kt .. "' is not supported as a key by JSON."
|
||||
end
|
||||
if prev then
|
||||
|
@ -223,16 +230,16 @@ local function addpair (key, value, prev, indent, level, buffer, buflen, tables,
|
|||
buffer[buflen] = ","
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level, buffer, buflen)
|
||||
buflen = addnewline2(level, buffer, buflen)
|
||||
end
|
||||
buffer[buflen+1] = quotestring (key)
|
||||
buffer[buflen+2] = ":"
|
||||
return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state)
|
||||
buffer[buflen + 1] = quotestring(key)
|
||||
buffer[buflen + 2] = ":"
|
||||
return encode2(value, indent, level, buffer, buflen + 2, tables, globalorder, state)
|
||||
end
|
||||
|
||||
local function appendcustom(res, buffer, state)
|
||||
local buflen = state.bufferlen
|
||||
if type (res) == 'string' then
|
||||
if type(res) == "string" then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = res
|
||||
end
|
||||
|
@ -246,8 +253,10 @@ local function exception(reason, value, state, buffer, buflen, defaultmessage)
|
|||
return nil, defaultmessage
|
||||
else
|
||||
state.bufferlen = buflen
|
||||
local ret, msg = handler (reason, value, state, defaultmessage)
|
||||
if not ret then return nil, msg or defaultmessage end
|
||||
local ret, msg = handler(reason, value, state, defaultmessage)
|
||||
if not ret then
|
||||
return nil, msg or defaultmessage
|
||||
end
|
||||
return appendcustom(ret, buffer, state)
|
||||
end
|
||||
end
|
||||
|
@ -256,48 +265,50 @@ function json.encodeexception(_reason, _value, _state, defaultmessage)
|
|||
return quotestring("<" .. defaultmessage .. ">")
|
||||
end
|
||||
|
||||
encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
local valtype = type (value)
|
||||
local valmeta = getmetatable (value)
|
||||
valmeta = type (valmeta) == 'table' and valmeta -- only tables
|
||||
encode2 = function(value, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
local valtype = type(value)
|
||||
local valmeta = getmetatable(value)
|
||||
valmeta = type(valmeta) == "table" and valmeta -- only tables
|
||||
local valtojson = valmeta and valmeta.__tojson
|
||||
if valtojson then
|
||||
if tables[value] then
|
||||
return exception('reference cycle', value, state, buffer, buflen)
|
||||
return exception("reference cycle", value, state, buffer, buflen)
|
||||
end
|
||||
tables[value] = true
|
||||
state.bufferlen = buflen
|
||||
local ret, msg = valtojson (value, state)
|
||||
if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end
|
||||
local ret, msg = valtojson(value, state)
|
||||
if not ret then
|
||||
return exception("custom encoder failed", value, state, buffer, buflen, msg)
|
||||
end
|
||||
tables[value] = nil
|
||||
buflen = appendcustom(ret, buffer, state)
|
||||
elseif value == nil then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "null"
|
||||
elseif valtype == 'number' then
|
||||
elseif valtype == "number" then
|
||||
local s
|
||||
if value ~= value or value >= huge or -value >= huge then
|
||||
-- This is the behaviour of the original JSON implementation.
|
||||
s = "null"
|
||||
else
|
||||
s = num2str (value)
|
||||
s = num2str(value)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = s
|
||||
elseif valtype == 'boolean' then
|
||||
elseif valtype == "boolean" then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = value and "true" or "false"
|
||||
elseif valtype == 'string' then
|
||||
elseif valtype == "string" then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = quotestring (value)
|
||||
elseif valtype == 'table' then
|
||||
buffer[buflen] = quotestring(value)
|
||||
elseif valtype == "table" then
|
||||
if tables[value] then
|
||||
return exception('reference cycle', value, state, buffer, buflen)
|
||||
return exception("reference cycle", value, state, buffer, buflen)
|
||||
end
|
||||
tables[value] = true
|
||||
level = level + 1
|
||||
local isa, n = isarray (value)
|
||||
if n == 0 and valmeta and valmeta.__jsontype == 'object' then
|
||||
local isa, n = isarray(value)
|
||||
if n == 0 and valmeta and valmeta.__jsontype == "object" then
|
||||
isa = false
|
||||
end
|
||||
local msg
|
||||
|
@ -305,8 +316,10 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
|
|||
buflen = buflen + 1
|
||||
buffer[buflen] = "["
|
||||
for i = 1, n do
|
||||
buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then return nil, msg end
|
||||
buflen, msg = encode2(value[i], indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then
|
||||
return nil, msg
|
||||
end
|
||||
if i < n then
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = ","
|
||||
|
@ -327,62 +340,80 @@ encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, s
|
|||
local v = value[k]
|
||||
if v ~= nil then
|
||||
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
|
||||
end
|
||||
end
|
||||
for k,v in pairs (value) do
|
||||
for k, v in pairs(value) do
|
||||
if not used[k] then
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then return nil, msg end
|
||||
buflen, msg = addpair(k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then
|
||||
return nil, msg
|
||||
end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
else -- unordered
|
||||
for k,v in pairs (value) do
|
||||
buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then return nil, msg end
|
||||
for k, v in pairs(value) do
|
||||
buflen, msg = addpair(k, v, prev, indent, level, buffer, buflen, tables, globalorder, state)
|
||||
if not buflen then
|
||||
return nil, msg
|
||||
end
|
||||
prev = true -- add a seperator before the next element
|
||||
end
|
||||
end
|
||||
if indent then
|
||||
buflen = addnewline2 (level - 1, buffer, buflen)
|
||||
buflen = addnewline2(level - 1, buffer, buflen)
|
||||
end
|
||||
buflen = buflen + 1
|
||||
buffer[buflen] = "}"
|
||||
end
|
||||
tables[value] = nil
|
||||
else
|
||||
return exception ('unsupported type', value, state, buffer, buflen,
|
||||
"type '" .. valtype .. "' is not supported by JSON.")
|
||||
return exception(
|
||||
"unsupported type",
|
||||
value,
|
||||
state,
|
||||
buffer,
|
||||
buflen,
|
||||
"type '" .. valtype .. "' is not supported by JSON."
|
||||
)
|
||||
end
|
||||
return buflen
|
||||
end
|
||||
|
||||
function json.encode (value, state)
|
||||
function json.encode(value, state)
|
||||
state = state or {}
|
||||
local oldbuffer = state.buffer
|
||||
local buffer = oldbuffer or {}
|
||||
state.buffer = buffer
|
||||
updatedecpoint()
|
||||
local ret, msg = encode2 (value, state.indent, state.level or 0,
|
||||
buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state)
|
||||
local ret, msg = encode2(
|
||||
value,
|
||||
state.indent,
|
||||
state.level or 0,
|
||||
buffer,
|
||||
state.bufferlen or 0,
|
||||
state.tables or {},
|
||||
state.keyorder,
|
||||
state
|
||||
)
|
||||
if not ret then
|
||||
error (msg, 2)
|
||||
error(msg, 2)
|
||||
elseif oldbuffer == buffer then
|
||||
state.bufferlen = ret
|
||||
return true
|
||||
else
|
||||
state.bufferlen = nil
|
||||
state.buffer = nil
|
||||
return concat (buffer)
|
||||
return concat(buffer)
|
||||
end
|
||||
end
|
||||
|
||||
local function loc (str, where)
|
||||
local function loc(str, where)
|
||||
local line, pos, linepos = 1, 1, 0
|
||||
while true do
|
||||
pos = strfind (str, "\n", pos, true)
|
||||
pos = strfind(str, "\n", pos, true)
|
||||
if pos and pos < where then
|
||||
line = line + 1
|
||||
linepos = pos
|
||||
|
@ -394,24 +425,30 @@ local function loc (str, where)
|
|||
return "line " .. line .. ", column " .. (where - linepos)
|
||||
end
|
||||
|
||||
local function unterminated (str, what, where)
|
||||
return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where)
|
||||
local function unterminated(str, what, where)
|
||||
return nil, strlen(str) + 1, "unterminated " .. what .. " at " .. loc(str, where)
|
||||
end
|
||||
|
||||
local function scanwhite (str, pos)
|
||||
local function scanwhite(str, pos)
|
||||
while true do
|
||||
pos = strfind (str, "%S", pos)
|
||||
if not pos then return nil end
|
||||
local sub2 = strsub (str, pos, pos + 1)
|
||||
if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then
|
||||
pos = strfind(str, "%S", pos)
|
||||
if not pos then
|
||||
return nil
|
||||
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
|
||||
pos = pos + 3
|
||||
elseif sub2 == "//" then
|
||||
pos = strfind (str, "[\n\r]", pos + 2)
|
||||
if not pos then return nil end
|
||||
pos = strfind(str, "[\n\r]", pos + 2)
|
||||
if not pos then
|
||||
return nil
|
||||
end
|
||||
elseif sub2 == "/*" then
|
||||
pos = strfind (str, "*/", pos + 2)
|
||||
if not pos then return nil end
|
||||
pos = strfind(str, "*/", pos + 2)
|
||||
if not pos then
|
||||
return nil
|
||||
end
|
||||
pos = pos + 2
|
||||
else
|
||||
return pos
|
||||
|
@ -420,59 +457,64 @@ local function scanwhite (str, pos)
|
|||
end
|
||||
|
||||
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
|
||||
return nil
|
||||
elseif value <= 0x007f then
|
||||
return strchar (value)
|
||||
return strchar(value)
|
||||
elseif value <= 0x07ff then
|
||||
return strchar (0xc0 + floor(value/0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
return strchar(0xc0 + floor(value / 0x40), 0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0xffff then
|
||||
return strchar (0xe0 + floor(value/0x1000),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
return strchar(0xe0 + floor(value / 0x1000), 0x80 + (floor(value / 0x40) % 0x40), 0x80 + (floor(value) % 0x40))
|
||||
elseif value <= 0x10ffff then
|
||||
return strchar (0xf0 + floor(value/0x40000),
|
||||
0x80 + (floor(value/0x1000) % 0x40),
|
||||
0x80 + (floor(value/0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40))
|
||||
return strchar(
|
||||
0xf0 + floor(value / 0x40000),
|
||||
0x80 + (floor(value / 0x1000) % 0x40),
|
||||
0x80 + (floor(value / 0x40) % 0x40),
|
||||
0x80 + (floor(value) % 0x40)
|
||||
)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function scanstring (str, pos)
|
||||
local function scanstring(str, pos)
|
||||
local lastpos = pos + 1
|
||||
local buffer, n = {}, 0
|
||||
while true do
|
||||
local nextpos = strfind (str, "[\"\\]", lastpos)
|
||||
local nextpos = strfind(str, '["\\]', lastpos)
|
||||
if not nextpos then
|
||||
return unterminated (str, "string", pos)
|
||||
return unterminated(str, "string", pos)
|
||||
end
|
||||
if nextpos > lastpos then
|
||||
n = n + 1
|
||||
buffer[n] = strsub (str, lastpos, nextpos - 1)
|
||||
buffer[n] = strsub(str, lastpos, nextpos - 1)
|
||||
end
|
||||
if strsub (str, nextpos, nextpos) == "\"" then
|
||||
if strsub(str, nextpos, nextpos) == '"' then
|
||||
lastpos = nextpos + 1
|
||||
break
|
||||
else
|
||||
local escchar = strsub (str, nextpos + 1, nextpos + 1)
|
||||
local escchar = strsub(str, nextpos + 1, nextpos + 1)
|
||||
local value
|
||||
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
|
||||
local value2
|
||||
if 0xD800 <= value and value <= 0xDBff then
|
||||
-- we have the high surrogate of UTF-16. Check if there is a
|
||||
-- low surrogate escaped nearby to combine them.
|
||||
if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then
|
||||
value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16)
|
||||
if strsub(str, nextpos + 6, nextpos + 7) == "\\u" then
|
||||
value2 = tonumber(strsub(str, nextpos + 8, nextpos + 11), 16)
|
||||
if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
|
||||
value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
|
||||
else
|
||||
|
@ -480,7 +522,7 @@ local function scanstring (str, pos)
|
|||
end
|
||||
end
|
||||
end
|
||||
value = value and unichar (value)
|
||||
value = value and unichar(value)
|
||||
if value then
|
||||
if value2 then
|
||||
lastpos = nextpos + 12
|
||||
|
@ -501,7 +543,7 @@ local function scanstring (str, pos)
|
|||
if n == 1 then
|
||||
return buffer[1], lastpos
|
||||
elseif n > 1 then
|
||||
return concat (buffer), lastpos
|
||||
return concat(buffer), lastpos
|
||||
else
|
||||
return "", lastpos
|
||||
end
|
||||
|
@ -509,40 +551,52 @@ end
|
|||
|
||||
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 pos = startpos + 1
|
||||
if what == 'object' then
|
||||
setmetatable (tbl, objectmeta)
|
||||
if what == "object" then
|
||||
setmetatable(tbl, objectmeta)
|
||||
else
|
||||
setmetatable (tbl, arraymeta)
|
||||
setmetatable(tbl, arraymeta)
|
||||
end
|
||||
while true do
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local char = strsub (str, pos, pos)
|
||||
pos = scanwhite(str, pos)
|
||||
if not pos then
|
||||
return unterminated(str, what, startpos)
|
||||
end
|
||||
local char = strsub(str, pos, pos)
|
||||
if char == closechar then
|
||||
return tbl, pos + 1
|
||||
end
|
||||
local val1, err
|
||||
val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
char = strsub (str, pos, pos)
|
||||
val1, pos, err = scanvalue(str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then
|
||||
return nil, pos, err
|
||||
end
|
||||
pos = scanwhite(str, pos)
|
||||
if not pos then
|
||||
return unterminated(str, what, startpos)
|
||||
end
|
||||
char = strsub(str, pos, pos)
|
||||
if char == ":" 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
|
||||
pos = scanwhite (str, pos + 1)
|
||||
if not pos then return unterminated (str, what, startpos) end
|
||||
local val2
|
||||
val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then return nil, pos, err end
|
||||
val2, pos, err = scanvalue(str, pos, nullval, objectmeta, arraymeta)
|
||||
if err then
|
||||
return nil, pos, err
|
||||
end
|
||||
tbl[val1] = val2
|
||||
pos = scanwhite (str, pos)
|
||||
if not pos then return unterminated (str, what, startpos) 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)
|
||||
else
|
||||
n = n + 1
|
||||
tbl[n] = val1
|
||||
|
@ -553,30 +607,30 @@ local function scantable (what, closechar, str, startpos, nullval, objectmeta, a
|
|||
end
|
||||
end
|
||||
|
||||
scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
|
||||
scanvalue = function(str, pos, nullval, objectmeta, arraymeta)
|
||||
pos = pos or 1
|
||||
pos = scanwhite (str, pos)
|
||||
pos = scanwhite(str, pos)
|
||||
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
|
||||
local char = strsub (str, pos, pos)
|
||||
local char = strsub(str, pos, pos)
|
||||
if char == "{" then
|
||||
return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta)
|
||||
return scantable("object", "}", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "[" then
|
||||
return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == "\"" then
|
||||
return scanstring (str, pos)
|
||||
return scantable("array", "]", str, pos, nullval, objectmeta, arraymeta)
|
||||
elseif char == '"' then
|
||||
return scanstring(str, pos)
|
||||
else
|
||||
local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
|
||||
local pstart, pend = strfind(str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
|
||||
if pstart then
|
||||
local number = str2num (strsub (str, pstart, pend))
|
||||
local number = str2num(strsub(str, pstart, pend))
|
||||
if number then
|
||||
return number, pend + 1
|
||||
end
|
||||
end
|
||||
pstart, pend = strfind (str, "^%a%w*", pos)
|
||||
pstart, pend = strfind(str, "^%a%w*", pos)
|
||||
if pstart then
|
||||
local name = strsub (str, pstart, pend)
|
||||
local name = strsub(str, pstart, pend)
|
||||
if name == "true" then
|
||||
return true, pend + 1
|
||||
elseif name == "false" then
|
||||
|
@ -585,7 +639,7 @@ scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
|
|||
return nullval, pend + 1
|
||||
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
|
||||
|
||||
|
@ -593,125 +647,132 @@ local function optionalmetatables(...)
|
|||
if select("#", ...) > 0 then
|
||||
return ...
|
||||
else
|
||||
return {__jsontype = 'object'}, {__jsontype = 'array'}
|
||||
return { __jsontype = "object" }, { __jsontype = "array" }
|
||||
end
|
||||
end
|
||||
|
||||
function json.decode (str, pos, nullval, ...)
|
||||
function json.decode(str, pos, nullval, ...)
|
||||
local objectmeta, arraymeta = optionalmetatables(...)
|
||||
return scanvalue (str, pos, nullval, objectmeta, arraymeta)
|
||||
return scanvalue(str, pos, nullval, objectmeta, arraymeta)
|
||||
end
|
||||
|
||||
function json.use_lpeg ()
|
||||
local g = require ("lpeg")
|
||||
function json.use_lpeg()
|
||||
local g = require("lpeg")
|
||||
|
||||
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
|
||||
|
||||
local pegmatch = g.match
|
||||
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
|
||||
state.msg = msg .. " at " .. loc (str, pos)
|
||||
state.msg = msg .. " at " .. loc(str, pos)
|
||||
state.pos = pos
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function Err (msg)
|
||||
return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
|
||||
local function Err(msg)
|
||||
return g.Cmt(g.Cc(msg) * g.Carg(2), ErrorCall)
|
||||
end
|
||||
|
||||
local function ErrorUnterminatedCall (str, pos, what, state)
|
||||
return ErrorCall (str, pos - 1, "unterminated " .. what, state)
|
||||
local function ErrorUnterminatedCall(str, pos, what, state)
|
||||
return ErrorCall(str, pos - 1, "unterminated " .. what, state)
|
||||
end
|
||||
|
||||
local SingleLineComment = P"//" * (1 - S"\n\r")^0
|
||||
local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/"
|
||||
local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0
|
||||
local SingleLineComment = P("//") * (1 - S("\n\r")) ^ 0
|
||||
local MultiLineComment = P("/*") * (1 - P("*/")) ^ 0 * P("*/")
|
||||
local Space = (S(" \n\r\t") + P("\239\187\191") + SingleLineComment + MultiLineComment) ^ 0
|
||||
|
||||
local function ErrUnterminated (what)
|
||||
return g.Cmt (g.Cc (what) * g.Carg (2), ErrorUnterminatedCall)
|
||||
local function ErrUnterminated(what)
|
||||
return g.Cmt(g.Cc(what) * g.Carg(2), ErrorUnterminatedCall)
|
||||
end
|
||||
|
||||
local PlainChar = 1 - S"\"\\\n\r"
|
||||
local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars
|
||||
local PlainChar = 1 - S('"\\\n\r')
|
||||
local EscapeSequence = (P("\\") * g.C(S('"\\/bfnrt') + Err("unsupported escape sequence"))) / escapechars
|
||||
local HexDigit = R("09", "af", "AF")
|
||||
local function UTF16Surrogate (_match, _pos, high, low)
|
||||
high, low = tonumber (high, 16), tonumber (low, 16)
|
||||
local function UTF16Surrogate(_match, _pos, high, low)
|
||||
high, low = tonumber(high, 16), tonumber(low, 16)
|
||||
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
|
||||
return false
|
||||
end
|
||||
end
|
||||
local function UTF16BMP (hex)
|
||||
return unichar (tonumber (hex, 16))
|
||||
local function UTF16BMP(hex)
|
||||
return unichar(tonumber(hex, 16))
|
||||
end
|
||||
local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit))
|
||||
local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP
|
||||
local U16Sequence = (P("\\u") * g.C(HexDigit * HexDigit * HexDigit * HexDigit))
|
||||
local UnicodeEscape = g.Cmt(U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence / UTF16BMP
|
||||
local Char = UnicodeEscape + EscapeSequence + PlainChar
|
||||
local String = P"\"" * (g.Cs (Char ^ 0) * P"\"" + ErrUnterminated "string")
|
||||
local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0))
|
||||
local Fractal = P"." * R"09"^0
|
||||
local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1
|
||||
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 String = P('"') * (g.Cs(Char ^ 0) * P('"') + ErrUnterminated("string"))
|
||||
local Integer = P("-") ^ -1 * (P("0") + (R("19") * R("09") ^ 0))
|
||||
local Fractal = P(".") * R("09") ^ 0
|
||||
local Exponent = (S("eE")) * (S("+-")) ^ -1 * R("09") ^ 1
|
||||
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 SimpleValue = Number + String + Constant
|
||||
local ArrayContent, ObjectContent
|
||||
|
||||
-- The functions parsearray and parseobject parse only a single value/pair
|
||||
-- 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 start = pos
|
||||
local npos
|
||||
local t, nt = {}, 0
|
||||
repeat
|
||||
obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
|
||||
if cont == 'end' then
|
||||
return ErrorUnterminatedCall (str, start, "array", state)
|
||||
obj, cont, npos = pegmatch(ArrayContent, str, pos, nullval, state)
|
||||
if cont == "end" then
|
||||
return ErrorUnterminatedCall(str, start, "array", state)
|
||||
end
|
||||
pos = npos
|
||||
if cont == 'cont' or cont == 'last' then
|
||||
if cont == "cont" or cont == "last" then
|
||||
nt = nt + 1
|
||||
t[nt] = obj
|
||||
end
|
||||
until cont ~= 'cont'
|
||||
return pos, setmetatable (t, state.arraymeta)
|
||||
until cont ~= "cont"
|
||||
return pos, setmetatable(t, state.arraymeta)
|
||||
end
|
||||
|
||||
local function parseobject (str, pos, nullval, state)
|
||||
local function parseobject(str, pos, nullval, state)
|
||||
local obj, key, cont
|
||||
local start = pos
|
||||
local npos
|
||||
local t = {}
|
||||
repeat
|
||||
key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
|
||||
if cont == 'end' then
|
||||
return ErrorUnterminatedCall (str, start, "object", state)
|
||||
key, obj, cont, npos = pegmatch(ObjectContent, str, pos, nullval, state)
|
||||
if cont == "end" then
|
||||
return ErrorUnterminatedCall(str, start, "object", state)
|
||||
end
|
||||
pos = npos
|
||||
if cont == 'cont' or cont == 'last' then
|
||||
if cont == "cont" or cont == "last" then
|
||||
t[key] = obj
|
||||
end
|
||||
until cont ~= 'cont'
|
||||
return pos, setmetatable (t, state.objectmeta)
|
||||
until cont ~= "cont"
|
||||
return pos, setmetatable(t, state.objectmeta)
|
||||
end
|
||||
|
||||
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 Array = P("[") * g.Cmt(g.Carg(1) * g.Carg(2), parsearray)
|
||||
local Object = P("{") * g.Cmt(g.Carg(1) * g.Carg(2), parseobject)
|
||||
local Value = Space * (Array + Object + SimpleValue)
|
||||
local ExpectedValue = Value + Space * Err "value expected"
|
||||
local ExpectedKey = String + Err "key expected"
|
||||
local End = P(-1) * g.Cc'end'
|
||||
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()
|
||||
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 ()
|
||||
local ExpectedValue = Value + Space * Err("value expected")
|
||||
local ExpectedKey = String + Err("key expected")
|
||||
local End = P(-1) * g.Cc("end")
|
||||
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()
|
||||
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.encode = json.encode
|
||||
|
@ -721,10 +782,10 @@ function json.use_lpeg ()
|
|||
jsonlpeg.encodeexception = json.encodeexception
|
||||
jsonlpeg.using_lpeg = true
|
||||
|
||||
function jsonlpeg.decode (str, pos, nullval, ...)
|
||||
function jsonlpeg.decode(str, pos, nullval, ...)
|
||||
local state = {}
|
||||
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
|
||||
return nil, state.pos, state.msg
|
||||
else
|
||||
|
@ -733,7 +794,9 @@ function json.use_lpeg ()
|
|||
end
|
||||
|
||||
-- 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
|
||||
|
||||
return jsonlpeg
|
||||
|
@ -744,4 +807,3 @@ if always_use_lpeg then
|
|||
end
|
||||
|
||||
return json
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--[[
|
||||
|
||||
Lain
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Utilities section
|
||||
|
@ -19,43 +19,51 @@ local tonumber = tonumber
|
|||
local wrequire = require("lina.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- Lain utilities submodule
|
||||
-- lain.util
|
||||
local util = { _NAME = "lain.util" }
|
||||
-- Lina utilities submodule
|
||||
-- lina.util
|
||||
local util = { _NAME = "lina.util" }
|
||||
|
||||
-- Like awful.menu.clients, but only show clients of currently selected tags
|
||||
function util.menu_clients_current_tags(menu, args)
|
||||
-- List of currently 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.
|
||||
local cls_t = {}
|
||||
|
||||
-- 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.
|
||||
for i = 1,#cls_tags do
|
||||
for i = 1, #cls_tags do
|
||||
local t = cls_tags[i]
|
||||
local cls = t:clients()
|
||||
|
||||
for _, c in pairs(cls) do
|
||||
cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "",
|
||||
function ()
|
||||
cls_t[#cls_t + 1] = {
|
||||
awful.util.escape(c.name) or "",
|
||||
function()
|
||||
c.minimized = false
|
||||
client.focus = c
|
||||
c:raise()
|
||||
end,
|
||||
c.icon }
|
||||
c.icon,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- fresh menu.
|
||||
if not menu then menu = {} end
|
||||
if not menu then
|
||||
menu = {}
|
||||
end
|
||||
|
||||
-- Set the list of items and show the menu.
|
||||
menu.items = cls_t
|
||||
|
@ -79,7 +87,9 @@ end
|
|||
-- https://github.com/lcpz/lain/issues/195
|
||||
function util.mc(c, width_f, height_f)
|
||||
c = c or util.magnified_client
|
||||
if not c then return end
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
|
||||
c.floating = true
|
||||
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.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
|
||||
|
||||
-- Non-empty tag browsing
|
||||
-- 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
|
||||
local s = sc or awful.screen.focused()
|
||||
local tags = s.tags
|
||||
|
@ -133,29 +145,35 @@ end
|
|||
|
||||
-- Add a new tag
|
||||
function util.add_tag(layout)
|
||||
awful.prompt.run {
|
||||
awful.prompt.run({
|
||||
prompt = "New tag name: ",
|
||||
textbox = awful.screen.focused().mypromptbox.widget,
|
||||
exe_callback = function(name)
|
||||
if not name or #name == 0 then return end
|
||||
awful.tag.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile }):view_only()
|
||||
if not name or #name == 0 then
|
||||
return
|
||||
end
|
||||
}
|
||||
awful.tag
|
||||
.add(name, { screen = awful.screen.focused(), layout = layout or awful.layout.suit.tile })
|
||||
:view_only()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Rename current tag
|
||||
function util.rename_tag()
|
||||
awful.prompt.run {
|
||||
awful.prompt.run({
|
||||
prompt = "Rename tag: ",
|
||||
textbox = awful.screen.focused().mypromptbox.widget,
|
||||
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
|
||||
if t then
|
||||
t.name = new_name
|
||||
end
|
||||
end
|
||||
}
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
-- Move current tag
|
||||
|
@ -173,7 +191,9 @@ end
|
|||
-- Any rule set on the tag shall be broken
|
||||
function util.delete_tag()
|
||||
local t = awful.screen.focused().selected_tag
|
||||
if not t then return end
|
||||
if not t then
|
||||
return
|
||||
end
|
||||
t:delete()
|
||||
end
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
local format = string.format
|
||||
local setmetatable = setmetatable
|
||||
|
||||
-- Lain markup util submodule
|
||||
-- lain.util.markup
|
||||
-- Lina markup util submodule
|
||||
-- lina.util.markup
|
||||
local markup = { fg = {}, bg = {} }
|
||||
|
||||
-- Convenience tags
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
--]]
|
||||
|
||||
-- Menu iterator with Naughty notifications
|
||||
-- lain.util.menu_iterator
|
||||
-- lina.util.menu_iterator
|
||||
|
||||
local naughty = require("naughty")
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local atable = require("awful.util").table
|
||||
local assert = assert
|
||||
local pairs = pairs
|
||||
|
|
|
@ -10,8 +10,8 @@ local wibox = require("wibox")
|
|||
local gears = require("gears")
|
||||
local beautiful = require("beautiful")
|
||||
|
||||
-- Lain Cairo separators util submodule
|
||||
-- lain.util.separators
|
||||
-- Lina Cairo separators util submodule
|
||||
-- lina.util.separators
|
||||
local separators = { height = beautiful.separators_height or 0, width = beautiful.separators_width or 9 }
|
||||
|
||||
-- [[ Arrow
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
|
||||
-- ALSA volume
|
||||
-- lain.widget.alsa
|
||||
-- lina.widget.alsa
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -16,7 +16,7 @@ local type = type
|
|||
local tonumber = tonumber
|
||||
|
||||
-- ALSA volume bar
|
||||
-- lain.widget.alsabar
|
||||
-- lina.widget.alsabar
|
||||
|
||||
local function factory(args)
|
||||
local alsabar = {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local fs = require("gears.filesystem")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -16,13 +16,13 @@ local ipairs = ipairs
|
|||
local tonumber = tonumber
|
||||
|
||||
-- Battery infos
|
||||
-- lain.widget.bat
|
||||
-- lina.widget.bat
|
||||
|
||||
local function factory(args)
|
||||
local pspath = args.pspath or "/sys/class/power_supply/"
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local markup = require("lain.util.markup")
|
||||
local helpers = require("lina.helpers")
|
||||
local markup = require("lina.util.markup")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local floor = math.floor
|
||||
|
@ -19,7 +19,7 @@ local tonumber = tonumber
|
|||
local tostring = tostring
|
||||
|
||||
-- Calendar notification
|
||||
-- lain.widget.cal
|
||||
-- lina.widget.cal
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--[[
|
||||
|
||||
Lain
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Users contributed widgets section
|
||||
|
@ -10,9 +10,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local wrequire = require("lain.helpers").wrequire
|
||||
local wrequire = require("lina.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local widget = { _NAME = "lain.widget.contrib" }
|
||||
local widget = { _NAME = "lina.widget.contrib" }
|
||||
|
||||
return setmetatable(widget, { __index = wrequire })
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local focused = require("awful.screen").focused
|
||||
local escape_f = require("awful.util").escape
|
||||
|
@ -15,7 +15,7 @@ local os = os
|
|||
local string = string
|
||||
|
||||
-- MOC audio player
|
||||
-- lain.widget.contrib.moc
|
||||
-- lina.widget.contrib.moc
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
--]]
|
||||
|
||||
local async = require("lain.helpers").async
|
||||
local async = require("lina.helpers").async
|
||||
local awful = require("awful")
|
||||
local execute = os.execute
|
||||
local type = type
|
||||
|
||||
-- Redshift
|
||||
-- lain.widget.contrib.redshift
|
||||
-- lina.widget.contrib.redshift
|
||||
local redshift = { active = false, pid = nil }
|
||||
|
||||
function redshift.start()
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local markup = require("lain.util").markup
|
||||
local helpers = require("lina.helpers")
|
||||
local markup = require("lina.util").markup
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local mouse = mouse
|
||||
|
||||
-- Taskwarrior notification
|
||||
-- lain.widget.contrib.task
|
||||
-- lina.widget.contrib.task
|
||||
local task = {}
|
||||
|
||||
function task.hide()
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local focused = require("awful.screen").focused
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -15,7 +15,7 @@ local type = type
|
|||
|
||||
-- ThinkPad battery infos and widget creator
|
||||
-- http://www.thinkwiki.org/wiki/Tp_smapi
|
||||
-- lain.widget.contrib.tp_smapi
|
||||
-- lina.widget.contrib.tp_smapi
|
||||
|
||||
local function factory(apipath)
|
||||
local tp_smapi = {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local math = math
|
||||
local string = string
|
||||
|
||||
-- CPU usage
|
||||
-- lain.widget.cpu
|
||||
-- lina.widget.cpu
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local Gio = require("lgi").Gio
|
||||
local focused = require("awful.screen").focused
|
||||
local wibox = require("wibox")
|
||||
|
@ -23,7 +23,7 @@ local query_used = Gio.FILE_ATTRIBUTE_FILESYSTEM_USED
|
|||
local query = query_size .. "," .. query_free .. "," .. query_used
|
||||
|
||||
-- File systems info
|
||||
-- lain.widget.fs
|
||||
-- lina.widget.fs
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local awful = require("awful")
|
||||
|
@ -14,7 +14,7 @@ local type = type
|
|||
local tonumber = tonumber
|
||||
|
||||
-- Mail IMAP check
|
||||
-- lain.widget.imap
|
||||
-- lina.widget.imap
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
@ -34,18 +34,22 @@ local function factory(args)
|
|||
local head_command = "curl --connect-timeout 3 -fsm 3"
|
||||
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 = {
|
||||
icon = helpers.icons_dir .. "mail.png",
|
||||
position = "top_left"
|
||||
position = "top_left",
|
||||
}
|
||||
|
||||
helpers.set_map(mail, 0)
|
||||
|
||||
if not is_plain 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
|
||||
imap.pwdtimer = helpers.newtimer(mail .. "-password", pwdtimeout, function()
|
||||
local retrieved_password, try_again = password()
|
||||
|
@ -59,31 +63,48 @@ local function factory(args)
|
|||
|
||||
function imap.update()
|
||||
-- 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",
|
||||
head_command, server, port, mail, password, request)
|
||||
local curl = string.format(
|
||||
"%s --url imaps://%s:%s/INBOX -u %s:'%s' %s -k",
|
||||
head_command,
|
||||
server,
|
||||
port,
|
||||
mail,
|
||||
password,
|
||||
request
|
||||
)
|
||||
|
||||
helpers.async(curl, function(f)
|
||||
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
|
||||
widget = imap.widget
|
||||
|
||||
settings()
|
||||
|
||||
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
|
||||
naughty.notify {
|
||||
if followtag then
|
||||
mail_notification_preset.screen = awful.screen.focused()
|
||||
end
|
||||
naughty.notify({
|
||||
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
|
||||
|
||||
helpers.set_map(mail, imap_now["UNSEEN"])
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--[[
|
||||
|
||||
Lain
|
||||
Lina
|
||||
Layouts, widgets and utilities for Awesome WM
|
||||
|
||||
Widgets section
|
||||
|
@ -11,9 +11,9 @@
|
|||
|
||||
--]]
|
||||
|
||||
local wrequire = require("lain.helpers").wrequire
|
||||
local wrequire = require("lina.helpers").wrequire
|
||||
local setmetatable = setmetatable
|
||||
|
||||
local widget = { _NAME = "lain.widget" }
|
||||
local widget = { _NAME = "lina.widget" }
|
||||
|
||||
return setmetatable(widget, { __index = wrequire })
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local gmatch, lines, floor = string.gmatch, io.lines, math.floor
|
||||
|
||||
-- Memory usage (ignoring caches)
|
||||
-- lain.widget.mem
|
||||
-- lina.widget.mem
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local escape_f = require("awful.util").escape
|
||||
local focused = require("awful.screen").focused
|
||||
|
@ -16,7 +16,7 @@ local os = os
|
|||
local string = string
|
||||
|
||||
-- MPD infos
|
||||
-- lain.widget.mpd
|
||||
-- lina.widget.mpd
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
|
||||
-- Network infos
|
||||
-- lain.widget.net
|
||||
-- lina.widget.net
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local shell = require("awful.util").shell
|
||||
local wibox = require("wibox")
|
||||
local string = string
|
||||
local type = type
|
||||
|
||||
-- PulseAudio volume
|
||||
-- lain.widget.pulse
|
||||
-- lina.widget.pulse
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local awful = require("awful")
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -16,7 +16,7 @@ local type = type
|
|||
local tonumber = tonumber
|
||||
|
||||
-- PulseAudio volume bar
|
||||
-- lain.widget.pulsebar
|
||||
-- lina.widget.pulsebar
|
||||
|
||||
local function factory(args)
|
||||
local pulsebar = {
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local open, match = io.open, string.match
|
||||
|
||||
-- System load
|
||||
-- lain.widget.sysload
|
||||
-- lina.widget.sysload
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local helpers = require("lina.helpers")
|
||||
local wibox = require("wibox")
|
||||
local tonumber = tonumber
|
||||
|
||||
-- {thermal,core} temperature info
|
||||
-- lain.widget.temp
|
||||
-- lina.widget.temp
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
--]]
|
||||
|
||||
local helpers = require("lain.helpers")
|
||||
local json = require("lain.util").dkjson
|
||||
local helpers = require("lina.helpers")
|
||||
local json = require("lina.util").dkjson
|
||||
local focused = require("awful.screen").focused
|
||||
local naughty = require("naughty")
|
||||
local wibox = require("wibox")
|
||||
|
@ -18,7 +18,7 @@ local tonumber = tonumber
|
|||
|
||||
-- OpenWeatherMap
|
||||
-- current weather and X-days forecast
|
||||
-- lain.widget.weather
|
||||
-- lina.widget.weather
|
||||
|
||||
local function factory(args)
|
||||
args = args or {}
|
||||
|
|
Loading…
Add table
Reference in a new issue