diff --git a/awesome/freedesktop/desktop.lua b/awesome/freedesktop/desktop.lua
index 676ebdb..b5fdb37 100644
--- a/awesome/freedesktop/desktop.lua
+++ b/awesome/freedesktop/desktop.lua
@@ -11,44 +11,44 @@
--]]
-local awful = require("awful")
-local theme = require("beautiful")
-local utils = require("menubar.utils")
-local wibox = require("wibox")
+local awful = require('awful')
+local theme = require('beautiful')
+local utils = require('menubar.utils')
+local wibox = require('wibox')
-local io = io
+local io = io
local ipairs = ipairs
-local mouse = mouse
-local os = os
+local mouse = mouse
+local os = os
local string = string
local screen = screen
-local table = table
+local table = table
-- Desktop icons
-- freedesktop.desktop
local desktop = {
- -- Default desktop basic icons
- baseicons = {
- [1] = {
- label = "This PC",
- icon = "computer",
- onclick = "computer://"
- },
- [2] = {
- label = "Home",
- icon = "user-home",
- onclick = os.getenv("HOME")
- },
- [3] = {
- label = "Trash",
- icon = "user-trash",
- onclick = "trash://"
- }
- },
- -- Default parameters
- iconsize = { width = 48, height = 48 },
- labelsize = { width = 140, height = 20 },
- margin = { x = 20, y = 20 },
+ -- Default desktop basic icons
+ baseicons = {
+ [1] = {
+ label = 'This PC',
+ icon = 'computer',
+ onclick = 'computer://',
+ },
+ [2] = {
+ label = 'Home',
+ icon = 'user-home',
+ onclick = os.getenv('HOME'),
+ },
+ [3] = {
+ label = 'Trash',
+ icon = 'user-trash',
+ onclick = 'trash://',
+ },
+ },
+ -- Default parameters
+ iconsize = { width = 48, height = 48 },
+ labelsize = { width = 140, height = 20 },
+ margin = { x = 20, y = 20 },
}
-- MIME types list
@@ -59,12 +59,14 @@ desktop.current_pos = {}
-- @return iterator on input pipe
local function pipelines(...)
- local f = assert(io.popen(...))
- return function ()
- local data = f:read()
- if data == nil then f:close() end
- return data
- end
+ local f = assert(io.popen(...))
+ return function()
+ local data = f:read()
+ if data == nil then
+ f:close()
+ end
+ return data
+ end
end
-- Adds an icon to desktop
@@ -73,187 +75,198 @@ end
-- @param icon icon string file path
-- @param onclick function to execute on click
function desktop.add_single_icon(args, label, icon, onclick)
- local s = args.screen
- local dcp = desktop.current_pos
+ local s = args.screen
+ local dcp = desktop.current_pos
- -- define icon dimensions and position
- if not dcp[s] then
- dcp[s] = { x = (screen[s].geometry.x + args.iconsize.width + args.margin.x), y = screen[s].geometry.y + 20 + args.margin.y }
- end
+ -- define icon dimensions and position
+ if not dcp[s] then
+ dcp[s] = {
+ x = (screen[s].geometry.x + args.iconsize.width + args.margin.x),
+ y = screen[s].geometry.y + 20 + args.margin.y,
+ }
+ end
- local tot_height = (icon and args.iconsize.height or 0) + (label and args.labelsize.height or 0)
- if tot_height == 0 then return end
+ local tot_height = (icon and args.iconsize.height or 0) + (label and args.labelsize.height or 0)
+ if tot_height == 0 then
+ return
+ end
- if dcp[s].y + tot_height > screen[s].geometry.y + screen[s].geometry.height - 20 - args.margin.y then
- dcp[s].x = dcp[s].x + args.labelsize.width + args.iconsize.width + args.margin.x
- dcp[s].y = 20 + args.margin.y
- end
+ if dcp[s].y + tot_height > screen[s].geometry.y + screen[s].geometry.height - 20 - args.margin.y then
+ dcp[s].x = dcp[s].x + args.labelsize.width + args.iconsize.width + args.margin.x
+ dcp[s].y = 20 + args.margin.y
+ end
- local common = { screen = s, bg = "#00000000", visible = true, type = "desktop" }
+ local common = { screen = s, bg = '#00000000', visible = true, type = 'desktop' }
- -- create icon container
- if icon then
- common.width = args.iconsize.width
- common.height = args.iconsize.height
- common.x = dcp[s].x
- common.y = dcp[s].y
+ -- create icon container
+ if icon then
+ common.width = args.iconsize.width
+ common.height = args.iconsize.height
+ common.x = dcp[s].x
+ common.y = dcp[s].y
- icon = wibox.widget {
- image = icon,
- resize = false,
- widget = wibox.widget.imagebox
- }
+ icon = wibox.widget({
+ image = icon,
+ resize = false,
+ widget = wibox.widget.imagebox,
+ })
- icon:buttons(awful.button({ }, 1, nil, onclick))
+ icon:buttons(awful.button({}, 1, nil, onclick))
- icon_container = wibox(common)
- icon_container:set_widget(icon)
+ icon_container = wibox(common)
+ icon_container:set_widget(icon)
- dcp[s].y = dcp[s].y + args.iconsize.height + 5
- end
+ dcp[s].y = dcp[s].y + args.iconsize.height + 5
+ end
- -- create label container
- if label then
- common.width = args.labelsize.width
- common.height = args.labelsize.height
- common.x = dcp[s].x - (args.labelsize.width/2) + args.iconsize.width/2
- common.y = dcp[s].y
+ -- create label container
+ if label then
+ common.width = args.labelsize.width
+ common.height = args.labelsize.height
+ common.x = dcp[s].x - (args.labelsize.width / 2) + args.iconsize.width / 2
+ common.y = dcp[s].y
- caption = wibox.widget {
- text = label,
- align = "center",
- forced_width = common.width,
- forced_height = common.height,
- ellipsize = "middle",
- widget = wibox.widget.textbox
- }
+ caption = wibox.widget({
+ text = label,
+ align = 'center',
+ forced_width = common.width,
+ forced_height = common.height,
+ ellipsize = 'middle',
+ widget = wibox.widget.textbox,
+ })
- caption:buttons(awful.button({ }, 1, onclick))
- caption_container = wibox(common)
- caption_container:set_widget(caption)
- end
+ caption:buttons(awful.button({}, 1, onclick))
+ caption_container = wibox(common)
+ caption_container:set_widget(caption)
+ end
- dcp[s].y = dcp[s].y + args.labelsize.height + args.margin.y
+ dcp[s].y = dcp[s].y + args.labelsize.height + args.margin.y
- desktop.current_pos = dcp
+ desktop.current_pos = dcp
- return dcp
+ return dcp
end
-- Adds base icons (This PC, Trash, etc) to desktop
-- @param args settings from desktop.add_icons
function desktop.add_base_icons(args)
- for _,base in ipairs(args.baseicons) do
- desktop.add_single_icon(args, base.label, utils.lookup_icon(base.icon), function()
- awful.spawn(string.format("%s '%s'", args.open_with, base.onclick))
- end)
- end
+ for _, base in ipairs(args.baseicons) do
+ desktop.add_single_icon(args, base.label, utils.lookup_icon(base.icon), function()
+ awful.spawn(string.format("%s '%s'", args.open_with, base.onclick))
+ end)
+ end
end
-- Looks up a suitable icon for filename
-- @param filename string file name
-- @return icon file path (string)
function desktop.lookup_file_icon(filename)
- -- load system MIME types
- if #mime_types == 0 then
- for line in io.lines("/etc/mime.types") do
- if not line:find("^#") then
- local parsed = {}
- for w in line:gmatch("[^%s]+") do
- table.insert(parsed, w)
- end
- if #parsed > 1 then
- for i = 2, #parsed do
- mime_types[parsed[i]] = parsed[1]:gsub("/", "-")
- end
- end
- end
- end
- end
+ -- load system MIME types
+ if #mime_types == 0 then
+ for line in io.lines('/etc/mime.types') do
+ if not line:find('^#') then
+ local parsed = {}
+ for w in line:gmatch('[^%s]+') do
+ table.insert(parsed, w)
+ end
+ if #parsed > 1 then
+ for i = 2, #parsed do
+ mime_types[parsed[i]] = parsed[1]:gsub('/', '-')
+ end
+ end
+ end
+ end
+ end
- -- try to search a possible icon among standards
- local extension = filename:match("%a+$")
- local mime = mime_types[extension] or ""
- local mime_family = mime:match("^%a+") or ""
+ -- try to search a possible icon among standards
+ local extension = filename:match('%a+$')
+ local mime = mime_types[extension] or ''
+ local mime_family = mime:match('^%a+') or ''
- local possible_filenames = {
- mime, "gnome-mime-" .. mime,
- mime_family, "gnome-mime-" .. mime_family,
- extension
- }
+ local possible_filenames = {
+ mime,
+ 'gnome-mime-' .. mime,
+ mime_family,
+ 'gnome-mime-' .. mime_family,
+ extension,
+ }
- for i, filename in ipairs(possible_filenames) do
- local icon = utils.lookup_icon(filename)
- if icon then return icon end
- end
+ for i, filename in ipairs(possible_filenames) do
+ local icon = utils.lookup_icon(filename)
+ if icon then
+ return icon
+ end
+ end
- -- if we don"t find ad icon, then pretend is a plain text file
- return utils.lookup_icon("text-x-generic")
+ -- if we don"t find ad icon, then pretend is a plain text file
+ return utils.lookup_icon('text-x-generic')
end
-- Parse subdirectories and files list from input directory
-- @input dir directory to parse (string)
-- @return files table with found entries
function desktop.parse_dirs_and_files(dir)
- local files = {}
- local paths = pipelines('find '..dir..' -maxdepth 1 -type d |sort|tail -n +1')
- for path in paths do
- if path:match("[^/]+$") then
- local file = {}
- file.filename = path:match("[^/]+$")
- file.path = path
- file.show = true
- file.icon = utils.lookup_icon("folder")
- table.insert(files, file)
- end
- end
- local paths = pipelines('find '..dir..' -maxdepth 1 -type f')
- for path in paths do
- if not path:find("%.desktop$") then
- local file = {}
- file.filename = path:match("[^/]+$")
- file.path = path
- file.show = true
- file.icon = desktop.lookup_file_icon(file.filename)
- table.insert(files, file)
- end
- end
- return files
+ local files = {}
+ local paths = pipelines('find ' .. dir .. ' -maxdepth 1 -type d |sort|tail -n +1')
+ for path in paths do
+ if path:match('[^/]+$') then
+ local file = {}
+ file.filename = path:match('[^/]+$')
+ file.path = path
+ file.show = true
+ file.icon = utils.lookup_icon('folder')
+ table.insert(files, file)
+ end
+ end
+ local paths = pipelines('find ' .. dir .. ' -maxdepth 1 -type f')
+ for path in paths do
+ if not path:find('%.desktop$') then
+ local file = {}
+ file.filename = path:match('[^/]+$')
+ file.path = path
+ file.show = true
+ file.icon = desktop.lookup_file_icon(file.filename)
+ table.insert(files, file)
+ end
+ end
+ return files
end
-- Adds subdirectories and files icons from args.dir
-- @param args settings from desktop.add_icons
function desktop.add_dirs_and_files_icons(args)
- for _, file in ipairs(desktop.parse_dirs_and_files(args.dir)) do
- if file.show then
- local label = args.showlabels and file.filename or nil
- local onclick = function () awful.spawn(string.format("%s '%s'", args.open_with, file.path)) end
- desktop.add_single_icon(args, label, file.icon, onclick)
- end
- end
+ for _, file in ipairs(desktop.parse_dirs_and_files(args.dir)) do
+ if file.show then
+ local label = args.showlabels and file.filename or nil
+ local onclick = function()
+ awful.spawn(string.format("%s '%s'", args.open_with, file.path))
+ end
+ desktop.add_single_icon(args, label, file.icon, onclick)
+ end
+ end
end
-- Main function, adds base, directory and files icons
-- @param args user defined settings, with fallback on defaults
function desktop.add_icons(args)
- args = args or {}
- args.screen = args.screen or mouse.screen
- args.dir = args.dir or os.getenv("HOME") .. "/Desktop"
- args.showlabels = args.showlabel or true
- args.open_with = args.open_with or "xdg_open"
- args.baseicons = args.baseicons or desktop.baseicons
- args.iconsize = args.iconsize or desktop.iconsize
- args.labelsize = args.labelsize or desktop.labelsize
- args.margin = args.margin or desktop.margin
+ args = args or {}
+ args.screen = args.screen or mouse.screen
+ args.dir = args.dir or os.getenv('HOME') .. '/Desktop'
+ args.showlabels = args.showlabel or true
+ args.open_with = args.open_with or 'xdg_open'
+ args.baseicons = args.baseicons or desktop.baseicons
+ args.iconsize = args.iconsize or desktop.iconsize
+ args.labelsize = args.labelsize or desktop.labelsize
+ args.margin = args.margin or desktop.margin
- -- trying to fallback on Adwaita if theme.icon_theme is not defined
- -- if Adwaita is missing too, no icons will be shown
- if not theme.icon_theme then
- theme.icon_theme = args.icon_theme or "Adwaita"
- end
+ -- trying to fallback on Adwaita if theme.icon_theme is not defined
+ -- if Adwaita is missing too, no icons will be shown
+ if not theme.icon_theme then
+ theme.icon_theme = args.icon_theme or 'Adwaita'
+ end
- desktop.add_base_icons(args)
- desktop.add_dirs_and_files_icons(args)
+ desktop.add_base_icons(args)
+ desktop.add_dirs_and_files_icons(args)
end
return desktop
diff --git a/awesome/freedesktop/init.lua b/awesome/freedesktop/init.lua
index 9350b44..1c66ba6 100644
--- a/awesome/freedesktop/init.lua
+++ b/awesome/freedesktop/init.lua
@@ -10,6 +10,6 @@
--]]
return {
- desktop = require("freedesktop.desktop"),
- menu = require("freedesktop.menu")
+ desktop = require('freedesktop.desktop'),
+ menu = require('freedesktop.menu'),
}
diff --git a/awesome/freedesktop/menu.lua b/awesome/freedesktop/menu.lua
index fed6e6b..55bb668 100644
--- a/awesome/freedesktop/menu.lua
+++ b/awesome/freedesktop/menu.lua
@@ -1,4 +1,3 @@
-
--[[
Awesome-Freedesktop
@@ -12,15 +11,15 @@
--]]
-local Gio = require("lgi").Gio
-local awful_menu = require("awful.menu")
-local menu_gen = require("menubar.menu_gen")
-local menu_utils = require("menubar.utils")
+local Gio = require('lgi').Gio
+local awful_menu = require('awful.menu')
+local menu_gen = require('menubar.menu_gen')
+local menu_utils = require('menubar.utils')
local io, pairs, string, table, os = io, pairs, string, table, os
-- Expecting a wm_name of awesome omits too many applications and tools
-menu_utils.wm_name = ""
+menu_utils.wm_name = ''
-- Menu
-- freedesktop.menu
@@ -30,15 +29,15 @@ local menu = {}
-- @tparam string path The directory path
-- @treturn boolean True if path exists and is a directory
function menu.is_dir(path)
- return Gio.File.new_for_path(path):query_file_type({}) == "DIRECTORY"
+ return Gio.File.new_for_path(path):query_file_type({}) == 'DIRECTORY'
end
-- Remove non existent paths in order to avoid issues
local existent_paths = {}
-for k,v in pairs(menu_gen.all_menu_dirs) do
- if menu.is_dir(v) then
- table.insert(existent_paths, v)
- end
+for k, v in pairs(menu_gen.all_menu_dirs) do
+ if menu.is_dir(v) then
+ table.insert(existent_paths, v)
+ end
end
menu_gen.all_menu_dirs = existent_paths
@@ -46,76 +45,84 @@ menu_gen.all_menu_dirs = existent_paths
-- @param tab a given table
-- @param val the element to search for
-- @return true if the given string is found within the search table; otherwise, false if not
-function menu.has_value (tab, val)
- for index, value in pairs(tab) do
- if val:find(value) then
- return true
- end
- end
- return false
+function menu.has_value(tab, val)
+ for index, value in pairs(tab) do
+ if val:find(value) then
+ return true
+ end
+ end
+ return false
end
-- Use MenuBar parsing utils to build a menu for Awesome
-- @return awful.menu
function menu.build(args)
- local args = args or {}
- local before = args.before or {}
- local after = args.after or {}
- local skip_items = args.skip_items or {}
- local sub_menu = args.sub_menu or false
+ local args = args or {}
+ local before = args.before or {}
+ local after = args.after or {}
+ local skip_items = args.skip_items or {}
+ local sub_menu = args.sub_menu or false
- local result = {}
- local _menu = awful_menu({ items = before })
+ local result = {}
+ local _menu = awful_menu({ items = before })
- menu_gen.generate(function(entries)
- -- Add category icons
- for k, v in pairs(menu_gen.all_categories) do
- table.insert(result, { k, {}, v.icon })
- end
+ menu_gen.generate(function(entries)
+ -- Add category icons
+ for k, v in pairs(menu_gen.all_categories) do
+ table.insert(result, { k, {}, v.icon })
+ end
- -- Get items table
- for k, v in pairs(entries) do
- for _, cat in pairs(result) do
- if cat[1] == v.category then
- if not menu.has_value(skip_items, v.name) then
- table.insert(cat[2], { v.name, v.cmdline, v.icon })
- end
- break
- end
- end
- end
+ -- Get items table
+ for k, v in pairs(entries) do
+ for _, cat in pairs(result) do
+ if cat[1] == v.category then
+ if not menu.has_value(skip_items, v.name) then
+ table.insert(cat[2], { v.name, v.cmdline, v.icon })
+ end
+ break
+ end
+ end
+ end
- -- Cleanup things a bit
- for i = #result, 1, -1 do
- local v = result[i]
- if #v[2] == 0 then
- -- Remove unused categories
- table.remove(result, i)
- else
- --Sort entries alphabetically (by name)
- table.sort(v[2], function (a, b) return string.byte(a[1]) < string.byte(b[1]) end)
- -- Replace category name with nice name
- v[1] = menu_gen.all_categories[v[1]].name
- end
- end
+ -- Cleanup things a bit
+ for i = #result, 1, -1 do
+ local v = result[i]
+ if #v[2] == 0 then
+ -- Remove unused categories
+ table.remove(result, i)
+ else
+ --Sort entries alphabetically (by name)
+ table.sort(v[2], function(a, b)
+ return string.byte(a[1]) < string.byte(b[1])
+ end)
+ -- Replace category name with nice name
+ v[1] = menu_gen.all_categories[v[1]].name
+ end
+ end
- -- Sort categories alphabetically also
- table.sort(result, function(a, b) return string.byte(a[1]) < string.byte(b[1]) end)
+ -- Sort categories alphabetically also
+ table.sort(result, function(a, b)
+ return string.byte(a[1]) < string.byte(b[1])
+ end)
- -- Add menu item to hold the generated menu
- if sub_menu then
- result = {{sub_menu, result}}
- end
+ -- Add menu item to hold the generated menu
+ if sub_menu then
+ result = { { sub_menu, result } }
+ end
- -- Add items to menu
- for _, v in pairs(result) do _menu:add(v) end
- for _, v in pairs(after) do _menu:add(v) end
- end)
+ -- Add items to menu
+ for _, v in pairs(result) do
+ _menu:add(v)
+ end
+ for _, v in pairs(after) do
+ _menu:add(v)
+ end
+ end)
- -- Hold the menu in the module
- menu.menu = _menu
+ -- Hold the menu in the module
+ menu.menu = _menu
- return _menu
+ return _menu
end
return menu
diff --git a/awesome/lain/helpers.lua b/awesome/lain/helpers.lua
index ef9e08b..bedb08f 100644
--- a/awesome/lain/helpers.lua
+++ b/awesome/lain/helpers.lua
@@ -5,28 +5,27 @@
--]]
-local spawn = require("awful.spawn")
-local timer = require("gears.timer")
-local debug = require("debug")
-local io = { lines = io.lines,
- open = io.open }
-local pairs = pairs
+local spawn = require('awful.spawn')
+local timer = require('gears.timer')
+local debug = require('debug')
+local io = { lines = io.lines, open = io.open }
+local pairs = pairs
local rawget = rawget
-local tsort = table.sort
+local tsort = table.sort
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
-- Lain helper functions for internal use
-- lain.helpers
local helpers = {}
-helpers.lain_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]]
-helpers.icons_dir = helpers.lain_dir .. 'icons/'
+helpers.lain_dir = debug.getinfo(1, 'S').source:match([[^@(.*/).*$]])
+helpers.icons_dir = helpers.lain_dir .. 'icons/'
helpers.scripts_dir = helpers.lain_dir .. 'scripts/'
-- {{{ Modules loader
function helpers.wrequire(t, k)
- return rawget(t, k) or require(t._NAME .. '.' .. k)
+ return rawget(t, k) or require(t._NAME .. '.' .. k)
end
-- }}}
@@ -35,47 +34,51 @@ end
-- check if the file exists and is readable
function helpers.file_exists(path)
- local file = io.open(path, "rb")
- if file then file:close() end
- return file ~= nil
+ local file = io.open(path, 'rb')
+ if file then
+ file:close()
+ end
+ return file ~= nil
end
-- get a table with all lines from a file
function helpers.lines_from(path)
- local lines = {}
- for line in io.lines(path) do
- lines[#lines + 1] = line
- end
- return lines
+ local lines = {}
+ for line in io.lines(path) do
+ lines[#lines + 1] = line
+ end
+ return lines
end
-- get a table with all lines from a file matching regexp
function helpers.lines_match(regexp, path)
- local lines = {}
- for line in io.lines(path) do
- if string.match(line, regexp) then
- lines[#lines + 1] = line
- end
- end
- return lines
+ local lines = {}
+ for line in io.lines(path) do
+ if string.match(line, regexp) then
+ lines[#lines + 1] = line
+ end
+ end
+ return lines
end
-- get first line of a file
function helpers.first_line(path)
- local file, first = io.open(path, "rb"), nil
- if file then
- first = file:read("*l")
- file:close()
- end
- return first
+ local file, first = io.open(path, 'rb'), nil
+ if file then
+ first = file:read('*l')
+ file:close()
+ end
+ return first
end
-- get first non empty line from a file
function helpers.first_nonempty_line(path)
- for line in io.lines(path) do
- if #line then return line end
- end
- return nil
+ for line in io.lines(path) do
+ if #line then
+ return line
+ end
+ end
+ return nil
end
-- }}}
@@ -85,17 +88,19 @@ end
helpers.timer_table = {}
function helpers.newtimer(name, timeout, fun, nostart, stoppable)
- if not name or #name == 0 then return end
- name = (stoppable and name) or timeout
- if not helpers.timer_table[name] then
- helpers.timer_table[name] = timer({ timeout = timeout })
- helpers.timer_table[name]:start()
- end
- helpers.timer_table[name]:connect_signal("timeout", fun)
- if not nostart then
- helpers.timer_table[name]:emit_signal("timeout")
- end
- return stoppable and helpers.timer_table[name]
+ if not name or #name == 0 then
+ return
+ end
+ name = (stoppable and name) or timeout
+ if not helpers.timer_table[name] then
+ helpers.timer_table[name] = timer({ timeout = timeout })
+ helpers.timer_table[name]:start()
+ end
+ helpers.timer_table[name]:connect_signal('timeout', fun)
+ if not nostart then
+ helpers.timer_table[name]:emit_signal('timeout')
+ end
+ return stoppable and helpers.timer_table[name]
end
-- }}}
@@ -107,27 +112,25 @@ end
-- @param callback function to execute on cmd output
-- @return cmd PID
function helpers.async(cmd, callback)
- return spawn.easy_async(cmd,
- function (stdout, _, _, exit_code)
- callback(stdout, exit_code)
- end)
+ return spawn.easy_async(cmd, function(stdout, _, _, exit_code)
+ callback(stdout, exit_code)
+ end)
end
-- like above, but call spawn.easy_async with a shell
function helpers.async_with_shell(cmd, callback)
- return spawn.easy_async_with_shell(cmd,
- function (stdout, _, _, exit_code)
- callback(stdout, exit_code)
- end)
+ return spawn.easy_async_with_shell(cmd, function(stdout, _, _, exit_code)
+ callback(stdout, exit_code)
+ end)
end
-- run a command and execute a function on its output line by line
function helpers.line_callback(cmd, callback)
- return spawn.with_line_callback(cmd, {
- stdout = function (line)
- callback(line)
- end,
- })
+ return spawn.with_line_callback(cmd, {
+ stdout = function(line)
+ callback(line)
+ end,
+ })
end
-- }}}
@@ -137,11 +140,11 @@ end
helpers.map_table = {}
function helpers.set_map(element, value)
- helpers.map_table[element] = value
+ helpers.map_table[element] = value
end
function helpers.get_map(element)
- return helpers.map_table[element]
+ return helpers.map_table[element]
end
-- }}}
@@ -150,52 +153,56 @@ end
-- check if an element exist on a table
function helpers.element_in_table(element, tbl)
- for _, i in pairs(tbl) do
- if i == element then
- return true
- end
- end
- return false
+ for _, i in pairs(tbl) do
+ if i == element then
+ return true
+ end
+ end
+ return false
end
-- iterate over table of records sorted by keys
function helpers.spairs(t)
- -- collect the keys
- local keys = {}
- for k in pairs(t) do keys[#keys+1] = k end
+ -- collect the keys
+ local keys = {}
+ for k in pairs(t) do
+ keys[#keys + 1] = k
+ end
- tsort(keys)
+ tsort(keys)
- -- return the iterator function
- local i = 0
- return function()
- i = i + 1
- if keys[i] then
- return keys[i], t[keys[i]]
- end
- end
+ -- return the iterator function
+ local i = 0
+ return function()
+ i = i + 1
+ if keys[i] then
+ return keys[i], t[keys[i]]
+ end
+ end
end
-- create the partition of singletons of a given set
-- example: the trivial partition set of {a, b, c}, is {{a}, {b}, {c}}
function helpers.trivial_partition_set(set)
- local ss = {}
- for _,e in pairs(set) do
- ss[#ss+1] = {e}
- end
- return ss
+ local ss = {}
+ for _, e in pairs(set) do
+ ss[#ss + 1] = { e }
+ end
+ return ss
end
-- create the powerset of a given set
function helpers.powerset(s)
- if not s then return {} end
- local t = {{}}
- for i = 1, #s do
- for j = 1, #t do
- t[#t+1] = {s[i],unpack(t[j])}
- end
- end
- return t
+ if not s then
+ return {}
+ end
+ local t = { {} }
+ for i = 1, #s do
+ for j = 1, #t do
+ t[#t + 1] = { s[i], unpack(t[j]) }
+ end
+ end
+ return t
end
-- }}}
diff --git a/awesome/lain/init.lua b/awesome/lain/init.lua
index b59d5dd..6770c40 100644
--- a/awesome/lain/init.lua
+++ b/awesome/lain/init.lua
@@ -9,7 +9,7 @@
--]]
return {
- layout = require("lain.layout"),
- util = require("lain.util"),
- widget = require("lain.widget")
+ layout = require('lain.layout'),
+ util = require('lain.util'),
+ widget = require('lain.widget'),
}
diff --git a/awesome/lain/layout/cascade.lua b/awesome/lain/layout/cascade.lua
index cbc3877..1403b97 100644
--- a/awesome/lain/layout/cascade.lua
+++ b/awesome/lain/layout/cascade.lua
@@ -7,166 +7,184 @@
--]]
-local floor = math.floor
+local floor = math.floor
local screen = screen
local cascade = {
- name = "cascade",
- nmaster = 0,
- offset_x = 32,
- offset_y = 8,
- tile = {
- name = "cascadetile",
- nmaster = 0,
- ncol = 0,
- mwfact = 0,
- offset_x = 5,
- offset_y = 32,
- extra_padding = 0
- }
+ name = 'cascade',
+ nmaster = 0,
+ offset_x = 32,
+ offset_y = 8,
+ tile = {
+ name = 'cascadetile',
+ nmaster = 0,
+ ncol = 0,
+ mwfact = 0,
+ offset_x = 5,
+ offset_y = 32,
+ extra_padding = 0,
+ },
}
local function do_cascade(p, tiling)
- local t = p.tag or screen[p.screen].selected_tag
- local wa = p.workarea
- local cls = p.clients
+ local t = p.tag or screen[p.screen].selected_tag
+ local wa = p.workarea
+ local cls = p.clients
- if #cls == 0 then return end
+ if #cls == 0 then
+ return
+ end
- if not tiling then
- -- Cascade windows.
+ if not tiling then
+ -- Cascade windows.
- local num_c
- if cascade.nmaster > 0 then
- num_c = cascade.nmaster
- else
- num_c = t.master_count
- end
+ local num_c
+ if cascade.nmaster > 0 then
+ num_c = cascade.nmaster
+ else
+ num_c = t.master_count
+ end
- -- Opening a new window will usually force all existing windows to
- -- get resized. This wastes a lot of CPU time. So let's set a lower
- -- bound to "how_many": This wastes a little screen space but you'll
- -- get a much better user experience.
- local how_many = (#cls >= num_c and #cls) or num_c
+ -- Opening a new window will usually force all existing windows to
+ -- get resized. This wastes a lot of CPU time. So let's set a lower
+ -- bound to "how_many": This wastes a little screen space but you'll
+ -- get a much better user experience.
+ local how_many = (#cls >= num_c and #cls) or num_c
- local current_offset_x = cascade.offset_x * (how_many - 1)
- local current_offset_y = cascade.offset_y * (how_many - 1)
+ local current_offset_x = cascade.offset_x * (how_many - 1)
+ local current_offset_y = cascade.offset_y * (how_many - 1)
- -- Iterate.
- for i = 1,#cls,1 do
- local c = cls[i]
- local g = {}
+ -- Iterate.
+ for i = 1, #cls, 1 do
+ local c = cls[i]
+ local g = {}
- g.x = wa.x + (how_many - i) * cascade.offset_x
- g.y = wa.y + (i - 1) * cascade.offset_y
- g.width = wa.width - current_offset_x
- g.height = wa.height - current_offset_y
+ g.x = wa.x + (how_many - i) * cascade.offset_x
+ g.y = wa.y + (i - 1) * cascade.offset_y
+ g.width = wa.width - current_offset_x
+ g.height = wa.height - current_offset_y
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
- p.geometries[c] = g
- end
- else
- -- Layout with one fixed column meant for a master window. Its
- -- width is calculated according to mwfact. Other clients are
- -- cascaded or "tabbed" in a slave column on the right.
+ p.geometries[c] = g
+ end
+ else
+ -- Layout with one fixed column meant for a master window. Its
+ -- width is calculated according to mwfact. Other clients are
+ -- cascaded or "tabbed" in a slave column on the right.
- -- (1) (2) (3) (4)
- -- +----------+---+ +----------+---+ +----------+---+ +----------+---+
- -- | | | | | 3 | | | 4 | | +---+|
- -- | | | -> | | | -> | +---++ -> | +---+|+
- -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+|
- -- | | | | | 2 || | +---++| | +---+|+ |
- -- | | | | | || | | 2 | | | | 2 |+ |
- -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+
+ -- (1) (2) (3) (4)
+ -- +----------+---+ +----------+---+ +----------+---+ +----------+---+
+ -- | | | | | 3 | | | 4 | | +---+|
+ -- | | | -> | | | -> | +---++ -> | +---+|+
+ -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+|
+ -- | | | | | 2 || | +---++| | +---+|+ |
+ -- | | | | | || | | 2 | | | | 2 |+ |
+ -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+
- local mwfact
- if cascade.tile.mwfact > 0 then
- mwfact = cascade.tile.mwfact
- else
- mwfact = t.master_width_factor
- end
+ local mwfact
+ if cascade.tile.mwfact > 0 then
+ mwfact = cascade.tile.mwfact
+ else
+ mwfact = t.master_width_factor
+ end
- -- Make slave windows overlap main window? Do this if ncol is 1.
- local overlap_main
- if cascade.tile.ncol > 0 then
- overlap_main = cascade.tile.ncol
- else
- overlap_main = t.column_count
- end
+ -- Make slave windows overlap main window? Do this if ncol is 1.
+ local overlap_main
+ if cascade.tile.ncol > 0 then
+ overlap_main = cascade.tile.ncol
+ else
+ overlap_main = t.column_count
+ end
- -- Minimum space for slave windows? See cascade.tile.lua.
- local num_c
- if cascade.tile.nmaster > 0 then
- num_c = cascade.tile.nmaster
- else
- num_c = t.master_count
- end
+ -- Minimum space for slave windows? See cascade.tile.lua.
+ local num_c
+ if cascade.tile.nmaster > 0 then
+ num_c = cascade.tile.nmaster
+ else
+ num_c = t.master_count
+ end
- local how_many = (#cls - 1 >= num_c and (#cls - 1)) or num_c
+ local how_many = (#cls - 1 >= num_c and (#cls - 1)) or num_c
- local current_offset_x = cascade.tile.offset_x * (how_many - 1)
- local current_offset_y = cascade.tile.offset_y * (how_many - 1)
+ local current_offset_x = cascade.tile.offset_x * (how_many - 1)
+ local current_offset_y = cascade.tile.offset_y * (how_many - 1)
- if #cls <= 0 then return end
+ if #cls <= 0 then
+ return
+ end
- -- Main column, fixed width and height.
- local c = cls[1]
- local g = {}
- -- Rounding is necessary to prevent the rendered size of slavewid
- -- from being 1 pixel off when the result is not an integer.
- local mainwid = floor(wa.width * mwfact)
- local slavewid = wa.width - mainwid
+ -- Main column, fixed width and height.
+ local c = cls[1]
+ local g = {}
+ -- Rounding is necessary to prevent the rendered size of slavewid
+ -- from being 1 pixel off when the result is not an integer.
+ local mainwid = floor(wa.width * mwfact)
+ local slavewid = wa.width - mainwid
- if overlap_main == 1 then
- g.width = wa.width
+ if overlap_main == 1 then
+ g.width = wa.width
- -- The size of the main window may be reduced a little bit.
- -- This allows you to see if there are any windows below the
- -- main window.
- -- This only makes sense, though, if the main window is
- -- overlapping everything else.
- g.width = g.width - cascade.tile.extra_padding
- else
- g.width = mainwid
- end
+ -- The size of the main window may be reduced a little bit.
+ -- This allows you to see if there are any windows below the
+ -- main window.
+ -- This only makes sense, though, if the main window is
+ -- overlapping everything else.
+ g.width = g.width - cascade.tile.extra_padding
+ else
+ g.width = mainwid
+ end
- g.height = wa.height
- g.x = wa.x
- g.y = wa.y
+ g.height = wa.height
+ g.x = wa.x
+ g.y = wa.y
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
- p.geometries[c] = g
+ p.geometries[c] = g
- -- Remaining clients stacked in slave column, new ones on top.
- if #cls <= 1 then return end
- for i = 2,#cls do
- c = cls[i]
- g = {}
+ -- Remaining clients stacked in slave column, new ones on top.
+ if #cls <= 1 then
+ return
+ end
+ for i = 2, #cls do
+ c = cls[i]
+ g = {}
- g.width = slavewid - current_offset_x
- g.height = wa.height - current_offset_y
+ g.width = slavewid - current_offset_x
+ g.height = wa.height - current_offset_y
- g.x = wa.x + mainwid + (how_many - (i - 1)) * cascade.tile.offset_x
- g.y = wa.y + (i - 2) * cascade.tile.offset_y
+ g.x = wa.x + mainwid + (how_many - (i - 1)) * cascade.tile.offset_x
+ g.y = wa.y + (i - 2) * cascade.tile.offset_y
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
- p.geometries[c] = g
- end
- end
+ p.geometries[c] = g
+ end
+ end
end
function cascade.tile.arrange(p)
- return do_cascade(p, true)
+ return do_cascade(p, true)
end
function cascade.arrange(p)
- return do_cascade(p, false)
+ return do_cascade(p, false)
end
return cascade
diff --git a/awesome/lain/layout/centerwork.lua b/awesome/lain/layout/centerwork.lua
index c105676..30c0e16 100644
--- a/awesome/lain/layout/centerwork.lua
+++ b/awesome/lain/layout/centerwork.lua
@@ -17,260 +17,274 @@ local mousegrabber = mousegrabber
local screen = screen
local centerwork = {
- name = "centerwork",
- horizontal = { name = "centerworkh" }
+ name = 'centerwork',
+ horizontal = { name = 'centerworkh' },
}
local function arrange(p, layout)
- local t = p.tag or screen[p.screen].selected_tag
- local wa = p.workarea
- local cls = p.clients
+ local t = p.tag or screen[p.screen].selected_tag
+ local wa = p.workarea
+ local cls = p.clients
- if #cls == 0 then return end
+ if #cls == 0 then
+ return
+ end
- local g = {}
+ local g = {}
- -- Main column, fixed width and height
- local mwfact = t.master_width_factor
- local mainhei = floor(wa.height * mwfact)
- local mainwid = floor(wa.width * mwfact)
- local slavewid = wa.width - mainwid
- local slaveLwid = floor(slavewid / 2)
- local slaveRwid = slavewid - slaveLwid
- local slavehei = wa.height - mainhei
- local slaveThei = floor(slavehei / 2)
- local slaveBhei = slavehei - slaveThei
- local nbrFirstSlaves = floor(#cls / 2)
- local nbrSecondSlaves = floor((#cls - 1) / 2)
+ -- Main column, fixed width and height
+ local mwfact = t.master_width_factor
+ local mainhei = floor(wa.height * mwfact)
+ local mainwid = floor(wa.width * mwfact)
+ local slavewid = wa.width - mainwid
+ local slaveLwid = floor(slavewid / 2)
+ local slaveRwid = slavewid - slaveLwid
+ local slavehei = wa.height - mainhei
+ local slaveThei = floor(slavehei / 2)
+ local slaveBhei = slavehei - slaveThei
+ local nbrFirstSlaves = floor(#cls / 2)
+ local nbrSecondSlaves = floor((#cls - 1) / 2)
- local slaveFirstDim, slaveSecondDim = 0, 0
+ local slaveFirstDim, slaveSecondDim = 0, 0
- if layout.name == "centerwork" then -- vertical
- if nbrFirstSlaves > 0 then slaveFirstDim = floor(wa.height / nbrFirstSlaves) end
- if nbrSecondSlaves > 0 then slaveSecondDim = floor(wa.height / nbrSecondSlaves) end
+ if layout.name == 'centerwork' then -- vertical
+ if nbrFirstSlaves > 0 then
+ slaveFirstDim = floor(wa.height / nbrFirstSlaves)
+ end
+ if nbrSecondSlaves > 0 then
+ slaveSecondDim = floor(wa.height / nbrSecondSlaves)
+ end
- g.height = wa.height
- g.width = mainwid
+ g.height = wa.height
+ g.width = mainwid
- g.x = wa.x + slaveLwid
- g.y = wa.y
- else -- horizontal
- if nbrFirstSlaves > 0 then slaveFirstDim = floor(wa.width / nbrFirstSlaves) end
- if nbrSecondSlaves > 0 then slaveSecondDim = floor(wa.width / nbrSecondSlaves) end
+ g.x = wa.x + slaveLwid
+ g.y = wa.y
+ else -- horizontal
+ if nbrFirstSlaves > 0 then
+ slaveFirstDim = floor(wa.width / nbrFirstSlaves)
+ end
+ if nbrSecondSlaves > 0 then
+ slaveSecondDim = floor(wa.width / nbrSecondSlaves)
+ end
- g.height = mainhei
- g.width = wa.width
+ g.height = mainhei
+ g.width = wa.width
- g.x = wa.x
- g.y = wa.y + slaveThei
- end
+ g.x = wa.x
+ g.y = wa.y + slaveThei
+ end
- g.width = max(g.width, 1)
- g.height = max(g.height, 1)
+ g.width = max(g.width, 1)
+ g.height = max(g.height, 1)
- p.geometries[cls[1]] = g
+ p.geometries[cls[1]] = g
- -- Auxiliary clients
- if #cls <= 1 then return end
- for i = 2, #cls do
- g = {}
- local idxChecker, dimToAssign
+ -- Auxiliary clients
+ if #cls <= 1 then
+ return
+ end
+ for i = 2, #cls do
+ g = {}
+ local idxChecker, dimToAssign
- local rowIndex = floor(i/2)
+ local rowIndex = floor(i / 2)
- if layout.name == "centerwork" then
- if i % 2 == 0 then -- left slave
- g.x = wa.x
- g.y = wa.y + (rowIndex - 1) * slaveFirstDim
- g.width = slaveLwid
+ if layout.name == 'centerwork' then
+ if i % 2 == 0 then -- left slave
+ g.x = wa.x
+ g.y = wa.y + (rowIndex - 1) * slaveFirstDim
+ g.width = slaveLwid
- idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
- else -- right slave
- g.x = wa.x + slaveLwid + mainwid
- g.y = wa.y + (rowIndex - 1) * slaveSecondDim
- g.width = slaveRwid
+ idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
+ else -- right slave
+ g.x = wa.x + slaveLwid + mainwid
+ g.y = wa.y + (rowIndex - 1) * slaveSecondDim
+ g.width = slaveRwid
- idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
- end
+ idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
+ end
- -- if last slave in row, use remaining space for it
- if rowIndex == idxChecker then
- g.height = wa.y + wa.height - g.y
- else
- g.height = dimToAssign
- end
- else
- if i % 2 == 0 then -- top slave
- g.x = wa.x + (rowIndex - 1) * slaveFirstDim
- g.y = wa.y
- g.height = slaveThei
+ -- if last slave in row, use remaining space for it
+ if rowIndex == idxChecker then
+ g.height = wa.y + wa.height - g.y
+ else
+ g.height = dimToAssign
+ end
+ else
+ if i % 2 == 0 then -- top slave
+ g.x = wa.x + (rowIndex - 1) * slaveFirstDim
+ g.y = wa.y
+ g.height = slaveThei
- idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
- else -- bottom slave
- g.x = wa.x + (rowIndex - 1) * slaveSecondDim
- g.y = wa.y + slaveThei + mainhei
- g.height = slaveBhei
+ idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
+ else -- bottom slave
+ g.x = wa.x + (rowIndex - 1) * slaveSecondDim
+ g.y = wa.y + slaveThei + mainhei
+ g.height = slaveBhei
- idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
- end
+ idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
+ end
- -- if last slave in row, use remaining space for it
- if rowIndex == idxChecker then
- g.width = wa.x + wa.width - g.x
- else
- g.width = dimToAssign
- end
- end
+ -- if last slave in row, use remaining space for it
+ if rowIndex == idxChecker then
+ g.width = wa.x + wa.width - g.x
+ else
+ g.width = dimToAssign
+ end
+ end
- g.width = max(g.width, 1)
- g.height = max(g.height, 1)
+ g.width = max(g.width, 1)
+ g.height = max(g.height, 1)
- p.geometries[cls[i]] = g
- end
+ p.geometries[cls[i]] = g
+ end
end
local function mouse_resize_handler(c, _, _, _, orientation)
- local wa = c.screen.workarea
- local mwfact = c.screen.selected_tag.master_width_factor
- local g = c:geometry()
- local offset = 0
- local cursor = "cross"
+ local wa = c.screen.workarea
+ local mwfact = c.screen.selected_tag.master_width_factor
+ local g = c:geometry()
+ local offset = 0
+ local cursor = 'cross'
- local corner_coords
+ local corner_coords
- if orientation == 'vertical' then
- if g.height + 15 >= wa.height then
- offset = g.height * .5
- cursor = "sb_h_double_arrow"
- elseif g.y + g.height + 15 <= wa.y + wa.height then
- offset = g.height
- end
- corner_coords = { x = wa.x + wa.width * (1 - mwfact) / 2, y = g.y + offset }
- else
- if g.width + 15 >= wa.width then
- offset = g.width * .5
- cursor = "sb_v_double_arrow"
- elseif g.x + g.width + 15 <= wa.x + wa.width then
- offset = g.width
- end
- corner_coords = { y = wa.y + wa.height * (1 - mwfact) / 2, x = g.x + offset }
- end
+ if orientation == 'vertical' then
+ if g.height + 15 >= wa.height then
+ offset = g.height * 0.5
+ cursor = 'sb_h_double_arrow'
+ elseif g.y + g.height + 15 <= wa.y + wa.height then
+ offset = g.height
+ end
+ corner_coords = { x = wa.x + wa.width * (1 - mwfact) / 2, y = g.y + offset }
+ else
+ if g.width + 15 >= wa.width then
+ offset = g.width * 0.5
+ cursor = 'sb_v_double_arrow'
+ elseif g.x + g.width + 15 <= wa.x + wa.width then
+ offset = g.width
+ end
+ corner_coords = { y = wa.y + wa.height * (1 - mwfact) / 2, x = g.x + offset }
+ end
- mouse.coords(corner_coords)
+ mouse.coords(corner_coords)
- local prev_coords = {}
+ local prev_coords = {}
- mousegrabber.run(function(m)
- if not c.valid then return false end
- for _, v in ipairs(m.buttons) do
- if v then
- prev_coords = { x = m.x, y = m.y }
- local new_mwfact
- if orientation == 'vertical' then
- new_mwfact = 1 - (m.x - wa.x) / wa.width * 2
- else
- new_mwfact = 1 - (m.y - wa.y) / wa.height * 2
- end
- c.screen.selected_tag.master_width_factor = math.min(math.max(new_mwfact, 0.01), 0.99)
- return true
- end
- end
- return prev_coords.x == m.x and prev_coords.y == m.y
- end, cursor)
+ mousegrabber.run(function(m)
+ if not c.valid then
+ return false
+ end
+ for _, v in ipairs(m.buttons) do
+ if v then
+ prev_coords = { x = m.x, y = m.y }
+ local new_mwfact
+ if orientation == 'vertical' then
+ new_mwfact = 1 - (m.x - wa.x) / wa.width * 2
+ else
+ new_mwfact = 1 - (m.y - wa.y) / wa.height * 2
+ end
+ c.screen.selected_tag.master_width_factor = math.min(math.max(new_mwfact, 0.01), 0.99)
+ return true
+ end
+ end
+ return prev_coords.x == m.x and prev_coords.y == m.y
+ end, cursor)
end
function centerwork.arrange(p)
- return arrange(p, centerwork)
+ return arrange(p, centerwork)
end
function centerwork.horizontal.arrange(p)
- return arrange(p, centerwork.horizontal)
+ return arrange(p, centerwork.horizontal)
end
function centerwork.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y, 'vertical')
+ return mouse_resize_handler(c, corner, x, y, 'vertical')
end
function centerwork.horizontal.mouse_resize_handler(c, corner, x, y)
- return mouse_resize_handler(c, corner, x, y, 'horizontal')
+ return mouse_resize_handler(c, corner, x, y, 'horizontal')
end
-
--[[
Make focus.byidx and swap.byidx behave more consistently with other layouts.
--]]
-local awful = require("awful")
-local gears = require("gears")
+local awful = require('awful')
+local gears = require('gears')
local client = client
local function compare_position(a, b)
- if a.x == b.x then
- return a.y < b.y
- else
- return a.x < b.x
- end
+ if a.x == b.x then
+ return a.y < b.y
+ else
+ return a.x < b.x
+ end
end
local function clients_by_position()
- local this = client.focus
- if this then
- local sorted = {}
- for _, c in ipairs(client.focus.first_tag:clients()) do
- if not c.minimized then sorted[#sorted+1] = c end
- end
- table.sort(sorted, compare_position)
+ local this = client.focus
+ if this then
+ local sorted = {}
+ for _, c in ipairs(client.focus.first_tag:clients()) do
+ if not c.minimized then
+ sorted[#sorted + 1] = c
+ end
+ end
+ table.sort(sorted, compare_position)
- local idx = 0
- for i, that in ipairs(sorted) do
- if this.window == that.window then
- idx = i
- end
- end
+ local idx = 0
+ for i, that in ipairs(sorted) do
+ if this.window == that.window then
+ idx = i
+ end
+ end
- if idx > 0 then
- return { sorted = sorted, idx = idx }
- end
- end
- return {}
+ if idx > 0 then
+ return { sorted = sorted, idx = idx }
+ end
+ end
+ return {}
end
local function in_centerwork()
- return client.focus and client.focus.first_tag.layout.name == "centerwork"
+ return client.focus and client.focus.first_tag.layout.name == 'centerwork'
end
centerwork.focus = {}
-
--[[
Drop in replacements for awful.client.focus.byidx and awful.client.swap.byidx
that behaves consistently with other layouts.
--]]
function centerwork.focus.byidx(i)
- if in_centerwork() then
- local cls = clients_by_position()
- if cls.idx then
- local target = cls.sorted[gears.math.cycle(#cls.sorted, cls.idx + i)]
- awful.client.focus.byidx(0, target)
- end
- else
- awful.client.focus.byidx(i)
- end
+ if in_centerwork() then
+ local cls = clients_by_position()
+ if cls.idx then
+ local target = cls.sorted[gears.math.cycle(#cls.sorted, cls.idx + i)]
+ awful.client.focus.byidx(0, target)
+ end
+ else
+ awful.client.focus.byidx(i)
+ end
end
centerwork.swap = {}
function centerwork.swap.byidx(i)
- if in_centerwork() then
- local cls = clients_by_position()
- if cls.idx then
- local target = cls.sorted[gears.math.cycle(#cls.sorted, cls.idx + i)]
- client.focus:swap(target)
- end
- else
- awful.client.swap.byidx(i)
- end
+ if in_centerwork() then
+ local cls = clients_by_position()
+ if cls.idx then
+ local target = cls.sorted[gears.math.cycle(#cls.sorted, cls.idx + i)]
+ client.focus:swap(target)
+ end
+ else
+ awful.client.swap.byidx(i)
+ end
end
return centerwork
diff --git a/awesome/lain/layout/init.lua b/awesome/lain/layout/init.lua
index 6478b06..cdcbad0 100644
--- a/awesome/lain/layout/init.lua
+++ b/awesome/lain/layout/init.lua
@@ -11,9 +11,9 @@
--]]
-local wrequire = require("lain.helpers").wrequire
+local wrequire = require('lain.helpers').wrequire
local setmetatable = setmetatable
-local layout = { _NAME = "lain.layout" }
+local layout = { _NAME = 'lain.layout' }
return setmetatable(layout, { __index = wrequire })
diff --git a/awesome/lain/layout/termfair.lua b/awesome/lain/layout/termfair.lua
index cf018ef..f1fcbe2 100644
--- a/awesome/lain/layout/termfair.lua
+++ b/awesome/lain/layout/termfair.lua
@@ -8,275 +8,305 @@
--]]
-local math = math
-local screen = screen
+local math = math
+local screen = screen
local tonumber = tonumber
-local termfair = { name = "termfair" }
-termfair.center = { name = "centerfair" }
-termfair.stable = { name = "stablefair" }
+local termfair = { name = 'termfair' }
+termfair.center = { name = 'centerfair' }
+termfair.stable = { name = 'stablefair' }
local function do_fair(p, orientation)
- local t = p.tag or screen[p.screen].selected_tag
- local wa = p.workarea
- local cls = p.clients
+ local t = p.tag or screen[p.screen].selected_tag
+ local wa = p.workarea
+ local cls = p.clients
- if #cls == 0 then return end
+ if #cls == 0 then
+ return
+ end
- -- How many vertical columns? Read from nmaster on the tag.
- local num_x = tonumber(termfair.nmaster) or t.master_count
- local ncol = tonumber(termfair.ncol) or t.column_count
- if num_x <= 2 then num_x = 2 end
- if ncol <= 1 then ncol = 1 end
- local width = math.floor(wa.width/num_x)
+ -- How many vertical columns? Read from nmaster on the tag.
+ local num_x = tonumber(termfair.nmaster) or t.master_count
+ local ncol = tonumber(termfair.ncol) or t.column_count
+ if num_x <= 2 then
+ num_x = 2
+ end
+ if ncol <= 1 then
+ ncol = 1
+ end
+ local width = math.floor(wa.width / num_x)
- if orientation == "west" then
- -- Layout with fixed number of vertical columns (read from nmaster).
- -- New windows align from left to right. When a row is full, a new
- -- one above it is created. Like this:
+ if orientation == 'west' then
+ -- Layout with fixed number of vertical columns (read from nmaster).
+ -- New windows align from left to right. When a row is full, a new
+ -- one above it is created. Like this:
- -- (1) (2) (3)
- -- +---+---+---+ +---+---+---+ +---+---+---+
- -- | | | | | | | | | | | |
- -- | 1 | | | -> | 1 | 2 | | -> | 1 | 2 | 3 | ->
- -- | | | | | | | | | | | |
- -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- (1) (2) (3)
+ -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- | | | | | | | | | | | |
+ -- | 1 | | | -> | 1 | 2 | | -> | 1 | 2 | 3 | ->
+ -- | | | | | | | | | | | |
+ -- +---+---+---+ +---+---+---+ +---+---+---+
- -- (4) (5) (6)
- -- +---+---+---+ +---+---+---+ +---+---+---+
- -- | 1 | | | | 1 | 2 | | | 1 | 2 | 3 |
- -- +---+---+---+ -> +---+---+---+ -> +---+---+---+
- -- | 2 | 3 | 4 | | 3 | 4 | 5 | | 4 | 5 | 6 |
- -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- (4) (5) (6)
+ -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- | 1 | | | | 1 | 2 | | | 1 | 2 | 3 |
+ -- +---+---+---+ -> +---+---+---+ -> +---+---+---+
+ -- | 2 | 3 | 4 | | 3 | 4 | 5 | | 4 | 5 | 6 |
+ -- +---+---+---+ +---+---+---+ +---+---+---+
- local num_y = math.max(math.ceil(#cls / num_x), ncol)
- local height = math.floor(wa.height/num_y)
- local cur_num_x = num_x
- local at_x = 0
- local at_y = 0
+ local num_y = math.max(math.ceil(#cls / num_x), ncol)
+ local height = math.floor(wa.height / num_y)
+ local cur_num_x = num_x
+ local at_x = 0
+ local at_y = 0
- local remaining_clients = #cls
+ local remaining_clients = #cls
- -- We start the first row. Left-align by limiting the number of
- -- available slots.
- if remaining_clients < num_x then
- cur_num_x = remaining_clients
- end
+ -- We start the first row. Left-align by limiting the number of
+ -- available slots.
+ if remaining_clients < num_x then
+ cur_num_x = remaining_clients
+ end
- -- Iterate in reversed order.
- for i = #cls,1,-1 do
- -- Get x and y position.
- local c = cls[i]
- local this_x = cur_num_x - at_x - 1
- local this_y = num_y - at_y - 1
+ -- Iterate in reversed order.
+ for i = #cls, 1, -1 do
+ -- Get x and y position.
+ local c = cls[i]
+ local this_x = cur_num_x - at_x - 1
+ local this_y = num_y - at_y - 1
- -- Calculate geometry.
- local g = {}
- if this_x == (num_x - 1) then
- g.width = wa.width - (num_x - 1)*width
- else
- g.width = width
- end
+ -- Calculate geometry.
+ local g = {}
+ if this_x == (num_x - 1) then
+ g.width = wa.width - (num_x - 1) * width
+ else
+ g.width = width
+ end
- if this_y == (num_y - 1) then
- g.height = wa.height - (num_y - 1)*height
- else
- g.height = height
- end
+ if this_y == (num_y - 1) then
+ g.height = wa.height - (num_y - 1) * height
+ else
+ g.height = height
+ end
- g.x = wa.x + this_x*width
- g.y = wa.y + this_y*height
+ g.x = wa.x + this_x * width
+ g.y = wa.y + this_y * height
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
- p.geometries[c] = g
+ p.geometries[c] = g
- remaining_clients = remaining_clients - 1
+ remaining_clients = remaining_clients - 1
- -- Next grid position.
- at_x = at_x + 1
- if at_x == num_x then
- -- Row full, create a new one above it.
- at_x = 0
- at_y = at_y + 1
+ -- Next grid position.
+ at_x = at_x + 1
+ if at_x == num_x then
+ -- Row full, create a new one above it.
+ at_x = 0
+ at_y = at_y + 1
- -- We start a new row. Left-align.
- if remaining_clients < num_x then
- cur_num_x = remaining_clients
- end
- end
- end
- elseif orientation == "stable" then
- -- Layout with fixed number of vertical columns (read from nmaster).
- -- New windows align from left to right. When a row is full, a new
- -- one below it is created. Like this:
+ -- We start a new row. Left-align.
+ if remaining_clients < num_x then
+ cur_num_x = remaining_clients
+ end
+ end
+ end
+ elseif orientation == 'stable' then
+ -- Layout with fixed number of vertical columns (read from nmaster).
+ -- New windows align from left to right. When a row is full, a new
+ -- one below it is created. Like this:
- -- (1) (2) (3)
- -- +---+---+---+ +---+---+---+ +---+---+---+
- -- | | | | | | | | | | | |
- -- | 1 | | | -> | 1 | 2 | | -> | 1 | 2 | 3 | ->
- -- | | | | | | | | | | | |
- -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- (1) (2) (3)
+ -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- | | | | | | | | | | | |
+ -- | 1 | | | -> | 1 | 2 | | -> | 1 | 2 | 3 | ->
+ -- | | | | | | | | | | | |
+ -- +---+---+---+ +---+---+---+ +---+---+---+
- -- (4) (5) (6)
- -- +---+---+---+ +---+---+---+ +---+---+---+
- -- | 1 | 2 | 3 | | 1 | 2 | 3 | | 1 | 2 | 3 |
- -- +---+---+---+ +---+---+---+ +---+---+---+
- -- | 4 | | | | 4 | 5 | | | 4 | 5 | 6 |
- -- +---+---+---+ -> +---+---+---+ -> +---+---+---+
+ -- (4) (5) (6)
+ -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- | 1 | 2 | 3 | | 1 | 2 | 3 | | 1 | 2 | 3 |
+ -- +---+---+---+ +---+---+---+ +---+---+---+
+ -- | 4 | | | | 4 | 5 | | | 4 | 5 | 6 |
+ -- +---+---+---+ -> +---+---+---+ -> +---+---+---+
- local num_y = math.max(math.ceil(#cls / num_x), ncol)
- local height = math.floor(wa.height/num_y)
+ local num_y = math.max(math.ceil(#cls / num_x), ncol)
+ local height = math.floor(wa.height / num_y)
- for i = #cls,1,-1 do
- -- Get x and y position.
- local c = cls[i]
- local this_x = (i - 1) % num_x
- local this_y = math.floor((i - this_x - 1) / num_x)
+ for i = #cls, 1, -1 do
+ -- Get x and y position.
+ local c = cls[i]
+ local this_x = (i - 1) % num_x
+ local this_y = math.floor((i - this_x - 1) / num_x)
- -- Calculate geometry.
- local g = {}
- if this_x == (num_x - 1) then
- g.width = wa.width - (num_x - 1)*width
- else
- g.width = width
- end
+ -- Calculate geometry.
+ local g = {}
+ if this_x == (num_x - 1) then
+ g.width = wa.width - (num_x - 1) * width
+ else
+ g.width = width
+ end
- if this_y == (num_y - 1) then
- g.height = wa.height - (num_y - 1)*height
- else
- g.height = height
- end
+ if this_y == (num_y - 1) then
+ g.height = wa.height - (num_y - 1) * height
+ else
+ g.height = height
+ end
- g.x = wa.x + this_x*width
- g.y = wa.y + this_y*height
+ g.x = wa.x + this_x * width
+ g.y = wa.y + this_y * height
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
- p.geometries[c] = g
- end
- elseif orientation == "center" then
- -- Layout with fixed number of vertical columns (read from nmaster).
- -- Cols are centerded until there is nmaster columns, then windows
- -- are stacked in the slave columns, with at most ncol clients per
- -- column if possible.
+ p.geometries[c] = g
+ end
+ elseif orientation == 'center' then
+ -- Layout with fixed number of vertical columns (read from nmaster).
+ -- Cols are centerded until there is nmaster columns, then windows
+ -- are stacked in the slave columns, with at most ncol clients per
+ -- column if possible.
- -- with nmaster=3 and ncol=1 you'll have
- -- (1) (2) (3)
- -- +---+---+---+ +-+---+---+-+ +---+---+---+
- -- | | | | | | | | | | | | |
- -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | ->
- -- | | | | | | | | | | | | |
- -- +---+---+---+ +-+---+---+-+ +---+---+---+
+ -- with nmaster=3 and ncol=1 you'll have
+ -- (1) (2) (3)
+ -- +---+---+---+ +-+---+---+-+ +---+---+---+
+ -- | | | | | | | | | | | | |
+ -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | ->
+ -- | | | | | | | | | | | | |
+ -- +---+---+---+ +-+---+---+-+ +---+---+---+
- -- (4) (5)
- -- +---+---+---+ +---+---+---+
- -- | | | 3 | | | 2 | 4 |
- -- + 1 + 2 +---+ -> + 1 +---+---+
- -- | | | 4 | | | 3 | 5 |
- -- +---+---+---+ +---+---+---+
+ -- (4) (5)
+ -- +---+---+---+ +---+---+---+
+ -- | | | 3 | | | 2 | 4 |
+ -- + 1 + 2 +---+ -> + 1 +---+---+
+ -- | | | 4 | | | 3 | 5 |
+ -- +---+---+---+ +---+---+---+
- if #cls < num_x then
- -- Less clients than the number of columns, let's center it!
- local offset_x = wa.x + (wa.width - #cls*width) / 2
- for i = 1, #cls do
- local g = { y = wa.y }
- g.width = width
- g.height = wa.height
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
- g.x = offset_x + (i - 1) * width
- p.geometries[cls[i]] = g
- end
- else
- -- More clients than the number of columns, let's arrange it!
- -- Master client deserves a special treatement
- local g = {}
- g.width = wa.width - (num_x - 1)*width
- g.height = wa.height
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
- g.x = wa.x
- g.y = wa.y
- p.geometries[cls[1]] = g
+ if #cls < num_x then
+ -- Less clients than the number of columns, let's center it!
+ local offset_x = wa.x + (wa.width - #cls * width) / 2
+ for i = 1, #cls do
+ local g = { y = wa.y }
+ g.width = width
+ g.height = wa.height
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
+ g.x = offset_x + (i - 1) * width
+ p.geometries[cls[i]] = g
+ end
+ else
+ -- More clients than the number of columns, let's arrange it!
+ -- Master client deserves a special treatement
+ local g = {}
+ g.width = wa.width - (num_x - 1) * width
+ g.height = wa.height
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
+ g.x = wa.x
+ g.y = wa.y
+ p.geometries[cls[1]] = g
- -- Treat the other clients
+ -- Treat the other clients
- -- Compute distribution of clients among columns
- local num_y = {}
- local remaining_clients = #cls-1
- local ncol_min = math.ceil(remaining_clients/(num_x-1))
+ -- Compute distribution of clients among columns
+ local num_y = {}
+ local remaining_clients = #cls - 1
+ local ncol_min = math.ceil(remaining_clients / (num_x - 1))
- if ncol >= ncol_min then
- for i = (num_x-1), 1, -1 do
- if (remaining_clients-i+1) < ncol then
- num_y[i] = remaining_clients-i + 1
- else
- num_y[i] = ncol
- end
- remaining_clients = remaining_clients - num_y[i]
- end
- else
- local rem = remaining_clients % (num_x-1)
- if rem == 0 then
- for i = 1, num_x-1 do
- num_y[i] = ncol_min
- end
- else
- for i = 1, num_x-1 do
- num_y[i] = ncol_min - 1
- end
- for i = 0, rem-1 do
- num_y[num_x-1-i] = num_y[num_x-1-i] + 1
- end
- end
- end
+ if ncol >= ncol_min then
+ for i = (num_x - 1), 1, -1 do
+ if (remaining_clients - i + 1) < ncol then
+ num_y[i] = remaining_clients - i + 1
+ else
+ num_y[i] = ncol
+ end
+ remaining_clients = remaining_clients - num_y[i]
+ end
+ else
+ local rem = remaining_clients % (num_x - 1)
+ if rem == 0 then
+ for i = 1, num_x - 1 do
+ num_y[i] = ncol_min
+ end
+ else
+ for i = 1, num_x - 1 do
+ num_y[i] = ncol_min - 1
+ end
+ for i = 0, rem - 1 do
+ num_y[num_x - 1 - i] = num_y[num_x - 1 - i] + 1
+ end
+ end
+ end
- -- Compute geometry of the other clients
- local nclient = 2 -- we start with the 2nd client
- local wx = g.x + g.width
- for i = 1, (num_x-1) do
- local height = math.floor(wa.height / num_y[i])
- local wy = wa.y
- for _ = 0, (num_y[i]-2) do
- g = {}
- g.x = wx
- g.y = wy
- g.height = height
- g.width = width
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
- p.geometries[cls[nclient]] = g
- nclient = nclient + 1
- wy = wy + height
- end
- g = {}
- g.x = wx
- g.y = wy
- g.height = wa.height - (num_y[i] - 1)*height
- g.width = width
- if g.width < 1 then g.width = 1 end
- if g.height < 1 then g.height = 1 end
- p.geometries[cls[nclient]] = g
- nclient = nclient + 1
- wx = wx + width
- end
- end
- end
+ -- Compute geometry of the other clients
+ local nclient = 2 -- we start with the 2nd client
+ local wx = g.x + g.width
+ for i = 1, (num_x - 1) do
+ local height = math.floor(wa.height / num_y[i])
+ local wy = wa.y
+ for _ = 0, (num_y[i] - 2) do
+ g = {}
+ g.x = wx
+ g.y = wy
+ g.height = height
+ g.width = width
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
+ p.geometries[cls[nclient]] = g
+ nclient = nclient + 1
+ wy = wy + height
+ end
+ g = {}
+ g.x = wx
+ g.y = wy
+ g.height = wa.height - (num_y[i] - 1) * height
+ g.width = width
+ if g.width < 1 then
+ g.width = 1
+ end
+ if g.height < 1 then
+ g.height = 1
+ end
+ p.geometries[cls[nclient]] = g
+ nclient = nclient + 1
+ wx = wx + width
+ end
+ end
+ end
end
function termfair.center.arrange(p)
- return do_fair(p, "center")
+ return do_fair(p, 'center')
end
function termfair.stable.arrange(p)
- return do_fair(p, "stable")
+ return do_fair(p, 'stable')
end
function termfair.arrange(p)
- return do_fair(p, "west")
+ return do_fair(p, 'west')
end
return termfair
diff --git a/awesome/lain/util/dkjson.lua b/awesome/lain/util/dkjson.lua
index 61cccb9..0cd5c08 100644
--- a/awesome/lain/util/dkjson.lua
+++ b/awesome/lain/util/dkjson.lua
@@ -43,705 +43,767 @@ SOFTWARE.
-- global dependencies:
local pairs, type, tostring, tonumber, getmetatable, setmetatable =
- pairs, type, tostring, tonumber, getmetatable, setmetatable
+ 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
-local json = { version = "dkjson 2.6" }
+local json = { version = 'dkjson 2.6' }
local jsonlpeg = {}
if register_global_module_table then
- if always_use_lpeg then
- _G[global_module_name] = jsonlpeg
- else
- _G[global_module_name] = json
- end
+ if always_use_lpeg then
+ _G[global_module_name] = jsonlpeg
+ else
+ _G[global_module_name] = json
+ end
end
_ENV = nil -- blocking globals in Lua 5.2 and later
-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
+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
end)
-json.null = setmetatable ({}, {
- __tojson = function () return "null" end
+json.null = setmetatable({}, {
+ __tojson = function()
+ return 'null'
+ end,
})
-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
- arraylen = v
- if v > max then
- max = v
- end
- else
- if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
- return false
- end
- if k > max then
- max = k
- end
- n = n + 1
- end
- end
- if max > 10 and max > arraylen and max > n * 2 then
- return false -- don't create an array with too many holes
- end
- return true, max
+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
+ arraylen = v
+ if v > max then
+ max = v
+ end
+ else
+ if type(k) ~= 'number' or k < 1 or floor(k) ~= k then
+ return false
+ end
+ if k > max then
+ max = k
+ end
+ n = n + 1
+ end
+ end
+ if max > 10 and max > arraylen and max > n * 2 then
+ return false -- don't create an array with too many holes
+ end
+ return true, max
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 value = escapecodes[uchar]
- if value then
- return value
- end
- 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
- elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
- value = (a - 0xc0) * 0x40 + b - 0x80
- elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
- value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
- elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
- value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
- else
- return ""
- end
- if value <= 0xffff then
- 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)
- else
- return ""
- end
+local function escapeutf8(uchar)
+ local value = escapecodes[uchar]
+ if value then
+ return value
+ end
+ 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
+ elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then
+ value = (a - 0xc0) * 0x40 + b - 0x80
+ elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then
+ value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80
+ elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then
+ value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80
+ else
+ return ''
+ end
+ if value <= 0xffff then
+ 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)
+ else
+ return ''
+ end
end
-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)
- else
- return str
- end
+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)
+ else
+ return str
+ end
end
-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)
- end
- return "\"" .. 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)
+ end
+ return '"' .. value .. '"'
end
json.quotestring = quotestring
local function replace(str, o, n)
- local i, j = strfind (str, o, 1, true)
- if i then
- return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1)
- else
- return str
- end
+ local i, j = strfind(str, o, 1, true)
+ if i then
+ return strsub(str, 1, i - 1) .. n .. strsub(str, j + 1, -1)
+ else
+ return str
+ end
end
-- locale independent num2str and str2num functions
local decpoint, numfilter
-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") .. "]+"
+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') .. ']+'
end
updatedecpoint()
-local function num2str (num)
- return replace(fsub(tostring(num), numfilter, ""), decpoint, ".")
+local function num2str(num)
+ return replace(fsub(tostring(num), numfilter, ''), decpoint, '.')
end
-local function str2num (str)
- local num = tonumber(replace(str, ".", decpoint))
- if not num then
- updatedecpoint()
- num = tonumber(replace(str, ".", decpoint))
- end
- return num
+local function str2num(str)
+ local num = tonumber(replace(str, '.', decpoint))
+ if not num then
+ updatedecpoint()
+ num = tonumber(replace(str, '.', decpoint))
+ end
+ return num
end
-local function addnewline2 (level, buffer, buflen)
- buffer[buflen+1] = "\n"
- buffer[buflen+2] = strrep (" ", level)
- buflen = buflen + 2
- return buflen
+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)
- if state.indent then
- state.bufferlen = addnewline2 (state.level or 0,
- state.buffer, state.bufferlen or #(state.buffer))
- end
+function json.addnewline(state)
+ if state.indent then
+ 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
- return nil, "type '" .. kt .. "' is not supported as a key by JSON."
- end
- if prev then
- buflen = buflen + 1
- buffer[buflen] = ","
- end
- if indent then
- 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)
+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
+ buflen = buflen + 1
+ buffer[buflen] = ','
+ end
+ if indent then
+ 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)
end
local function appendcustom(res, buffer, state)
- local buflen = state.bufferlen
- if type (res) == 'string' then
- buflen = buflen + 1
- buffer[buflen] = res
- end
- return buflen
+ local buflen = state.bufferlen
+ if type(res) == 'string' then
+ buflen = buflen + 1
+ buffer[buflen] = res
+ end
+ return buflen
end
local function exception(reason, value, state, buffer, buflen, defaultmessage)
- defaultmessage = defaultmessage or reason
- local handler = state.exception
- if not handler then
- 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
- return appendcustom(ret, buffer, state)
- end
+ defaultmessage = defaultmessage or reason
+ local handler = state.exception
+ if not handler then
+ 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
+ return appendcustom(ret, buffer, state)
+ end
end
function json.encodeexception(_reason, _value, _state, defaultmessage)
- return quotestring("<" .. 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
- local valtojson = valmeta and valmeta.__tojson
- if valtojson then
- if tables[value] then
- 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
- tables[value] = nil
- buflen = appendcustom(ret, buffer, state)
- elseif value == nil then
- buflen = buflen + 1
- buffer[buflen] = "null"
- 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)
- end
- buflen = buflen + 1
- buffer[buflen] = s
- elseif valtype == 'boolean' then
- buflen = buflen + 1
- buffer[buflen] = value and "true" or "false"
- elseif valtype == 'string' then
- buflen = buflen + 1
- buffer[buflen] = quotestring (value)
- elseif valtype == 'table' then
- if tables[value] then
- 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
- isa = false
- end
- local msg
- if isa then -- JSON array
- 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
- if i < n then
- buflen = buflen + 1
- buffer[buflen] = ","
- end
- end
- buflen = buflen + 1
- buffer[buflen] = "]"
- else -- JSON object
- local prev = false
- buflen = buflen + 1
- buffer[buflen] = "{"
- local order = valmeta and valmeta.__jsonorder or globalorder
- if order then
- local used = {}
- n = #order
- for i = 1, n do
- local k = order[i]
- local v = value[k]
- if v ~= nil then
- used[k] = true
- 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
- 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
- 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
- prev = true -- add a seperator before the next element
- end
- end
- if indent then
- 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.")
- end
- return buflen
+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)
+ 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
+ tables[value] = nil
+ buflen = appendcustom(ret, buffer, state)
+ elseif value == nil then
+ buflen = buflen + 1
+ buffer[buflen] = 'null'
+ 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)
+ end
+ buflen = buflen + 1
+ buffer[buflen] = s
+ elseif valtype == 'boolean' then
+ buflen = buflen + 1
+ buffer[buflen] = value and 'true' or 'false'
+ elseif valtype == 'string' then
+ buflen = buflen + 1
+ buffer[buflen] = quotestring(value)
+ elseif valtype == 'table' then
+ if tables[value] then
+ 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
+ isa = false
+ end
+ local msg
+ if isa then -- JSON array
+ 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
+ if i < n then
+ buflen = buflen + 1
+ buffer[buflen] = ','
+ end
+ end
+ buflen = buflen + 1
+ buffer[buflen] = ']'
+ else -- JSON object
+ local prev = false
+ buflen = buflen + 1
+ buffer[buflen] = '{'
+ local order = valmeta and valmeta.__jsonorder or globalorder
+ if order then
+ local used = {}
+ n = #order
+ for i = 1, n do
+ local k = order[i]
+ local v = value[k]
+ if v ~= nil then
+ used[k] = true
+ 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
+ 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
+ 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
+ prev = true -- add a seperator before the next element
+ end
+ end
+ if indent then
+ 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."
+ )
+ end
+ return buflen
end
-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)
- if not ret then
- error (msg, 2)
- elseif oldbuffer == buffer then
- state.bufferlen = ret
- return true
- else
- state.bufferlen = nil
- state.buffer = nil
- return concat (buffer)
- end
+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
+ )
+ if not ret then
+ error(msg, 2)
+ elseif oldbuffer == buffer then
+ state.bufferlen = ret
+ return true
+ else
+ state.bufferlen = nil
+ state.buffer = nil
+ return concat(buffer)
+ end
end
-local function loc (str, where)
- local line, pos, linepos = 1, 1, 0
- while true do
- pos = strfind (str, "\n", pos, true)
- if pos and pos < where then
- line = line + 1
- linepos = pos
- pos = pos + 1
- else
- break
- end
- end
- return "line " .. line .. ", column " .. (where - linepos)
+local function loc(str, where)
+ local line, pos, linepos = 1, 1, 0
+ while true do
+ pos = strfind(str, '\n', pos, true)
+ if pos and pos < where then
+ line = line + 1
+ linepos = pos
+ pos = pos + 1
+ else
+ break
+ end
+ end
+ 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)
- 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
- -- 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
- elseif sub2 == "/*" then
- pos = strfind (str, "*/", pos + 2)
- if not pos then return nil end
- pos = pos + 2
- else
- return pos
- end
- end
+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
+ -- 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
+ elseif sub2 == '/*' then
+ pos = strfind(str, '*/', pos + 2)
+ if not pos then
+ return nil
+ end
+ pos = pos + 2
+ else
+ return pos
+ end
+ end
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)
- if value < 0 then
- return nil
- elseif value <= 0x007f then
- return strchar (value)
- elseif value <= 0x07ff then
- 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))
- elseif value <= 0x10ffff then
- return strchar (0xf0 + floor(value/0x40000),
- 0x80 + (floor(value/0x1000) % 0x40),
- 0x80 + (floor(value/0x40) % 0x40),
- 0x80 + (floor(value) % 0x40))
- else
- return nil
- end
+local function unichar(value)
+ if value < 0 then
+ return nil
+ elseif value <= 0x007f then
+ return strchar(value)
+ elseif value <= 0x07ff then
+ 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))
+ elseif value <= 0x10ffff then
+ 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 lastpos = pos + 1
- local buffer, n = {}, 0
- while true do
- local nextpos = strfind (str, "[\"\\]", lastpos)
- if not nextpos then
- return unterminated (str, "string", pos)
- end
- if nextpos > lastpos then
- n = n + 1
- buffer[n] = strsub (str, lastpos, nextpos - 1)
- end
- if strsub (str, nextpos, nextpos) == "\"" then
- lastpos = nextpos + 1
- break
- else
- local escchar = strsub (str, nextpos + 1, nextpos + 1)
- local value
- if escchar == "u" then
- 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 value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
- value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
- else
- value2 = nil -- in case it was out of range for a low surrogate
- end
- end
- end
- value = value and unichar (value)
- if value then
- if value2 then
- lastpos = nextpos + 12
- else
- lastpos = nextpos + 6
- end
- end
- end
- end
- if not value then
- value = escapechars[escchar] or escchar
- lastpos = nextpos + 2
- end
- n = n + 1
- buffer[n] = value
- end
- end
- if n == 1 then
- return buffer[1], lastpos
- elseif n > 1 then
- return concat (buffer), lastpos
- else
- return "", lastpos
- end
+local function scanstring(str, pos)
+ local lastpos = pos + 1
+ local buffer, n = {}, 0
+ while true do
+ local nextpos = strfind(str, '["\\]', lastpos)
+ if not nextpos then
+ return unterminated(str, 'string', pos)
+ end
+ if nextpos > lastpos then
+ n = n + 1
+ buffer[n] = strsub(str, lastpos, nextpos - 1)
+ end
+ if strsub(str, nextpos, nextpos) == '"' then
+ lastpos = nextpos + 1
+ break
+ else
+ local escchar = strsub(str, nextpos + 1, nextpos + 1)
+ local value
+ if escchar == 'u' then
+ 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 value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then
+ value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000
+ else
+ value2 = nil -- in case it was out of range for a low surrogate
+ end
+ end
+ end
+ value = value and unichar(value)
+ if value then
+ if value2 then
+ lastpos = nextpos + 12
+ else
+ lastpos = nextpos + 6
+ end
+ end
+ end
+ end
+ if not value then
+ value = escapechars[escchar] or escchar
+ lastpos = nextpos + 2
+ end
+ n = n + 1
+ buffer[n] = value
+ end
+ end
+ if n == 1 then
+ return buffer[1], lastpos
+ elseif n > 1 then
+ return concat(buffer), lastpos
+ else
+ return '', lastpos
+ end
end
local scanvalue -- forward declaration
-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)
- else
- 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)
- 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)
- if char == ":" then
- if val1 == nil then
- 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
- local val2
- 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)
- else
- n = n + 1
- tbl[n] = val1
- end
- if char == "," then
- pos = pos + 1
- end
- end
+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)
+ else
+ 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)
+ 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)
+ if char == ':' then
+ if val1 == nil then
+ 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
+ local val2
+ 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)
+ else
+ n = n + 1
+ tbl[n] = val1
+ end
+ if char == ',' then
+ pos = pos + 1
+ end
+ end
end
-scanvalue = function (str, pos, nullval, objectmeta, arraymeta)
- pos = pos or 1
- pos = scanwhite (str, pos)
- if not pos then
- return nil, strlen (str) + 1, "no valid JSON value (reached the end)"
- end
- local char = strsub (str, pos, pos)
- if char == "{" then
- 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)
- else
- local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos)
- if pstart then
- local number = str2num (strsub (str, pstart, pend))
- if number then
- return number, pend + 1
- end
- end
- pstart, pend = strfind (str, "^%a%w*", pos)
- if pstart then
- local name = strsub (str, pstart, pend)
- if name == "true" then
- return true, pend + 1
- elseif name == "false" then
- return false, pend + 1
- elseif name == "null" then
- return nullval, pend + 1
- end
- end
- return nil, pos, "no valid JSON value at " .. loc (str, pos)
- end
+scanvalue = function(str, pos, nullval, objectmeta, arraymeta)
+ pos = pos or 1
+ pos = scanwhite(str, pos)
+ if not pos then
+ return nil, strlen(str) + 1, 'no valid JSON value (reached the end)'
+ end
+ local char = strsub(str, pos, pos)
+ if char == '{' then
+ 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)
+ else
+ local pstart, pend = strfind(str, '^%-?[%d%.]+[eE]?[%+%-]?%d*', pos)
+ if pstart then
+ local number = str2num(strsub(str, pstart, pend))
+ if number then
+ return number, pend + 1
+ end
+ end
+ pstart, pend = strfind(str, '^%a%w*', pos)
+ if pstart then
+ local name = strsub(str, pstart, pend)
+ if name == 'true' then
+ return true, pend + 1
+ elseif name == 'false' then
+ return false, pend + 1
+ elseif name == 'null' then
+ return nullval, pend + 1
+ end
+ end
+ return nil, pos, 'no valid JSON value at ' .. loc(str, pos)
+ end
end
local function optionalmetatables(...)
- if select("#", ...) > 0 then
- return ...
- else
- return {__jsontype = 'object'}, {__jsontype = 'array'}
- end
+ if select('#', ...) > 0 then
+ return ...
+ else
+ return { __jsontype = 'object' }, { __jsontype = 'array' }
+ end
end
-function json.decode (str, pos, nullval, ...)
- local objectmeta, arraymeta = optionalmetatables(...)
- return scanvalue (str, pos, nullval, objectmeta, arraymeta)
+function json.decode(str, pos, nullval, ...)
+ local objectmeta, arraymeta = optionalmetatables(...)
+ 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"
- end
+ if g.version() == '0.11' then
+ 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 pegmatch = g.match
+ local P, S, R = g.P, g.S, g.R
- local function ErrorCall (str, pos, msg, state)
- if not state.msg then
- state.msg = msg .. " at " .. loc (str, pos)
- state.pos = pos
- end
- return false
- end
+ local function ErrorCall(str, pos, msg, state)
+ if not state.msg then
+ 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)
- end
+ 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)
- end
+ 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)
- end
+ 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 HexDigit = R("09", "af", "AF")
- 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)
- else
- return false
- end
- end
- 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 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 SimpleValue = Number + String + Constant
- local ArrayContent, ObjectContent
+ 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)
+ if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then
+ return true, unichar((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000)
+ else
+ return false
+ end
+ end
+ 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 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 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 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)
- end
- pos = npos
- if cont == 'cont' or cont == 'last' then
- nt = nt + 1
- t[nt] = obj
- end
- until cont ~= 'cont'
- return pos, setmetatable (t, state.arraymeta)
- end
+ -- 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 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)
+ end
+ pos = npos
+ if cont == 'cont' or cont == 'last' then
+ nt = nt + 1
+ t[nt] = obj
+ end
+ until cont ~= 'cont'
+ return pos, setmetatable(t, state.arraymeta)
+ end
- 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)
- end
- pos = npos
- if cont == 'cont' or cont == 'last' then
- t[key] = obj
- end
- until cont ~= 'cont'
- return pos, setmetatable (t, state.objectmeta)
- end
+ 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)
+ end
+ pos = npos
+ if cont == 'cont' or cont == 'last' then
+ t[key] = obj
+ end
+ 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 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 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()
- jsonlpeg.version = json.version
- jsonlpeg.encode = json.encode
- jsonlpeg.null = json.null
- jsonlpeg.quotestring = json.quotestring
- jsonlpeg.addnewline = json.addnewline
- jsonlpeg.encodeexception = json.encodeexception
- jsonlpeg.using_lpeg = true
+ jsonlpeg.version = json.version
+ jsonlpeg.encode = json.encode
+ jsonlpeg.null = json.null
+ jsonlpeg.quotestring = json.quotestring
+ jsonlpeg.addnewline = json.addnewline
+ jsonlpeg.encodeexception = json.encodeexception
+ jsonlpeg.using_lpeg = true
- function jsonlpeg.decode (str, pos, nullval, ...)
- local state = {}
- state.objectmeta, state.arraymeta = optionalmetatables(...)
- local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state)
- if state.msg then
- return nil, state.pos, state.msg
- else
- return obj, retpos
- end
- end
+ function jsonlpeg.decode(str, pos, nullval, ...)
+ local state = {}
+ state.objectmeta, state.arraymeta = optionalmetatables(...)
+ local obj, retpos = pegmatch(DecodeValue, str, pos, nullval, state)
+ if state.msg then
+ return nil, state.pos, state.msg
+ else
+ return obj, retpos
+ end
+ end
- -- cache result of this function:
- json.use_lpeg = function () return jsonlpeg end
- jsonlpeg.use_lpeg = json.use_lpeg
+ -- cache result of this function:
+ json.use_lpeg = function()
+ return jsonlpeg
+ end
+ jsonlpeg.use_lpeg = json.use_lpeg
- return jsonlpeg
+ return jsonlpeg
end
if always_use_lpeg then
- return json.use_lpeg()
+ return json.use_lpeg()
end
return json
-
diff --git a/awesome/lain/util/init.lua b/awesome/lain/util/init.lua
index 5ae0523..accd219 100644
--- a/awesome/lain/util/init.lua
+++ b/awesome/lain/util/init.lua
@@ -11,180 +11,200 @@
--]]
-local awful = require("awful")
-local sqrt = math.sqrt
-local pairs = pairs
-local client = client
-local tonumber = tonumber
-local wrequire = require("lain.helpers").wrequire
+local awful = require('awful')
+local sqrt = math.sqrt
+local pairs = pairs
+local client = client
+local tonumber = tonumber
+local wrequire = require('lain.helpers').wrequire
local setmetatable = setmetatable
-- Lain utilities submodule
-- lain.util
-local util = { _NAME = "lain.util" }
+local util = { _NAME = 'lain.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
+ -- 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 = {}
+ -- 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
- local t = cls_tags[i]
- local cls = t:clients()
+ -- 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
+ 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 ()
- c.minimized = false
- client.focus = c
- c:raise()
- end,
- c.icon }
- end
- end
+ for _, c in pairs(cls) do
+ cls_t[#cls_t + 1] = {
+ awful.util.escape(c.name) or '',
+ function()
+ c.minimized = false
+ client.focus = c
+ c:raise()
+ end,
+ c.icon,
+ }
+ end
+ end
- -- No clients? Then quit.
- if #cls_t <= 0 then return nil end
+ -- No clients? Then quit.
+ 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
+ -- menu may contain some predefined values, otherwise start with a
+ -- fresh menu.
+ if not menu then
+ menu = {}
+ end
- -- Set the list of items and show the menu.
- menu.items = cls_t
- local m = awful.menu(menu)
- m:show(args)
+ -- Set the list of items and show the menu.
+ menu.items = cls_t
+ local m = awful.menu(menu)
+ m:show(args)
- return m
+ return m
end
-- Magnify a client: set it to "float" and resize it.
function util.magnify_client(c, width_f, height_f)
- if c and not c.floating then
- util.magnified_client = c
- util.mc(c, width_f, height_f)
- else
- util.magnified_client = nil
- c.floating = false
- end
+ if c and not c.floating then
+ util.magnified_client = c
+ util.mc(c, width_f, height_f)
+ else
+ util.magnified_client = nil
+ c.floating = false
+ end
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
+ c = c or util.magnified_client
+ if not c then
+ return
+ end
- c.floating = true
- local s = awful.screen.focused()
- local mg = s.workarea
- local g = {}
- local mwfact = width_f or s.selected_tag.master_width_factor or 0.5
- g.width = sqrt(mwfact) * mg.width
- g.height = sqrt(height_f or mwfact) * mg.height
- g.x = mg.x + (mg.width - g.width) / 2
- g.y = mg.y + (mg.height - g.height) / 2
+ c.floating = true
+ local s = awful.screen.focused()
+ local mg = s.workarea
+ local g = {}
+ local mwfact = width_f or s.selected_tag.master_width_factor or 0.5
+ g.width = sqrt(mwfact) * mg.width
+ g.height = sqrt(height_f or mwfact) * mg.height
+ 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)
- direction = direction or 1
- local s = sc or awful.screen.focused()
- local tags = s.tags
- local sel = s.selected_tag
+function util.tag_view_nonempty(direction, sc)
+ direction = direction or 1
+ local s = sc or awful.screen.focused()
+ local tags = s.tags
+ local sel = s.selected_tag
- local i = sel.index
- repeat
- i = i + direction
+ local i = sel.index
+ repeat
+ i = i + direction
- -- Wrap around when we reach one of the bounds
- if i > #tags then
- i = i - #tags
- end
- if i < 1 then
- i = i + #tags
- end
+ -- Wrap around when we reach one of the bounds
+ if i > #tags then
+ i = i - #tags
+ end
+ if i < 1 then
+ i = i + #tags
+ end
- local t = tags[i]
+ local t = tags[i]
- -- Stop when we get back to where we started
- if t == sel then
- break
- end
+ -- Stop when we get back to where we started
+ if t == sel then
+ break
+ end
- -- If it's The One, view it.
- if #t:clients() > 0 then
- t:view_only()
- return
- end
- until false
+ -- If it's The One, view it.
+ if #t:clients() > 0 then
+ t:view_only()
+ return
+ end
+ until false
end
-- {{{ Dynamic tagging
-- Add a new tag
function util.add_tag(layout)
- 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()
- end
- }
+ 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()
+ end,
+ })
end
-- Rename current tag
function util.rename_tag()
- 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
- local t = awful.screen.focused().selected_tag
- if t then
- t.name = new_name
- end
- end
- }
+ 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
+ local t = awful.screen.focused().selected_tag
+ if t then
+ t.name = new_name
+ end
+ end,
+ })
end
-- Move current tag
-- pos in {-1, 1} <-> {previous, next} tag position
function util.move_tag(pos)
- local tag = awful.screen.focused().selected_tag
- if tonumber(pos) <= -1 then
- awful.tag.move(tag.index - 1, tag)
- else
- awful.tag.move(tag.index + 1, tag)
- end
+ local tag = awful.screen.focused().selected_tag
+ if tonumber(pos) <= -1 then
+ awful.tag.move(tag.index - 1, tag)
+ else
+ awful.tag.move(tag.index + 1, tag)
+ end
end
-- Delete current tag
-- 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
- t:delete()
+ local t = awful.screen.focused().selected_tag
+ if not t then
+ return
+ end
+ t:delete()
end
-- }}}
-- On the fly useless gaps change
function util.useless_gaps_resize(thatmuch, s, t)
- local scr = s or awful.screen.focused()
- local tag = t or scr.selected_tag
- tag.gap = tag.gap + tonumber(thatmuch)
- awful.layout.arrange(scr)
+ local scr = s or awful.screen.focused()
+ local tag = t or scr.selected_tag
+ tag.gap = tag.gap + tonumber(thatmuch)
+ awful.layout.arrange(scr)
end
return setmetatable(util, { __index = wrequire })
diff --git a/awesome/lain/util/markup.lua b/awesome/lain/util/markup.lua
index 63f9486..831b83d 100644
--- a/awesome/lain/util/markup.lua
+++ b/awesome/lain/util/markup.lua
@@ -15,52 +15,78 @@ local setmetatable = setmetatable
local markup = { fg = {}, bg = {} }
-- Convenience tags
-function markup.bold(text) return format("%s", text) end
-function markup.italic(text) return format("%s", text) end
-function markup.strike(text) return format("%s", text) end
-function markup.underline(text) return format("%s", text) end
-function markup.monospace(text) return format("%s", text) end
-function markup.big(text) return format("%s", text) end
-function markup.small(text) return format("%s", text) end
+function markup.bold(text)
+ return format('%s', text)
+end
+function markup.italic(text)
+ return format('%s', text)
+end
+function markup.strike(text)
+ return format('%s', text)
+end
+function markup.underline(text)
+ return format('%s', text)
+end
+function markup.monospace(text)
+ return format('%s', text)
+end
+function markup.big(text)
+ return format('%s', text)
+end
+function markup.small(text)
+ return format('%s', text)
+end
-- Set the font
function markup.font(font, text)
- return format("%s", font, text)
+ return format("%s", font, text)
end
-- Set the foreground
function markup.fg.color(color, text)
- return format("%s", color, text)
+ return format("%s", color, text)
end
-- Set the background
function markup.bg.color(color, text)
- return format("%s", color, text)
+ return format("%s", color, text)
end
-- Set foreground and background
function markup.color(fg, bg, text)
- return format("%s", fg, bg, text)
+ return format("%s", fg, bg, text)
end
-- Set font and foreground
function markup.fontfg(font, fg, text)
- return format("%s", font, fg, text)
+ return format("%s", font, fg, text)
end
-- Set font and background
function markup.fontbg(font, bg, text)
- return format("%s", font, bg, text)
+ return format("%s", font, bg, text)
end
-- Set font, foreground and background
function markup.fontcolor(font, fg, bg, text)
- return format("%s", font, fg, bg, text)
+ return format("%s", font, fg, bg, text)
end
-- link markup.{fg,bg}(...) calls to markup.{fg,bg}.color(...)
-setmetatable(markup.fg, { __call = function(_, ...) return markup.fg.color(...) end })
-setmetatable(markup.bg, { __call = function(_, ...) return markup.bg.color(...) end })
+setmetatable(markup.fg, {
+ __call = function(_, ...)
+ return markup.fg.color(...)
+ end,
+})
+setmetatable(markup.bg, {
+ __call = function(_, ...)
+ return markup.bg.color(...)
+ end,
+})
-- link markup(...) calls to markup.fg.color(...)
-return setmetatable(markup, { __call = function(_, ...) return markup.fg.color(...) end })
+return setmetatable(markup, {
+ __call = function(_, ...)
+ return markup.fg.color(...)
+ end,
+})
diff --git a/awesome/lain/util/menu_iterator.lua b/awesome/lain/util/menu_iterator.lua
index d457473..104544f 100644
--- a/awesome/lain/util/menu_iterator.lua
+++ b/awesome/lain/util/menu_iterator.lua
@@ -10,28 +10,30 @@
-- Menu iterator with Naughty notifications
-- lain.util.menu_iterator
-local naughty = require("naughty")
-local helpers = require("lain.helpers")
-local atable = require("awful.util").table
-local assert = assert
-local pairs = pairs
+local naughty = require('naughty')
+local helpers = require('lain.helpers')
+local atable = require('awful.util').table
+local assert = assert
+local pairs = pairs
local tconcat = table.concat
local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
local state = { cid = nil }
local function naughty_destroy_callback(reason)
- local closed = naughty.notificationClosedReason
- if reason == closed.expired or reason == closed.dismissedByUser then
- local actions = state.index and state.menu[state.index - 1][2]
- if actions then
- for _,action in pairs(actions) do
- -- don't try to call nil callbacks
- if action then action() end
- end
- state.index = nil
- end
- end
+ local closed = naughty.notificationClosedReason
+ if reason == closed.expired or reason == closed.dismissedByUser then
+ local actions = state.index and state.menu[state.index - 1][2]
+ if actions then
+ for _, action in pairs(actions) do
+ -- don't try to call nil callbacks
+ if action then
+ action()
+ end
+ end
+ state.index = nil
+ end
+ end
end
-- Iterates over a menu.
@@ -41,35 +43,35 @@ end
-- * timeout: time to wait before confirming the menu selection
-- * icon: icon to display in the notification of the chosen label
local function iterate(menu, timeout, icon)
- timeout = timeout or 4 -- default timeout for each menu entry
- icon = icon or nil -- icon to display on the menu
+ timeout = timeout or 4 -- default timeout for each menu entry
+ icon = icon or nil -- icon to display on the menu
- -- Build the list of choices
- if not state.index then
- state.menu = menu
- state.index = 1
- end
+ -- Build the list of choices
+ if not state.index then
+ state.menu = menu
+ state.index = 1
+ end
- -- Select one and display the appropriate notification
- local label
- local next = state.menu[state.index]
- state.index = state.index + 1
+ -- Select one and display the appropriate notification
+ local label
+ local next = state.menu[state.index]
+ state.index = state.index + 1
- if not next then
- label = "Cancel"
- state.index = nil
- else
- label, _ = unpack(next)
- end
+ if not next then
+ label = 'Cancel'
+ state.index = nil
+ else
+ label, _ = unpack(next)
+ end
- state.cid = naughty.notify({
- text = label,
- icon = icon,
- timeout = timeout,
- screen = mouse.screen,
- replaces_id = state.cid,
- destroy = naughty_destroy_callback
- }).id
+ state.cid = naughty.notify({
+ text = label,
+ icon = icon,
+ timeout = timeout,
+ screen = mouse.screen,
+ replaces_id = state.cid,
+ destroy = naughty_destroy_callback,
+ }).id
end
-- Generates a menu compatible with the first argument of `iterate` function and
@@ -95,50 +97,55 @@ end
-- Output:
-- * m: menu to be iterated over.
local function menu(args)
- local choices = assert(args.choices or args[1])
- local name = assert(args.name or args[2])
- local selected_cb = args.selected_cb
- local rejected_cb = args.rejected_cb
- local extra_choices = args.extra_choices or {}
+ local choices = assert(args.choices or args[1])
+ local name = assert(args.name or args[2])
+ local selected_cb = args.selected_cb
+ local rejected_cb = args.rejected_cb
+ local extra_choices = args.extra_choices or {}
- local ch_combinations = args.combination == "powerset" and helpers.powerset(choices) or helpers.trivial_partition_set(choices)
+ local ch_combinations = args.combination == 'powerset' and helpers.powerset(choices)
+ or helpers.trivial_partition_set(choices)
- for _, c in pairs(extra_choices) do
- ch_combinations = atable.join(ch_combinations, {{c[1]}})
- end
+ for _, c in pairs(extra_choices) do
+ ch_combinations = atable.join(ch_combinations, { { c[1] } })
+ end
- local m = {} -- the menu
+ local m = {} -- the menu
- for _,c in pairs(ch_combinations) do
- if #c > 0 then
- local cbs = {}
+ for _, c in pairs(ch_combinations) do
+ if #c > 0 then
+ local cbs = {}
- -- selected choices
- for _,ch in pairs(c) do
- if atable.hasitem(choices, ch) then
- cbs[#cbs + 1] = selected_cb and function() selected_cb(ch) end or nil
- end
- end
+ -- selected choices
+ for _, ch in pairs(c) do
+ if atable.hasitem(choices, ch) then
+ cbs[#cbs + 1] = selected_cb and function()
+ selected_cb(ch)
+ end or nil
+ end
+ end
- -- rejected choices
- for _,ch in pairs(choices) do
- if not atable.hasitem(c, ch) and atable.hasitem(choices, ch) then
- cbs[#cbs + 1] = rejected_cb and function() rejected_cb(ch) end or nil
- end
- end
+ -- rejected choices
+ for _, ch in pairs(choices) do
+ if not atable.hasitem(c, ch) and atable.hasitem(choices, ch) then
+ cbs[#cbs + 1] = rejected_cb and function()
+ rejected_cb(ch)
+ end or nil
+ end
+ end
- -- add user extra choices (like the choice "None" for example)
- for _,x in pairs(extra_choices) do
- if x[1] == c[1] then
- cbs[#cbs + 1] = x[2]
- end
- end
+ -- add user extra choices (like the choice "None" for example)
+ for _, x in pairs(extra_choices) do
+ if x[1] == c[1] then
+ cbs[#cbs + 1] = x[2]
+ end
+ end
- m[#m + 1] = { name .. ": " .. tconcat(c, " + "), cbs }
- end
- end
+ m[#m + 1] = { name .. ': ' .. tconcat(c, ' + '), cbs }
+ end
+ end
- return m
+ return m
end
return { iterate = iterate, menu = menu }
diff --git a/awesome/lain/util/quake.lua b/awesome/lain/util/quake.lua
index 8bc68a7..0fbd748 100644
--- a/awesome/lain/util/quake.lua
+++ b/awesome/lain/util/quake.lua
@@ -6,12 +6,12 @@
--]]
-local awful = require("awful")
-local capi = { client = client }
-local math = math
-local string = string
-local pairs = pairs
-local screen = screen
+local awful = require('awful')
+local capi = { client = client }
+local math = math
+local string = string
+local pairs = pairs
+local screen = screen
local setmetatable = setmetatable
-- Quake-like Dropdown application spawn
@@ -22,158 +22,182 @@ local quake = {}
-- run into problems with focus.
function quake:display()
- if self.followtag then self.screen = awful.screen.focused() end
+ if self.followtag then
+ self.screen = awful.screen.focused()
+ end
- -- First, we locate the client
- local client = nil
- local i = 0
- for c in awful.client.iterate(function (c)
- -- c.name may be changed!
- return c.instance == self.name
- end)
- do
- i = i + 1
- if i == 1 then
- client = c
- else
- -- Additional matching clients, let's remove the sticky bit
- -- which may persist between awesome restarts. We don't close
- -- them as they may be valuable. They will just turn into
- -- normal clients.
- c.sticky = false
- c.ontop = false
- c.above = false
- end
- end
+ -- First, we locate the client
+ local client = nil
+ local i = 0
+ for c in
+ awful.client.iterate(function(c)
+ -- c.name may be changed!
+ return c.instance == self.name
+ end)
+ do
+ i = i + 1
+ if i == 1 then
+ client = c
+ else
+ -- Additional matching clients, let's remove the sticky bit
+ -- which may persist between awesome restarts. We don't close
+ -- them as they may be valuable. They will just turn into
+ -- normal clients.
+ c.sticky = false
+ c.ontop = false
+ c.above = false
+ end
+ end
- if not client and not self.visible then return end
+ if not client and not self.visible then
+ return
+ end
- if not client then
- -- The client does not exist, we spawn it
- local cmd = string.format("%s %s %s", self.app,
- string.format(self.argname, self.name), self.extra)
- awful.spawn(cmd, { tag = self.screen.selected_tag })
- return
- end
+ if not client then
+ -- The client does not exist, we spawn it
+ local cmd = string.format('%s %s %s', self.app, string.format(self.argname, self.name), self.extra)
+ awful.spawn(cmd, { tag = self.screen.selected_tag })
+ return
+ end
- -- Set geometry
- client.floating = true
- client.border_width = self.border
- client.size_hints_honor = false
- local maximized = client.maximized
- local fullscreen = client.fullscreen
- client:geometry(self.geometry[self.screen.index] or self:compute_size())
+ -- Set geometry
+ client.floating = true
+ client.border_width = self.border
+ client.size_hints_honor = false
+ local maximized = client.maximized
+ local fullscreen = client.fullscreen
+ client:geometry(self.geometry[self.screen.index] or self:compute_size())
- -- Set not sticky and on top
- client.sticky = false
- client.ontop = true
- client.above = true
- client.skip_taskbar = true
+ -- Set not sticky and on top
+ client.sticky = false
+ client.ontop = true
+ client.above = true
+ client.skip_taskbar = true
- -- Additional user settings
- if self.settings then self.settings(client) end
+ -- Additional user settings
+ if self.settings then
+ self.settings(client)
+ end
- -- Toggle display
- if self.visible then
- client.hidden = false
- client.maximized = self.maximized
- client.fullscreen = self.fullscreen
- client:raise()
- self.last_tag = self.screen.selected_tag
- client:tags({self.screen.selected_tag})
- capi.client.focus = client
- else
- self.maximized = maximized
- self.fullscreen = fullscreen
- client.maximized = false
- client.fullscreen = false
- client.hidden = true
- local ctags = client:tags()
- for j, _ in pairs(ctags) do
- ctags[j] = nil
- end
- client:tags(ctags)
- end
+ -- Toggle display
+ if self.visible then
+ client.hidden = false
+ client.maximized = self.maximized
+ client.fullscreen = self.fullscreen
+ client:raise()
+ self.last_tag = self.screen.selected_tag
+ client:tags({ self.screen.selected_tag })
+ capi.client.focus = client
+ else
+ self.maximized = maximized
+ self.fullscreen = fullscreen
+ client.maximized = false
+ client.fullscreen = false
+ client.hidden = true
+ local ctags = client:tags()
+ for j, _ in pairs(ctags) do
+ ctags[j] = nil
+ end
+ client:tags(ctags)
+ end
- return client
+ return client
end
function quake:compute_size()
- -- skip if we already have a geometry for this screen
- if not self.geometry[self.screen.index] then
- local geom
- if not self.overlap then
- geom = screen[self.screen.index].workarea
- else
- geom = screen[self.screen.index].geometry
- end
- local width, height = self.width, self.height
- if width <= 1 then width = math.floor(geom.width * width) - 2 * self.border end
- if height <= 1 then height = math.floor(geom.height * height) end
- local x, y
- if self.horiz == "left" then x = geom.x
- elseif self.horiz == "right" then x = geom.width + geom.x - width
- else x = geom.x + (geom.width - width)/2 end
- if self.vert == "top" then y = geom.y
- elseif self.vert == "bottom" then y = geom.height + geom.y - height
- else y = geom.y + (geom.height - height)/2 end
- self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height }
- end
- return self.geometry[self.screen.index]
+ -- skip if we already have a geometry for this screen
+ if not self.geometry[self.screen.index] then
+ local geom
+ if not self.overlap then
+ geom = screen[self.screen.index].workarea
+ else
+ geom = screen[self.screen.index].geometry
+ end
+ local width, height = self.width, self.height
+ if width <= 1 then
+ width = math.floor(geom.width * width) - 2 * self.border
+ end
+ if height <= 1 then
+ height = math.floor(geom.height * height)
+ end
+ local x, y
+ if self.horiz == 'left' then
+ x = geom.x
+ elseif self.horiz == 'right' then
+ x = geom.width + geom.x - width
+ else
+ x = geom.x + (geom.width - width) / 2
+ end
+ if self.vert == 'top' then
+ y = geom.y
+ elseif self.vert == 'bottom' then
+ y = geom.height + geom.y - height
+ else
+ y = geom.y + (geom.height - height) / 2
+ end
+ self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height }
+ end
+ return self.geometry[self.screen.index]
end
function quake:toggle()
- if self.followtag then self.screen = awful.screen.focused() end
- local current_tag = self.screen.selected_tag
- if current_tag and self.last_tag ~= current_tag and self.visible then
- local c=self:display()
- if c then
- c:move_to_tag(current_tag)
- end
- else
- self.visible = not self.visible
- self:display()
- end
+ if self.followtag then
+ self.screen = awful.screen.focused()
+ end
+ local current_tag = self.screen.selected_tag
+ if current_tag and self.last_tag ~= current_tag and self.visible then
+ local c = self:display()
+ if c then
+ c:move_to_tag(current_tag)
+ end
+ else
+ self.visible = not self.visible
+ self:display()
+ end
end
function quake.new(conf)
- conf = conf or {}
+ conf = conf or {}
- conf.app = conf.app or "xterm" -- application to spawn
- conf.name = conf.name or "QuakeDD" -- window name
- conf.argname = conf.argname or "-name %s" -- how to specify window name
- conf.extra = conf.extra or "" -- extra arguments
- conf.border = conf.border or 1 -- client border width
- conf.visible = conf.visible or false -- initially not visible
- conf.followtag = conf.followtag or false -- spawn on currently focused screen
- conf.overlap = conf.overlap or false -- overlap wibox
- conf.screen = conf.screen or awful.screen.focused()
- conf.settings = conf.settings
+ conf.app = conf.app or 'xterm' -- application to spawn
+ conf.name = conf.name or 'QuakeDD' -- window name
+ conf.argname = conf.argname or '-name %s' -- how to specify window name
+ conf.extra = conf.extra or '' -- extra arguments
+ conf.border = conf.border or 1 -- client border width
+ conf.visible = conf.visible or false -- initially not visible
+ conf.followtag = conf.followtag or false -- spawn on currently focused screen
+ conf.overlap = conf.overlap or false -- overlap wibox
+ conf.screen = conf.screen or awful.screen.focused()
+ conf.settings = conf.settings
- -- If width or height <= 1 this is a proportion of the workspace
- conf.height = conf.height or 0.25 -- height
- conf.width = conf.width or 1 -- width
- conf.vert = conf.vert or "top" -- top, bottom or center
- conf.horiz = conf.horiz or "left" -- left, right or center
- conf.geometry = {} -- internal use
+ -- If width or height <= 1 this is a proportion of the workspace
+ conf.height = conf.height or 0.25 -- height
+ conf.width = conf.width or 1 -- width
+ conf.vert = conf.vert or 'top' -- top, bottom or center
+ conf.horiz = conf.horiz or 'left' -- left, right or center
+ conf.geometry = {} -- internal use
- conf.maximized = false
- conf.fullscreen = false
+ conf.maximized = false
+ conf.fullscreen = false
- local dropdown = setmetatable(conf, { __index = quake })
+ local dropdown = setmetatable(conf, { __index = quake })
- capi.client.connect_signal("manage", function(c)
- if c.instance == dropdown.name and c.screen == dropdown.screen then
- dropdown:display()
- end
- end)
- capi.client.connect_signal("unmanage", function(c)
- if c.instance == dropdown.name and c.screen == dropdown.screen then
- dropdown.visible = false
- end
- end)
+ capi.client.connect_signal('manage', function(c)
+ if c.instance == dropdown.name and c.screen == dropdown.screen then
+ dropdown:display()
+ end
+ end)
+ capi.client.connect_signal('unmanage', function(c)
+ if c.instance == dropdown.name and c.screen == dropdown.screen then
+ dropdown.visible = false
+ end
+ end)
- return dropdown
+ return dropdown
end
-return setmetatable(quake, { __call = function(_, ...) return quake.new(...) end })
+return setmetatable(quake, {
+ __call = function(_, ...)
+ return quake.new(...)
+ end,
+})
diff --git a/awesome/lain/util/separators.lua b/awesome/lain/util/separators.lua
index 04402bb..9b5675b 100644
--- a/awesome/lain/util/separators.lua
+++ b/awesome/lain/util/separators.lua
@@ -6,9 +6,9 @@
--]]
-local wibox = require("wibox")
-local gears = require("gears")
-local beautiful = require("beautiful")
+local wibox = require('wibox')
+local gears = require('gears')
+local beautiful = require('beautiful')
-- Lain Cairo separators util submodule
-- lain.util.separators
@@ -18,99 +18,99 @@ local separators = { height = beautiful.separators_height or 0, width = beautifu
-- Right
function separators.arrow_right(col1, col2)
- local widget = wibox.widget.base.make_widget()
- widget.col1 = col1
- widget.col2 = col2
+ local widget = wibox.widget.base.make_widget()
+ widget.col1 = col1
+ widget.col2 = col2
- widget.fit = function(_, _, _)
- return separators.width, separators.height
- end
+ widget.fit = function(_, _, _)
+ return separators.width, separators.height
+ end
- widget.update = function(_, _)
- widget.col1 = col1
- widget.col2 = col2
- widget:emit_signal("widget::redraw_needed")
- end
+ widget.update = function(_, _)
+ widget.col1 = col1
+ widget.col2 = col2
+ widget:emit_signal('widget::redraw_needed')
+ end
- widget.draw = function(_, _, cr, width, height)
- if widget.col2 ~= "alpha" then
- cr:set_source_rgba(gears.color.parse_color(widget.col2))
- cr:new_path()
- cr:move_to(0, 0)
- cr:line_to(width, height/2)
- cr:line_to(width, 0)
- cr:close_path()
- cr:fill()
+ widget.draw = function(_, _, cr, width, height)
+ if widget.col2 ~= 'alpha' then
+ cr:set_source_rgba(gears.color.parse_color(widget.col2))
+ cr:new_path()
+ cr:move_to(0, 0)
+ cr:line_to(width, height / 2)
+ cr:line_to(width, 0)
+ cr:close_path()
+ cr:fill()
- cr:new_path()
- cr:move_to(0, height)
- cr:line_to(width, height/2)
- cr:line_to(width, height)
- cr:close_path()
- cr:fill()
- end
+ cr:new_path()
+ cr:move_to(0, height)
+ cr:line_to(width, height / 2)
+ cr:line_to(width, height)
+ cr:close_path()
+ cr:fill()
+ end
- if widget.col1 ~= "alpha" then
- cr:set_source_rgba(gears.color.parse_color(widget.col1))
- cr:new_path()
- cr:move_to(0, 0)
- cr:line_to(width, height/2)
- cr:line_to(0, height)
- cr:close_path()
- cr:fill()
- end
- end
+ if widget.col1 ~= 'alpha' then
+ cr:set_source_rgba(gears.color.parse_color(widget.col1))
+ cr:new_path()
+ cr:move_to(0, 0)
+ cr:line_to(width, height / 2)
+ cr:line_to(0, height)
+ cr:close_path()
+ cr:fill()
+ end
+ end
- return widget
+ return widget
end
-- Left
function separators.arrow_left(col1, col2)
- local widget = wibox.widget.base.make_widget()
- widget.col1 = col1
- widget.col2 = col2
+ local widget = wibox.widget.base.make_widget()
+ widget.col1 = col1
+ widget.col2 = col2
- widget.fit = function(_, _, _)
- return separators.width, separators.height
- end
+ widget.fit = function(_, _, _)
+ return separators.width, separators.height
+ end
- widget.update = function(c1, c2)
- widget.col1 = c1
- widget.col2 = c2
- widget:emit_signal("widget::redraw_needed")
- end
+ widget.update = function(c1, c2)
+ widget.col1 = c1
+ widget.col2 = c2
+ widget:emit_signal('widget::redraw_needed')
+ end
- widget.draw = function(_, _, cr, width, height)
- if widget.col1 ~= "alpha" then
- cr:set_source_rgba(gears.color.parse_color(widget.col1))
- cr:new_path()
- cr:move_to(width, 0)
- cr:line_to(0, height/2)
- cr:line_to(0, 0)
- cr:close_path()
- cr:fill()
+ widget.draw = function(_, _, cr, width, height)
+ if widget.col1 ~= 'alpha' then
+ cr:set_source_rgba(gears.color.parse_color(widget.col1))
+ cr:new_path()
+ cr:move_to(width, 0)
+ cr:line_to(0, height / 2)
+ cr:line_to(0, 0)
+ cr:close_path()
+ cr:fill()
- cr:new_path()
- cr:move_to(width, height)
- cr:line_to(0, height/2)
- cr:line_to(0, height)
- cr:close_path()
- cr:fill()
- end
+ cr:new_path()
+ cr:move_to(width, height)
+ cr:line_to(0, height / 2)
+ cr:line_to(0, height)
+ cr:close_path()
+ cr:fill()
+ end
- if widget.col2 ~= "alpha" then
- cr:new_path()
- cr:move_to(width, 0)
- cr:line_to(0, height/2)
- cr:line_to(width, height)
- cr:close_path()
+ if widget.col2 ~= 'alpha' then
+ cr:new_path()
+ cr:move_to(width, 0)
+ cr:line_to(0, height / 2)
+ cr:line_to(width, height)
+ cr:close_path()
- cr:set_source_rgba(gears.color.parse_color(widget.col2))
- cr:fill()
- end
- end
+ cr:set_source_rgba(gears.color.parse_color(widget.col2))
+ cr:fill()
+ end
+ end
- return widget
+ return widget
end
-- ]]
diff --git a/awesome/lain/widget/alsa.lua b/awesome/lain/widget/alsa.lua
index 202dc98..d8fca56 100644
--- a/awesome/lain/widget/alsa.lua
+++ b/awesome/lain/widget/alsa.lua
@@ -6,49 +6,52 @@
--]]
-local helpers = require("lain.helpers")
-local shell = require("awful.util").shell
-local wibox = require("wibox")
-local string = string
+local helpers = require('lain.helpers')
+local shell = require('awful.util').shell
+local wibox = require('wibox')
+local string = string
-- ALSA volume
-- lain.widget.alsa
local function factory(args)
- args = args or {}
- local alsa = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 5
- local settings = args.settings or function() end
+ args = args or {}
+ local alsa = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 5
+ local settings = args.settings or function() end
- alsa.cmd = args.cmd or "amixer"
- alsa.channel = args.channel or "Master"
- alsa.togglechannel = args.togglechannel
+ alsa.cmd = args.cmd or 'amixer'
+ alsa.channel = args.channel or 'Master'
+ alsa.togglechannel = args.togglechannel
- local format_cmd = string.format("%s get %s", alsa.cmd, alsa.channel)
+ local format_cmd = string.format('%s get %s', alsa.cmd, alsa.channel)
- if alsa.togglechannel then
- format_cmd = { shell, "-c", string.format("%s get %s; %s get %s",
- alsa.cmd, alsa.channel, alsa.cmd, alsa.togglechannel) }
- end
+ if alsa.togglechannel then
+ format_cmd = {
+ shell,
+ '-c',
+ string.format('%s get %s; %s get %s', alsa.cmd, alsa.channel, alsa.cmd, alsa.togglechannel),
+ }
+ end
- alsa.last = {}
+ alsa.last = {}
- function alsa.update()
- helpers.async(format_cmd, function(mixer)
- local l,s = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
- l = tonumber(l)
- if alsa.last.level ~= l or alsa.last.status ~= s then
- volume_now = { level = l, status = s }
- widget = alsa.widget
- settings()
- alsa.last = volume_now
- end
- end)
- end
+ function alsa.update()
+ helpers.async(format_cmd, function(mixer)
+ local l, s = string.match(mixer, '([%d]+)%%.*%[([%l]*)')
+ l = tonumber(l)
+ if alsa.last.level ~= l or alsa.last.status ~= s then
+ volume_now = { level = l, status = s }
+ widget = alsa.widget
+ settings()
+ alsa.last = volume_now
+ end
+ end)
+ end
- helpers.newtimer(string.format("alsa-%s-%s", alsa.cmd, alsa.channel), timeout, alsa.update)
+ helpers.newtimer(string.format('alsa-%s-%s', alsa.cmd, alsa.channel), timeout, alsa.update)
- return alsa
+ return alsa
end
return factory
diff --git a/awesome/lain/widget/alsabar.lua b/awesome/lain/widget/alsabar.lua
index 8e8cd3a..fbbd3ab 100644
--- a/awesome/lain/widget/alsabar.lua
+++ b/awesome/lain/widget/alsabar.lua
@@ -6,161 +6,167 @@
--]]
-local helpers = require("lain.helpers")
-local awful = require("awful")
-local naughty = require("naughty")
-local wibox = require("wibox")
-local math = math
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local awful = require('awful')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local math = math
+local string = string
+local type = type
local tonumber = tonumber
-- ALSA volume bar
-- lain.widget.alsabar
local function factory(args)
- local alsabar = {
- colors = {
- background = "#000000",
- mute = "#EB8F8F",
- unmute = "#A4CE8A"
- },
+ local alsabar = {
+ colors = {
+ background = '#000000',
+ mute = '#EB8F8F',
+ unmute = '#A4CE8A',
+ },
- _current_level = 0,
- _playback = "off"
- }
+ _current_level = 0,
+ _playback = 'off',
+ }
- args = args or {}
+ args = args or {}
- local timeout = args.timeout or 5
- local settings = args.settings or function() end
- local width = args.width or 63
- local height = args.height or 1
- local margins = args.margins or 1
- local ticks = args.ticks or false
- local ticks_size = args.ticks_size or 7
- local tick = args.tick or "|"
- local tick_pre = args.tick_pre or "["
- local tick_post = args.tick_post or "]"
- local tick_none = args.tick_none or " "
+ local timeout = args.timeout or 5
+ local settings = args.settings or function() end
+ local width = args.width or 63
+ local height = args.height or 1
+ local margins = args.margins or 1
+ local ticks = args.ticks or false
+ local ticks_size = args.ticks_size or 7
+ local tick = args.tick or '|'
+ local tick_pre = args.tick_pre or '['
+ local tick_post = args.tick_post or ']'
+ local tick_none = args.tick_none or ' '
- alsabar.cmd = args.cmd or "amixer"
- alsabar.channel = args.channel or "Master"
- alsabar.togglechannel = args.togglechannel
- alsabar.colors = args.colors or alsabar.colors
- alsabar.followtag = args.followtag or false
- alsabar.notification_preset = args.notification_preset
+ alsabar.cmd = args.cmd or 'amixer'
+ alsabar.channel = args.channel or 'Master'
+ alsabar.togglechannel = args.togglechannel
+ alsabar.colors = args.colors or alsabar.colors
+ alsabar.followtag = args.followtag or false
+ alsabar.notification_preset = args.notification_preset
- if not alsabar.notification_preset then
- alsabar.notification_preset = { font = "Monospace 10" }
- end
+ if not alsabar.notification_preset then
+ alsabar.notification_preset = { font = 'Monospace 10' }
+ end
- local format_cmd = string.format("%s get %s", alsabar.cmd, alsabar.channel)
+ local format_cmd = string.format('%s get %s', alsabar.cmd, alsabar.channel)
- if alsabar.togglechannel then
- format_cmd = { awful.util.shell, "-c", string.format("%s get %s; %s get %s",
- alsabar.cmd, alsabar.channel, alsabar.cmd, alsabar.togglechannel) }
- end
+ if alsabar.togglechannel then
+ format_cmd = {
+ awful.util.shell,
+ '-c',
+ string.format('%s get %s; %s get %s', alsabar.cmd, alsabar.channel, alsabar.cmd, alsabar.togglechannel),
+ }
+ end
- alsabar.bar = wibox.widget {
- color = alsabar.colors.unmute,
- background_color = alsabar.colors.background,
- forced_height = height,
- forced_width = width,
- margins = margins,
- paddings = margins,
- ticks = ticks,
- ticks_size = ticks_size,
- widget = wibox.widget.progressbar
- }
+ alsabar.bar = wibox.widget({
+ color = alsabar.colors.unmute,
+ background_color = alsabar.colors.background,
+ forced_height = height,
+ forced_width = width,
+ margins = margins,
+ paddings = margins,
+ ticks = ticks,
+ ticks_size = ticks_size,
+ widget = wibox.widget.progressbar,
+ })
- alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
+ alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } })
- function alsabar.update(callback)
- helpers.async(format_cmd, function(mixer)
- local vol, playback = string.match(mixer, "([%d]+)%%.*%[([%l]*)")
+ function alsabar.update(callback)
+ helpers.async(format_cmd, function(mixer)
+ local vol, playback = string.match(mixer, '([%d]+)%%.*%[([%l]*)')
- if not vol or not playback then return end
+ if not vol or not playback then
+ return
+ end
- if vol ~= alsabar._current_level or playback ~= alsabar._playback then
- alsabar._current_level = tonumber(vol)
- alsabar.bar:set_value(alsabar._current_level / 100)
- if alsabar._current_level == 0 or playback == "off" then
- alsabar._playback = playback
- alsabar.tooltip:set_text("[Muted]")
- alsabar.bar.color = alsabar.colors.mute
- else
- alsabar._playback = "on"
- alsabar.tooltip:set_text(string.format("%s: %s", alsabar.channel, vol))
- alsabar.bar.color = alsabar.colors.unmute
- end
+ if vol ~= alsabar._current_level or playback ~= alsabar._playback then
+ alsabar._current_level = tonumber(vol)
+ alsabar.bar:set_value(alsabar._current_level / 100)
+ if alsabar._current_level == 0 or playback == 'off' then
+ alsabar._playback = playback
+ alsabar.tooltip:set_text('[Muted]')
+ alsabar.bar.color = alsabar.colors.mute
+ else
+ alsabar._playback = 'on'
+ alsabar.tooltip:set_text(string.format('%s: %s', alsabar.channel, vol))
+ alsabar.bar.color = alsabar.colors.unmute
+ end
- volume_now = {
- level = alsabar._current_level,
- status = alsabar._playback
- }
+ volume_now = {
+ level = alsabar._current_level,
+ status = alsabar._playback,
+ }
- settings()
+ settings()
- if type(callback) == "function" then callback() end
- end
- end)
- end
+ if type(callback) == 'function' then
+ callback()
+ end
+ end
+ end)
+ end
- function alsabar.notify()
- alsabar.update(function()
- local preset = alsabar.notification_preset
+ function alsabar.notify()
+ alsabar.update(function()
+ local preset = alsabar.notification_preset
- preset.title = string.format("%s - %s%%", alsabar.channel, alsabar._current_level)
+ preset.title = string.format('%s - %s%%', alsabar.channel, alsabar._current_level)
- if alsabar._playback == "off" then
- preset.title = preset.title .. " Muted"
- end
+ if alsabar._playback == 'off' then
+ preset.title = preset.title .. ' Muted'
+ end
- -- tot is the maximum number of ticks to display in the notification
- local tot = alsabar.notification_preset.max_ticks
+ -- tot is the maximum number of ticks to display in the notification
+ local tot = alsabar.notification_preset.max_ticks
- if not tot then
- local wib = awful.screen.focused().mywibox
- -- if we can grab mywibox, tot is defined as its height if
- -- horizontal, or width otherwise
- if wib then
- if wib.position == "left" or wib.position == "right" then
- tot = wib.width
- else
- tot = wib.height
- end
- -- fallback: default horizontal wibox height
- else
- tot = 20
- end
- end
+ if not tot then
+ local wib = awful.screen.focused().mywibox
+ -- if we can grab mywibox, tot is defined as its height if
+ -- horizontal, or width otherwise
+ if wib then
+ if wib.position == 'left' or wib.position == 'right' then
+ tot = wib.width
+ else
+ tot = wib.height
+ end
+ -- fallback: default horizontal wibox height
+ else
+ tot = 20
+ end
+ end
- local int = math.modf((alsabar._current_level / 100) * tot)
- preset.text = string.format(
- "%s%s%s%s",
- tick_pre,
- string.rep(tick, int),
- string.rep(tick_none, tot - int),
- tick_post
- )
+ local int = math.modf((alsabar._current_level / 100) * tot)
+ preset.text =
+ string.format('%s%s%s%s', tick_pre, string.rep(tick, int), string.rep(tick_none, tot - int), tick_post)
- if alsabar.followtag then preset.screen = awful.screen.focused() end
+ if alsabar.followtag then
+ preset.screen = awful.screen.focused()
+ end
- if not alsabar.notification then
- alsabar.notification = naughty.notify {
- preset = preset,
- destroy = function() alsabar.notification = nil end
- }
- else
- naughty.replace_text(alsabar.notification, preset.title, preset.text)
- end
- end)
- end
+ if not alsabar.notification then
+ alsabar.notification = naughty.notify({
+ preset = preset,
+ destroy = function()
+ alsabar.notification = nil
+ end,
+ })
+ else
+ naughty.replace_text(alsabar.notification, preset.title, preset.text)
+ end
+ end)
+ end
- helpers.newtimer(string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel), timeout, alsabar.update)
+ helpers.newtimer(string.format('alsabar-%s-%s', alsabar.cmd, alsabar.channel), timeout, alsabar.update)
- return alsabar
+ return alsabar
end
return factory
diff --git a/awesome/lain/widget/bat.lua b/awesome/lain/widget/bat.lua
index 260f4b9..bed1570 100644
--- a/awesome/lain/widget/bat.lua
+++ b/awesome/lain/widget/bat.lua
@@ -6,231 +6,232 @@
--]]
-local helpers = require("lain.helpers")
-local fs = require("gears.filesystem")
-local naughty = require("naughty")
-local wibox = require("wibox")
-local math = math
-local string = string
-local ipairs = ipairs
+local helpers = require('lain.helpers')
+local fs = require('gears.filesystem')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local math = math
+local string = string
+local ipairs = ipairs
local tonumber = tonumber
-- Battery infos
-- lain.widget.bat
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
- naughty.notify { text = "lain.widget.bat: invalid power supply path", timeout = 0 }
- return
- end
+ if not fs.is_dir(pspath) then
+ naughty.notify({ text = 'lain.widget.bat: invalid power supply path', timeout = 0 })
+ return
+ end
- args = args or {}
+ args = args or {}
- local bat = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 30
- local notify = args.notify or "on"
- local full_notify = args.full_notify or notify
- local n_perc = args.n_perc or { 5, 15 }
- local batteries = args.batteries or (args.battery and {args.battery}) or {}
- local ac = args.ac or "AC0"
- local settings = args.settings or function() end
+ local bat = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 30
+ local notify = args.notify or 'on'
+ local full_notify = args.full_notify or notify
+ local n_perc = args.n_perc or { 5, 15 }
+ local batteries = args.batteries or (args.battery and { args.battery }) or {}
+ local ac = args.ac or 'AC0'
+ local settings = args.settings or function() end
- function bat.get_batteries()
- helpers.line_callback("ls -1 " .. pspath, function(line)
- local bstr = string.match(line, "BAT%w+")
- if bstr then
- batteries[#batteries + 1] = bstr
- else
- ac = string.match(line, "A%w+") or ac
- end
- end)
- end
+ function bat.get_batteries()
+ helpers.line_callback('ls -1 ' .. pspath, function(line)
+ local bstr = string.match(line, 'BAT%w+')
+ if bstr then
+ batteries[#batteries + 1] = bstr
+ else
+ ac = string.match(line, 'A%w+') or ac
+ end
+ end)
+ end
- if #batteries == 0 then bat.get_batteries() end
+ if #batteries == 0 then
+ bat.get_batteries()
+ end
- bat_notification_critical_preset = {
- title = "Battery exhausted",
- text = "Shutdown imminent",
- timeout = 15,
- fg = "#000000",
- bg = "#FFFFFF"
- }
+ bat_notification_critical_preset = {
+ title = 'Battery exhausted',
+ text = 'Shutdown imminent',
+ timeout = 15,
+ fg = '#000000',
+ bg = '#FFFFFF',
+ }
- bat_notification_low_preset = {
- title = "Battery low",
- text = "Plug the cable!",
- timeout = 15,
- fg = "#202020",
- bg = "#CDCDCD"
- }
+ bat_notification_low_preset = {
+ title = 'Battery low',
+ text = 'Plug the cable!',
+ timeout = 15,
+ fg = '#202020',
+ bg = '#CDCDCD',
+ }
- bat_notification_charged_preset = {
- title = "Battery full",
- text = "You can unplug the cable",
- timeout = 15,
- fg = "#202020",
- bg = "#CDCDCD"
- }
+ bat_notification_charged_preset = {
+ title = 'Battery full',
+ text = 'You can unplug the cable',
+ timeout = 15,
+ fg = '#202020',
+ bg = '#CDCDCD',
+ }
- bat_now = {
- status = "N/A",
- ac_status = "N/A",
- perc = "N/A",
- time = "N/A",
- watt = "N/A",
- capacity = "N/A"
- }
+ bat_now = {
+ status = 'N/A',
+ ac_status = 'N/A',
+ perc = 'N/A',
+ time = 'N/A',
+ watt = 'N/A',
+ capacity = 'N/A',
+ }
- bat_now.n_status = {}
- bat_now.n_perc = {}
- bat_now.n_capacity = {}
- for i = 1, #batteries do
- bat_now.n_status[i] = "N/A"
- bat_now.n_perc[i] = 0
- bat_now.n_capacity[i] = 0
- end
+ bat_now.n_status = {}
+ bat_now.n_perc = {}
+ bat_now.n_capacity = {}
+ for i = 1, #batteries do
+ bat_now.n_status[i] = 'N/A'
+ bat_now.n_perc[i] = 0
+ bat_now.n_capacity[i] = 0
+ end
- -- used to notify full charge only once before discharging
- local fullnotification = false
+ -- used to notify full charge only once before discharging
+ local fullnotification = false
- function bat.update()
- -- luacheck: globals bat_now
- local sum_rate_current = 0
- local sum_rate_voltage = 0
- local sum_rate_power = 0
- local sum_rate_energy = 0
- local sum_energy_now = 0
- local sum_energy_full = 0
- local sum_charge_full = 0
- local sum_charge_design = 0
+ function bat.update()
+ -- luacheck: globals bat_now
+ local sum_rate_current = 0
+ local sum_rate_voltage = 0
+ local sum_rate_power = 0
+ local sum_rate_energy = 0
+ local sum_energy_now = 0
+ local sum_energy_full = 0
+ local sum_charge_full = 0
+ local sum_charge_design = 0
- for i, battery in ipairs(batteries) do
- local bstr = pspath .. battery
- local present = helpers.first_line(bstr .. "/present")
+ for i, battery in ipairs(batteries) do
+ local bstr = pspath .. battery
+ local present = helpers.first_line(bstr .. '/present')
- if tonumber(present) == 1 then
- -- current_now(I)[uA], voltage_now(U)[uV], power_now(P)[uW]
- local rate_current = tonumber(helpers.first_line(bstr .. "/current_now"))
- local rate_voltage = tonumber(helpers.first_line(bstr .. "/voltage_now"))
- local rate_power = tonumber(helpers.first_line(bstr .. "/power_now"))
- local charge_full = tonumber(helpers.first_line(bstr .. "/charge_full"))
- local charge_design = tonumber(helpers.first_line(bstr .. "/charge_full_design"))
+ if tonumber(present) == 1 then
+ -- current_now(I)[uA], voltage_now(U)[uV], power_now(P)[uW]
+ local rate_current = tonumber(helpers.first_line(bstr .. '/current_now'))
+ local rate_voltage = tonumber(helpers.first_line(bstr .. '/voltage_now'))
+ local rate_power = tonumber(helpers.first_line(bstr .. '/power_now'))
+ local charge_full = tonumber(helpers.first_line(bstr .. '/charge_full'))
+ local charge_design = tonumber(helpers.first_line(bstr .. '/charge_full_design'))
- -- energy_now(P)[uWh], charge_now(I)[uAh]
- local energy_now = tonumber(helpers.first_line(bstr .. "/energy_now") or
- helpers.first_line(bstr .. "/charge_now"))
+ -- energy_now(P)[uWh], charge_now(I)[uAh]
+ local energy_now =
+ tonumber(helpers.first_line(bstr .. '/energy_now') or helpers.first_line(bstr .. '/charge_now'))
- -- energy_full(P)[uWh], charge_full(I)[uAh]
- local energy_full = tonumber(helpers.first_line(bstr .. "/energy_full") or
- charge_full)
+ -- energy_full(P)[uWh], charge_full(I)[uAh]
+ local energy_full = tonumber(helpers.first_line(bstr .. '/energy_full') or charge_full)
- local energy_percentage = tonumber(helpers.first_line(bstr .. "/capacity")) or
- math.floor((energy_now / energy_full) * 100)
+ local energy_percentage = tonumber(helpers.first_line(bstr .. '/capacity'))
+ or math.floor((energy_now / energy_full) * 100)
- bat_now.n_status[i] = helpers.first_line(bstr .. "/status") or "N/A"
- bat_now.n_perc[i] = energy_percentage or bat_now.n_perc[i]
+ bat_now.n_status[i] = helpers.first_line(bstr .. '/status') or 'N/A'
+ bat_now.n_perc[i] = energy_percentage or bat_now.n_perc[i]
- if not charge_design or charge_design == 0 then
- bat_now.n_capacity[i] = 0
- else
- bat_now.n_capacity[i] = math.floor((charge_full / charge_design) * 100)
- end
+ if not charge_design or charge_design == 0 then
+ bat_now.n_capacity[i] = 0
+ else
+ bat_now.n_capacity[i] = math.floor((charge_full / charge_design) * 100)
+ end
- sum_rate_current = sum_rate_current + (rate_current or 0)
- sum_rate_voltage = sum_rate_voltage + (rate_voltage or 0)
- sum_rate_power = sum_rate_power + (rate_power or 0)
- sum_rate_energy = sum_rate_energy + (rate_power or (((rate_voltage or 0) * (rate_current or 0)) / 1e6))
- sum_energy_now = sum_energy_now + (energy_now or 0)
- sum_energy_full = sum_energy_full + (energy_full or 0)
- sum_charge_full = sum_charge_full + (charge_full or 0)
- sum_charge_design = sum_charge_design + (charge_design or 0)
- end
- end
+ sum_rate_current = sum_rate_current + (rate_current or 0)
+ sum_rate_voltage = sum_rate_voltage + (rate_voltage or 0)
+ sum_rate_power = sum_rate_power + (rate_power or 0)
+ sum_rate_energy = sum_rate_energy + (rate_power or (((rate_voltage or 0) * (rate_current or 0)) / 1e6))
+ sum_energy_now = sum_energy_now + (energy_now or 0)
+ sum_energy_full = sum_energy_full + (energy_full or 0)
+ sum_charge_full = sum_charge_full + (charge_full or 0)
+ sum_charge_design = sum_charge_design + (charge_design or 0)
+ end
+ end
- bat_now.capacity = math.floor(math.min(100, (sum_charge_full / sum_charge_design) * 100))
+ bat_now.capacity = math.floor(math.min(100, (sum_charge_full / sum_charge_design) * 100))
- -- When one of the battery is charging, others' status are either
- -- "Full", "Unknown" or "Charging". When the laptop is not plugged in,
- -- one or more of the batteries may be full, but only one battery
- -- discharging suffices to set global status to "Discharging".
- bat_now.status = bat_now.n_status[1] or "N/A"
- for _,status in ipairs(bat_now.n_status) do
- if status == "Discharging" or status == "Charging" then
- bat_now.status = status
- end
- end
- bat_now.ac_status = tonumber(helpers.first_line(string.format("%s%s/online", pspath, ac))) or "N/A"
+ -- When one of the battery is charging, others' status are either
+ -- "Full", "Unknown" or "Charging". When the laptop is not plugged in,
+ -- one or more of the batteries may be full, but only one battery
+ -- discharging suffices to set global status to "Discharging".
+ bat_now.status = bat_now.n_status[1] or 'N/A'
+ for _, status in ipairs(bat_now.n_status) do
+ if status == 'Discharging' or status == 'Charging' then
+ bat_now.status = status
+ end
+ end
+ bat_now.ac_status = tonumber(helpers.first_line(string.format('%s%s/online', pspath, ac))) or 'N/A'
- if bat_now.status ~= "N/A" then
- if bat_now.status ~= "Full" and sum_rate_power == 0 and bat_now.ac_status == 1 then
- bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
- bat_now.time = "00:00"
- bat_now.watt = 0
+ if bat_now.status ~= 'N/A' then
+ if bat_now.status ~= 'Full' and sum_rate_power == 0 and bat_now.ac_status == 1 then
+ bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
+ bat_now.time = '00:00'
+ bat_now.watt = 0
- -- update {perc,time,watt} iff battery not full and rate > 0
- elseif bat_now.status ~= "Full" then
- local rate_time = 0
- -- Calculate time and watt if rates are greater then 0
- if (sum_rate_power > 0 or sum_rate_current > 0) then
- local div = (sum_rate_power > 0 and sum_rate_power) or sum_rate_current
+ -- update {perc,time,watt} iff battery not full and rate > 0
+ elseif bat_now.status ~= 'Full' then
+ local rate_time = 0
+ -- Calculate time and watt if rates are greater then 0
+ if sum_rate_power > 0 or sum_rate_current > 0 then
+ local div = (sum_rate_power > 0 and sum_rate_power) or sum_rate_current
- if bat_now.status == "Charging" then
- rate_time = (sum_energy_full - sum_energy_now) / div
- else -- Discharging
- rate_time = sum_energy_now / div
- end
+ if bat_now.status == 'Charging' then
+ rate_time = (sum_energy_full - sum_energy_now) / div
+ else -- Discharging
+ rate_time = sum_energy_now / div
+ end
- if 0 < rate_time and rate_time < 0.01 then -- check for magnitude discrepancies (#199)
- rate_time_magnitude = math.abs(math.floor(math.log10(rate_time)))
- rate_time = rate_time * 10^(rate_time_magnitude - 2)
- end
- end
+ if 0 < rate_time and rate_time < 0.01 then -- check for magnitude discrepancies (#199)
+ rate_time_magnitude = math.abs(math.floor(math.log10(rate_time)))
+ rate_time = rate_time * 10 ^ (rate_time_magnitude - 2)
+ end
+ end
- local hours = math.floor(rate_time)
- local minutes = math.floor((rate_time - hours) * 60)
- bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
- bat_now.time = string.format("%02d:%02d", hours, minutes)
- bat_now.watt = tonumber(string.format("%.2f", sum_rate_energy / 1e6))
- elseif bat_now.status == "Full" then
- bat_now.perc = 100
- bat_now.time = "00:00"
- bat_now.watt = 0
- end
- end
+ local hours = math.floor(rate_time)
+ local minutes = math.floor((rate_time - hours) * 60)
+ bat_now.perc = math.floor(math.min(100, (sum_energy_now / sum_energy_full) * 100))
+ bat_now.time = string.format('%02d:%02d', hours, minutes)
+ bat_now.watt = tonumber(string.format('%.2f', sum_rate_energy / 1e6))
+ elseif bat_now.status == 'Full' then
+ bat_now.perc = 100
+ bat_now.time = '00:00'
+ bat_now.watt = 0
+ end
+ end
- widget = bat.widget
- settings()
+ widget = bat.widget
+ settings()
- -- notifications for critical, low, and full levels
- if notify == "on" then
- if bat_now.status == "Discharging" then
- if tonumber(bat_now.perc) <= n_perc[1] then
- bat.id = naughty.notify({
- preset = bat_notification_critical_preset,
- replaces_id = bat.id
- }).id
- elseif tonumber(bat_now.perc) <= n_perc[2] then
- bat.id = naughty.notify({
- preset = bat_notification_low_preset,
- replaces_id = bat.id
- }).id
- end
- fullnotification = false
- elseif bat_now.status == "Full" and full_notify == "on" and not fullnotification then
- bat.id = naughty.notify({
- preset = bat_notification_charged_preset,
- replaces_id = bat.id
- }).id
- fullnotification = true
- end
- end
- end
+ -- notifications for critical, low, and full levels
+ if notify == 'on' then
+ if bat_now.status == 'Discharging' then
+ if tonumber(bat_now.perc) <= n_perc[1] then
+ bat.id = naughty.notify({
+ preset = bat_notification_critical_preset,
+ replaces_id = bat.id,
+ }).id
+ elseif tonumber(bat_now.perc) <= n_perc[2] then
+ bat.id = naughty.notify({
+ preset = bat_notification_low_preset,
+ replaces_id = bat.id,
+ }).id
+ end
+ fullnotification = false
+ elseif bat_now.status == 'Full' and full_notify == 'on' and not fullnotification then
+ bat.id = naughty.notify({
+ preset = bat_notification_charged_preset,
+ replaces_id = bat.id,
+ }).id
+ fullnotification = true
+ end
+ end
+ end
- helpers.newtimer("batteries", timeout, bat.update)
+ helpers.newtimer('batteries', timeout, bat.update)
- return bat
+ return bat
end
return factory
diff --git a/awesome/lain/widget/cal.lua b/awesome/lain/widget/cal.lua
index 97dced8..cb556e5 100644
--- a/awesome/lain/widget/cal.lua
+++ b/awesome/lain/widget/cal.lua
@@ -5,16 +5,16 @@
--]]
-local helpers = require("lain.helpers")
-local markup = require("lain.util.markup")
-local awful = require("awful")
-local naughty = require("naughty")
-local floor = math.floor
-local os = os
-local pairs = pairs
-local string = string
-local tconcat = table.concat
-local type = type
+local helpers = require('lain.helpers')
+local markup = require('lain.util.markup')
+local awful = require('awful')
+local naughty = require('naughty')
+local floor = math.floor
+local os = os
+local pairs = pairs
+local string = string
+local tconcat = table.concat
+local type = type
local tonumber = tonumber
local tostring = tostring
@@ -22,170 +22,205 @@ local tostring = tostring
-- lain.widget.cal
local function factory(args)
- args = args or {}
- local cal = {
- attach_to = args.attach_to or {},
- week_start = args.week_start or 2,
- three = args.three or false,
- followtag = args.followtag or false,
- week_number = args.week_number or "none",
- week_number_format = args.week_number_format or args.week_number == "left" and "%3d | " or "| %-3d",
- icons = args.icons or helpers.icons_dir .. "cal/white/",
- notification_preset = args.notification_preset or {
- font = "Monospace 10", fg = "#FFFFFF", bg = "#000000"
- }
- }
+ args = args or {}
+ local cal = {
+ attach_to = args.attach_to or {},
+ week_start = args.week_start or 2,
+ three = args.three or false,
+ followtag = args.followtag or false,
+ week_number = args.week_number or 'none',
+ week_number_format = args.week_number_format or args.week_number == 'left' and '%3d | ' or '| %-3d',
+ icons = args.icons or helpers.icons_dir .. 'cal/white/',
+ notification_preset = args.notification_preset or {
+ font = 'Monospace 10',
+ fg = '#FFFFFF',
+ bg = '#000000',
+ },
+ }
- function cal.get_week_number(m, st_day, x)
- local date = os.date("*t", m)
+ function cal.get_week_number(m, st_day, x)
+ local date = os.date('*t', m)
- local week_step = (x ~= 0 and floor((x + st_day) / 7) - 1 or 0);
+ local week_step = (x ~= 0 and floor((x + st_day) / 7) - 1 or 0)
- local display_time = os.time {
- year = date.year, month = date.month, day = date.day + 7 * week_step
- }
+ local display_time = os.time({
+ year = date.year,
+ month = date.month,
+ day = date.day + 7 * week_step,
+ })
- return string.format(cal.week_number_format, os.date("%V", display_time))
- end
+ return string.format(cal.week_number_format, os.date('%V', display_time))
+ end
- function cal.sum_week_days(x, y)
- return (x + y) % 7
- end
+ function cal.sum_week_days(x, y)
+ return (x + y) % 7
+ end
- function cal.build(month, year)
- local current_month, current_year = tonumber(os.date("%m")), tonumber(os.date("%Y"))
- local is_current_month = (not month or not year) or (month == current_month and year == current_year)
- local today = is_current_month and tonumber(os.date("%d")) -- otherwise nil and not highlighted
- local t = os.time { year = year or current_year, month = month and month+1 or current_month+1, day = 0 }
- local d = os.date("*t", t)
- local mth_days, st_day, this_month = d.day, (d.wday-d.day-cal.week_start+1)%7, os.date("%B %Y", t)
- local notifytable = { [1] = string.format("%s%s\n", string.rep(" ", floor((28 - this_month:len())/2)), markup.bold(this_month)) }
- for day_num = 0, 6 do
- notifytable[#notifytable+1] = string.format("%3s ", os.date("%a", os.time { year = 2006, month = 1, day = day_num + cal.week_start }))
- end
- notifytable[#notifytable] = string.format("%s\n%s", notifytable[#notifytable]:sub(1, -2), string.rep(" ", st_day*4))
- local strx
- for x = 1,mth_days do
- strx = x
- if x == today then
- if x < 10 then x = " " .. x end
- strx = markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. " ")
- end
- strx = string.format("%s%s", string.rep(" ", 3 - tostring(x):len()), strx)
- notifytable[#notifytable+1] = string.format("%-4s%s", strx, (x+st_day)%7==0 and x ~= mth_days and "\n" or "")
- end
- if string.len(cal.icons or "") > 0 and today then cal.icon = cal.icons .. today .. ".png" end
- cal.month, cal.year = d.month, d.year
+ function cal.build(month, year)
+ local current_month, current_year = tonumber(os.date('%m')), tonumber(os.date('%Y'))
+ local is_current_month = (not month or not year) or (month == current_month and year == current_year)
+ local today = is_current_month and tonumber(os.date('%d')) -- otherwise nil and not highlighted
+ local t = os.time({ year = year or current_year, month = month and month + 1 or current_month + 1, day = 0 })
+ local d = os.date('*t', t)
+ local mth_days, st_day, this_month = d.day, (d.wday - d.day - cal.week_start + 1) % 7, os.date('%B %Y', t)
+ local notifytable = {
+ [1] = string.format('%s%s\n', string.rep(' ', floor((28 - this_month:len()) / 2)), markup.bold(this_month)),
+ }
+ for day_num = 0, 6 do
+ notifytable[#notifytable + 1] = string.format(
+ '%3s ',
+ os.date('%a', os.time({ year = 2006, month = 1, day = day_num + cal.week_start }))
+ )
+ end
+ notifytable[#notifytable] =
+ string.format('%s\n%s', notifytable[#notifytable]:sub(1, -2), string.rep(' ', st_day * 4))
+ local strx
+ for x = 1, mth_days do
+ strx = x
+ if x == today then
+ if x < 10 then
+ x = ' ' .. x
+ end
+ strx = markup.bold(markup.color(cal.notification_preset.bg, cal.notification_preset.fg, x) .. ' ')
+ end
+ strx = string.format('%s%s', string.rep(' ', 3 - tostring(x):len()), strx)
+ notifytable[#notifytable + 1] =
+ string.format('%-4s%s', strx, (x + st_day) % 7 == 0 and x ~= mth_days and '\n' or '')
+ end
+ if string.len(cal.icons or '') > 0 and today then
+ cal.icon = cal.icons .. today .. '.png'
+ end
+ cal.month, cal.year = d.month, d.year
- if cal.week_number ~= "none" then
- local m = os.time { year = year or current_year, month = month and month or current_month, day = 1 }
- local head_prepend = string.rep(" ", tostring(string.format(cal.week_number_format, 0)):len())
+ if cal.week_number ~= 'none' then
+ local m = os.time({ year = year or current_year, month = month and month or current_month, day = 1 })
+ local head_prepend = string.rep(' ', tostring(string.format(cal.week_number_format, 0)):len())
- if cal.week_number == "left" then
- notifytable[1] = head_prepend .. notifytable[1] -- month-year row
- notifytable[2] = head_prepend .. notifytable[2] -- weekdays row
- notifytable[8] = notifytable[8]:gsub("\n", "\n" .. cal.get_week_number(m, st_day, 0)) -- first week of the month
+ if cal.week_number == 'left' then
+ notifytable[1] = head_prepend .. notifytable[1] -- month-year row
+ notifytable[2] = head_prepend .. notifytable[2] -- weekdays row
+ notifytable[8] = notifytable[8]:gsub('\n', '\n' .. cal.get_week_number(m, st_day, 0)) -- first week of the month
- for x = 10,#notifytable do
- if cal.sum_week_days(st_day, x) == 2 then
- notifytable[x] = cal.get_week_number(m, st_day, x) .. notifytable[x]
- end
- end
- elseif cal.week_number == "right" then
- notifytable[8] = notifytable[8]:gsub("\n", head_prepend .. "\n") -- weekdays row
- for x = 9,#notifytable do
- if cal.sum_week_days(st_day, x) == 1 then
- notifytable[x] = notifytable[x]:gsub("\n", cal.get_week_number(m, st_day, x - 7) .. "\n")
- end
- end
- -- last week of the month
- local end_days = cal.sum_week_days(st_day, mth_days)
- if end_days ~= 0 then end_days = 7 - end_days end
- notifytable[#notifytable] = notifytable[#notifytable] .. string.rep(" ", 4 * end_days) .. cal.get_week_number(m, st_day, mth_days + end_days)
- end
- end
+ for x = 10, #notifytable do
+ if cal.sum_week_days(st_day, x) == 2 then
+ notifytable[x] = cal.get_week_number(m, st_day, x) .. notifytable[x]
+ end
+ end
+ elseif cal.week_number == 'right' then
+ notifytable[8] = notifytable[8]:gsub('\n', head_prepend .. '\n') -- weekdays row
+ for x = 9, #notifytable do
+ if cal.sum_week_days(st_day, x) == 1 then
+ notifytable[x] = notifytable[x]:gsub('\n', cal.get_week_number(m, st_day, x - 7) .. '\n')
+ end
+ end
+ -- last week of the month
+ local end_days = cal.sum_week_days(st_day, mth_days)
+ if end_days ~= 0 then
+ end_days = 7 - end_days
+ end
+ notifytable[#notifytable] = notifytable[#notifytable]
+ .. string.rep(' ', 4 * end_days)
+ .. cal.get_week_number(m, st_day, mth_days + end_days)
+ end
+ end
- return notifytable
- end
+ return notifytable
+ end
- function cal.getdate(month, year, offset)
- if not month or not year then
- month = tonumber(os.date("%m"))
- year = tonumber(os.date("%Y"))
- end
+ function cal.getdate(month, year, offset)
+ if not month or not year then
+ month = tonumber(os.date('%m'))
+ year = tonumber(os.date('%Y'))
+ end
- month = month + offset
+ month = month + offset
- while month > 12 do
- month = month - 12
- year = year + 1
- end
+ while month > 12 do
+ month = month - 12
+ year = year + 1
+ end
- while month < 1 do
- month = month + 12
- year = year - 1
- end
+ while month < 1 do
+ month = month + 12
+ year = year - 1
+ end
- return month, year
- end
+ return month, year
+ end
- function cal.hide()
- if not cal.notification then return end
- naughty.destroy(cal.notification)
- cal.notification = nil
- end
+ function cal.hide()
+ if not cal.notification then
+ return
+ end
+ naughty.destroy(cal.notification)
+ cal.notification = nil
+ end
- function cal.show(seconds, month, year, scr)
- local text = tconcat(cal.build(month, year))
+ function cal.show(seconds, month, year, scr)
+ local text = tconcat(cal.build(month, year))
- if cal.three then
- local current_month, current_year = cal.month, cal.year
- local prev_month, prev_year = cal.getdate(cal.month, cal.year, -1)
- local next_month, next_year = cal.getdate(cal.month, cal.year, 1)
- text = string.format("%s\n\n%s\n\n%s",
- tconcat(cal.build(prev_month, prev_year)), text,
- tconcat(cal.build(next_month, next_year)))
- cal.month, cal.year = current_month, current_year
- end
+ if cal.three then
+ local current_month, current_year = cal.month, cal.year
+ local prev_month, prev_year = cal.getdate(cal.month, cal.year, -1)
+ local next_month, next_year = cal.getdate(cal.month, cal.year, 1)
+ text = string.format(
+ '%s\n\n%s\n\n%s',
+ tconcat(cal.build(prev_month, prev_year)),
+ text,
+ tconcat(cal.build(next_month, next_year))
+ )
+ cal.month, cal.year = current_month, current_year
+ end
- if cal.notification then
- local title = cal.notification_preset.title or nil
- naughty.replace_text(cal.notification, title, text)
- return
- end
+ if cal.notification then
+ local title = cal.notification_preset.title or nil
+ naughty.replace_text(cal.notification, title, text)
+ return
+ end
- cal.notification = naughty.notify {
- preset = cal.notification_preset,
- screen = cal.followtag and awful.screen.focused() or scr or 1,
- icon = cal.icon,
- timeout = type(seconds) == "number" and seconds or cal.notification_preset.timeout or 5,
- text = text
- }
- end
+ cal.notification = naughty.notify({
+ preset = cal.notification_preset,
+ screen = cal.followtag and awful.screen.focused() or scr or 1,
+ icon = cal.icon,
+ timeout = type(seconds) == 'number' and seconds or cal.notification_preset.timeout or 5,
+ text = text,
+ })
+ end
- function cal.hover_on() cal.show(0) end
- function cal.move(offset)
- offset = offset or 0
- cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
- cal.show(0, cal.month, cal.year)
- end
- function cal.prev() cal.move(-1) end
- function cal.next() cal.move( 1) end
+ function cal.hover_on()
+ cal.show(0)
+ end
+ function cal.move(offset)
+ offset = offset or 0
+ cal.month, cal.year = cal.getdate(cal.month, cal.year, offset)
+ cal.show(0, cal.month, cal.year)
+ end
+ function cal.prev()
+ cal.move(-1)
+ end
+ function cal.next()
+ cal.move(1)
+ end
- function cal.attach(widget)
- widget:connect_signal("mouse::enter", cal.hover_on)
- widget:connect_signal("mouse::leave", cal.hide)
- widget:buttons(awful.util.table.join(
- awful.button({}, 1, cal.prev),
- awful.button({}, 3, cal.next),
- awful.button({}, 2, cal.hover_on),
- awful.button({}, 5, cal.prev),
- awful.button({}, 4, cal.next)))
- end
+ function cal.attach(widget)
+ widget:connect_signal('mouse::enter', cal.hover_on)
+ widget:connect_signal('mouse::leave', cal.hide)
+ widget:buttons(
+ awful.util.table.join(
+ awful.button({}, 1, cal.prev),
+ awful.button({}, 3, cal.next),
+ awful.button({}, 2, cal.hover_on),
+ awful.button({}, 5, cal.prev),
+ awful.button({}, 4, cal.next)
+ )
+ )
+ end
- for _, widget in pairs(cal.attach_to) do cal.attach(widget) end
+ for _, widget in pairs(cal.attach_to) do
+ cal.attach(widget)
+ end
- return cal
+ return cal
end
return factory
diff --git a/awesome/lain/widget/contrib/init.lua b/awesome/lain/widget/contrib/init.lua
index 9e863a5..f245ac1 100644
--- a/awesome/lain/widget/contrib/init.lua
+++ b/awesome/lain/widget/contrib/init.lua
@@ -10,9 +10,9 @@
--]]
-local wrequire = require("lain.helpers").wrequire
+local wrequire = require('lain.helpers').wrequire
local setmetatable = setmetatable
-local widget = { _NAME = "lain.widget.contrib" }
+local widget = { _NAME = 'lain.widget.contrib' }
return setmetatable(widget, { __index = wrequire })
diff --git a/awesome/lain/widget/contrib/moc.lua b/awesome/lain/widget/contrib/moc.lua
index ad6452e..682b0fe 100644
--- a/awesome/lain/widget/contrib/moc.lua
+++ b/awesome/lain/widget/contrib/moc.lua
@@ -5,93 +5,103 @@
--]]
-local helpers = require("lain.helpers")
-local shell = require("awful.util").shell
-local focused = require("awful.screen").focused
-local escape_f = require("awful.util").escape
-local naughty = require("naughty")
-local wibox = require("wibox")
-local os = os
-local string = string
+local helpers = require('lain.helpers')
+local shell = require('awful.util').shell
+local focused = require('awful.screen').focused
+local escape_f = require('awful.util').escape
+local naughty = require('naughty')
+local wibox = require('wibox')
+local os = os
+local string = string
-- MOC audio player
-- lain.widget.contrib.moc
local function factory(args)
- args = args or {}
+ args = args or {}
- local moc = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 2
- local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
- local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
- local cover_size = args.cover_size or 100
- local default_art = args.default_art or ""
- local followtag = args.followtag or false
- local settings = args.settings or function() end
+ local moc = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 2
+ local music_dir = args.music_dir or os.getenv('HOME') .. '/Music'
+ local cover_pattern = args.cover_pattern or '*\\.(jpg|jpeg|png|gif)$'
+ local cover_size = args.cover_size or 100
+ local default_art = args.default_art or ''
+ local followtag = args.followtag or false
+ local settings = args.settings or function() end
- moc_notification_preset = { title = "Now playing", timeout = 6 }
+ moc_notification_preset = { title = 'Now playing', timeout = 6 }
- helpers.set_map("current moc track", nil)
+ helpers.set_map('current moc track', nil)
- function moc.update()
- helpers.async("mocp -i", function(f)
- moc_now = {
- state = "N/A",
- file = "N/A",
- artist = "N/A",
- title = "N/A",
- album = "N/A",
- elapsed = "N/A",
- total = "N/A"
- }
+ function moc.update()
+ helpers.async('mocp -i', function(f)
+ moc_now = {
+ state = 'N/A',
+ file = 'N/A',
+ artist = 'N/A',
+ title = 'N/A',
+ album = 'N/A',
+ elapsed = 'N/A',
+ total = 'N/A',
+ }
- for line in string.gmatch(f, "[^\n]+") do
- for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
- if k == "State" then moc_now.state = v
- elseif k == "File" then moc_now.file = v
- elseif k == "Artist" then moc_now.artist = escape_f(v)
- elseif k == "SongTitle" then moc_now.title = escape_f(v)
- elseif k == "Album" then moc_now.album = escape_f(v)
- elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v)
- elseif k == "TotalTime" then moc_now.total = escape_f(v)
- end
- end
- end
+ for line in string.gmatch(f, '[^\n]+') do
+ for k, v in string.gmatch(line, '([%w]+):[%s](.*)$') do
+ if k == 'State' then
+ moc_now.state = v
+ elseif k == 'File' then
+ moc_now.file = v
+ elseif k == 'Artist' then
+ moc_now.artist = escape_f(v)
+ elseif k == 'SongTitle' then
+ moc_now.title = escape_f(v)
+ elseif k == 'Album' then
+ moc_now.album = escape_f(v)
+ elseif k == 'CurrentTime' then
+ moc_now.elapsed = escape_f(v)
+ elseif k == 'TotalTime' then
+ moc_now.total = escape_f(v)
+ end
+ end
+ end
- moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist,
- moc_now.album, moc_now.total, moc_now.title)
- widget = moc.widget
- settings()
+ moc_notification_preset.text =
+ string.format('%s (%s) - %s\n%s', moc_now.artist, moc_now.album, moc_now.total, moc_now.title)
+ widget = moc.widget
+ settings()
- if moc_now.state == "PLAY" then
- if moc_now.title ~= helpers.get_map("current moc track") then
- helpers.set_map("current moc track", moc_now.title)
+ if moc_now.state == 'PLAY' then
+ if moc_now.title ~= helpers.get_map('current moc track') then
+ helpers.set_map('current moc track', moc_now.title)
- if followtag then moc_notification_preset.screen = focused() end
+ if followtag then
+ moc_notification_preset.screen = focused()
+ end
- local common = {
- preset = moc_notification_preset,
- icon = default_art,
- icon_size = cover_size,
- replaces_id = moc.id,
- }
+ local common = {
+ preset = moc_notification_preset,
+ icon = default_art,
+ icon_size = cover_size,
+ replaces_id = moc.id,
+ }
- local path = string.format("%s/%s", music_dir, string.match(moc_now.file, ".*/"))
- local cover = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'", path, cover_pattern)
- helpers.async({ shell, "-c", cover }, function(current_icon)
- common.icon = current_icon:gsub("\n", "")
- moc.id = naughty.notify(common).id
- end)
- end
- elseif moc_now.state ~= "PAUSE" then
- helpers.set_map("current moc track", nil)
- end
- end)
- end
+ local path = string.format('%s/%s', music_dir, string.match(moc_now.file, '.*/'))
+ local cover =
+ string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'", path, cover_pattern)
+ helpers.async({ shell, '-c', cover }, function(current_icon)
+ common.icon = current_icon:gsub('\n', '')
+ moc.id = naughty.notify(common).id
+ end)
+ end
+ elseif moc_now.state ~= 'PAUSE' then
+ helpers.set_map('current moc track', nil)
+ end
+ end)
+ end
- moc.timer = helpers.newtimer("moc", timeout, moc.update, true, true)
+ moc.timer = helpers.newtimer('moc', timeout, moc.update, true, true)
- return moc
+ return moc
end
return factory
diff --git a/awesome/lain/widget/contrib/redshift.lua b/awesome/lain/widget/contrib/redshift.lua
index d91d941..0d9f278 100644
--- a/awesome/lain/widget/contrib/redshift.lua
+++ b/awesome/lain/widget/contrib/redshift.lua
@@ -6,36 +6,36 @@
--]]
-local async = require("lain.helpers").async
-local awful = require("awful")
+local async = require('lain.helpers').async
+local awful = require('awful')
local execute = os.execute
-local type = type
+local type = type
-- Redshift
-- lain.widget.contrib.redshift
local redshift = { active = false, pid = nil }
function redshift.start()
- execute("pkill redshift")
- awful.spawn.with_shell("redshift -x") -- clear adjustments
- redshift.pid = awful.spawn.with_shell("redshift")
- redshift.active = true
- if type(redshift.update_fun) == "function" then
- redshift.update_fun(redshift.active)
- end
+ execute('pkill redshift')
+ awful.spawn.with_shell('redshift -x') -- clear adjustments
+ redshift.pid = awful.spawn.with_shell('redshift')
+ redshift.active = true
+ if type(redshift.update_fun) == 'function' then
+ redshift.update_fun(redshift.active)
+ end
end
function redshift.toggle()
- async({ awful.util.shell, "-c", string.format("ps -p %d -o pid=", redshift.pid) }, function(f)
- if f and #f > 0 then -- redshift is running
- -- Sending -USR1 toggles redshift (See project website)
- execute("pkill -USR1 redshift")
- redshift.active = not redshift.active
- else -- not started or killed, (re)start it
- redshift.start()
- end
- redshift.update_fun(redshift.active)
- end)
+ async({ awful.util.shell, '-c', string.format('ps -p %d -o pid=', redshift.pid) }, function(f)
+ if f and #f > 0 then -- redshift is running
+ -- Sending -USR1 toggles redshift (See project website)
+ execute('pkill -USR1 redshift')
+ redshift.active = not redshift.active
+ else -- not started or killed, (re)start it
+ redshift.start()
+ end
+ redshift.update_fun(redshift.active)
+ end)
end
-- Attach to a widget
@@ -44,11 +44,15 @@ end
-- @param fun: Function to be run each time redshift is toggled (optional).
-- Use it to update widget text or icons on status change.
function redshift.attach(widget, fun)
- redshift.update_fun = fun or function() end
- if not redshift.pid then redshift.start() end
- if widget then
- widget:buttons(awful.util.table.join(awful.button({}, 1, function () redshift.toggle() end)))
- end
+ redshift.update_fun = fun or function() end
+ if not redshift.pid then
+ redshift.start()
+ end
+ if widget then
+ widget:buttons(awful.util.table.join(awful.button({}, 1, function()
+ redshift.toggle()
+ end)))
+ end
end
return redshift
diff --git a/awesome/lain/widget/contrib/task.lua b/awesome/lain/widget/contrib/task.lua
index 2311996..bb30726 100644
--- a/awesome/lain/widget/contrib/task.lua
+++ b/awesome/lain/widget/contrib/task.lua
@@ -5,88 +5,92 @@
--]]
-local helpers = require("lain.helpers")
-local markup = require("lain.util").markup
-local awful = require("awful")
-local naughty = require("naughty")
-local mouse = mouse
+local helpers = require('lain.helpers')
+local markup = require('lain.util').markup
+local awful = require('awful')
+local naughty = require('naughty')
+local mouse = mouse
-- Taskwarrior notification
-- lain.widget.contrib.task
local task = {}
function task.hide()
- if not task.notification then return end
- naughty.destroy(task.notification)
- task.notification = nil
+ if not task.notification then
+ return
+ end
+ naughty.destroy(task.notification)
+ task.notification = nil
end
function task.show(scr)
- task.notification_preset.screen = task.followtag and awful.screen.focused() or scr or 1
+ task.notification_preset.screen = task.followtag and awful.screen.focused() or scr or 1
- helpers.async({ awful.util.shell, "-c", task.show_cmd }, function(f)
- local widget_focused = true
+ helpers.async({ awful.util.shell, '-c', task.show_cmd }, function(f)
+ local widget_focused = true
- if mouse.current_widgets then
- widget_focused = false
- for _,v in ipairs(mouse.current_widgets) do
- if task.widget == v then
- widget_focused = true
- break
- end
- end
- end
+ if mouse.current_widgets then
+ widget_focused = false
+ for _, v in ipairs(mouse.current_widgets) do
+ if task.widget == v then
+ widget_focused = true
+ break
+ end
+ end
+ end
- if widget_focused then
- task.hide()
- task.notification = naughty.notify {
- preset = task.notification_preset,
- title = "task next",
- text = markup.font(task.notification_preset.font,
- awful.util.escape(f:gsub("\n*$", "")))
- }
- end
- end)
+ if widget_focused then
+ task.hide()
+ task.notification = naughty.notify({
+ preset = task.notification_preset,
+ title = 'task next',
+ text = markup.font(task.notification_preset.font, awful.util.escape(f:gsub('\n*$', ''))),
+ })
+ end
+ end)
end
function task.prompt()
- awful.prompt.run {
- prompt = task.prompt_text,
- textbox = awful.screen.focused().mypromptbox.widget,
- exe_callback = function(t)
- helpers.async(t, function(f)
- naughty.notify {
- preset = task.notification_preset,
- title = t,
- text = markup.font(task.notification_preset.font,
- awful.util.escape(f:gsub("\n*$", "")))
- }
- end)
- end,
- history_path = awful.util.getdir("cache") .. "/history_task"
- }
+ awful.prompt.run({
+ prompt = task.prompt_text,
+ textbox = awful.screen.focused().mypromptbox.widget,
+ exe_callback = function(t)
+ helpers.async(t, function(f)
+ naughty.notify({
+ preset = task.notification_preset,
+ title = t,
+ text = markup.font(task.notification_preset.font, awful.util.escape(f:gsub('\n*$', ''))),
+ })
+ end)
+ end,
+ history_path = awful.util.getdir('cache') .. '/history_task',
+ })
end
function task.attach(widget, args)
- args = args or {}
+ args = args or {}
- task.show_cmd = args.show_cmd or "task next"
- task.prompt_text = args.prompt_text or "Enter task command: "
- task.followtag = args.followtag or false
- task.notification_preset = args.notification_preset
- task.widget = widget
+ task.show_cmd = args.show_cmd or 'task next'
+ task.prompt_text = args.prompt_text or 'Enter task command: '
+ task.followtag = args.followtag or false
+ task.notification_preset = args.notification_preset
+ task.widget = widget
- if not task.notification_preset then
- task.notification_preset = {
- font = "Monospace 10",
- icon = helpers.icons_dir .. "/taskwarrior.png"
- }
- end
+ if not task.notification_preset then
+ task.notification_preset = {
+ font = 'Monospace 10',
+ icon = helpers.icons_dir .. '/taskwarrior.png',
+ }
+ end
- if widget then
- widget:connect_signal("mouse::enter", function () task.show() end)
- widget:connect_signal("mouse::leave", function () task.hide() end)
- end
+ if widget then
+ widget:connect_signal('mouse::enter', function()
+ task.show()
+ end)
+ widget:connect_signal('mouse::leave', function()
+ task.hide()
+ end)
+ end
end
return task
diff --git a/awesome/lain/widget/contrib/tp_smapi.lua b/awesome/lain/widget/contrib/tp_smapi.lua
index 87c5e51..5dbf4ad 100644
--- a/awesome/lain/widget/contrib/tp_smapi.lua
+++ b/awesome/lain/widget/contrib/tp_smapi.lua
@@ -6,142 +6,159 @@
--]]
-local helpers = require("lain.helpers")
-local focused = require("awful.screen").focused
-local naughty = require("naughty")
-local wibox = require("wibox")
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local focused = require('awful.screen').focused
+local naughty = require('naughty')
+local wibox = require('wibox')
+local string = string
+local type = type
-- ThinkPad battery infos and widget creator
-- http://www.thinkwiki.org/wiki/Tp_smapi
-- lain.widget.contrib.tp_smapi
local function factory(apipath)
- local tp_smapi = {
- path = apipath or "/sys/devices/platform/smapi"
- }
+ local tp_smapi = {
+ path = apipath or '/sys/devices/platform/smapi',
+ }
- function tp_smapi.get(batid, feature)
- return helpers.first_line(string.format("%s/%s/%s", tp_smapi.path, batid or "BAT0", feature or ""))
- end
+ function tp_smapi.get(batid, feature)
+ return helpers.first_line(string.format('%s/%s/%s', tp_smapi.path, batid or 'BAT0', feature or ''))
+ end
- function tp_smapi.installed(batid)
- return tp_smapi.get(batid, "installed") == "1"
- end
+ function tp_smapi.installed(batid)
+ return tp_smapi.get(batid, 'installed') == '1'
+ end
- function tp_smapi.status(batid)
- return tp_smapi.get(batid, "state")
- end
+ function tp_smapi.status(batid)
+ return tp_smapi.get(batid, 'state')
+ end
- function tp_smapi.percentage(batid)
- return tp_smapi.get(batid, "remaining_percent")
- end
+ function tp_smapi.percentage(batid)
+ return tp_smapi.get(batid, 'remaining_percent')
+ end
- -- either running or charging time
- function tp_smapi.time(batid)
- local status = tp_smapi.status(batid)
- local mins_left = tp_smapi.get(batid, string.match(string.lower(status), "discharging") and "remaining_running_time" or "remaining_charging_time")
- if not string.find(mins_left, "^%d+") then return "N/A" end
- return string.format("%02d:%02d", math.floor(mins_left / 60), mins_left % 60) -- HH:mm
- end
+ -- either running or charging time
+ function tp_smapi.time(batid)
+ local status = tp_smapi.status(batid)
+ local mins_left = tp_smapi.get(
+ batid,
+ string.match(string.lower(status), 'discharging') and 'remaining_running_time' or 'remaining_charging_time'
+ )
+ if not string.find(mins_left, '^%d+') then
+ return 'N/A'
+ end
+ return string.format('%02d:%02d', math.floor(mins_left / 60), mins_left % 60) -- HH:mm
+ end
- function tp_smapi.hide()
- if not tp_smapi.notification then return end
- naughty.destroy(tp_smapi.notification)
- tp_smapi.notification = nil
- end
+ function tp_smapi.hide()
+ if not tp_smapi.notification then
+ return
+ end
+ naughty.destroy(tp_smapi.notification)
+ tp_smapi.notification = nil
+ end
- function tp_smapi.show(batid, seconds, scr)
- if not tp_smapi.installed(batid) then return end
+ function tp_smapi.show(batid, seconds, scr)
+ if not tp_smapi.installed(batid) then
+ return
+ end
- local mfgr = tp_smapi.get(batid, "manufacturer") or "no_mfgr"
- local model = tp_smapi.get(batid, "model") or "no_model"
- local chem = tp_smapi.get(batid, "chemistry") or "no_chem"
- local status = tp_smapi.get(batid, "state")
- local time = tp_smapi.time(batid)
- local msg
+ local mfgr = tp_smapi.get(batid, 'manufacturer') or 'no_mfgr'
+ local model = tp_smapi.get(batid, 'model') or 'no_model'
+ local chem = tp_smapi.get(batid, 'chemistry') or 'no_chem'
+ local status = tp_smapi.get(batid, 'state')
+ local time = tp_smapi.time(batid)
+ local msg
- if status and status ~= "idle" then
- msg = string.format("[%s] %s %s", status, time ~= "N/A" and time or "unknown remaining time",
- string.lower(status):gsub(" ", ""):gsub("\n", "") == "charging" and " until charged" or " remaining")
- else
- msg = "On AC power"
- end
+ if status and status ~= 'idle' then
+ msg = string.format(
+ '[%s] %s %s',
+ status,
+ time ~= 'N/A' and time or 'unknown remaining time',
+ string.lower(status):gsub(' ', ''):gsub('\n', '') == 'charging' and ' until charged' or ' remaining'
+ )
+ else
+ msg = 'On AC power'
+ end
- tp_smapi.hide()
- tp_smapi.notification = naughty.notify {
- title = string.format("%s: %s %s (%s)", batid, mfgr, model, chem),
- text = msg,
- timeout = type(seconds) == "number" and seconds or 0,
- screen = scr or focused()
- }
- end
+ tp_smapi.hide()
+ tp_smapi.notification = naughty.notify({
+ title = string.format('%s: %s %s (%s)', batid, mfgr, model, chem),
+ text = msg,
+ timeout = type(seconds) == 'number' and seconds or 0,
+ screen = scr or focused(),
+ })
+ end
- function tp_smapi.create_widget(args)
- args = args or {}
+ function tp_smapi.create_widget(args)
+ args = args or {}
- local pspath = args.pspath or "/sys/class/power_supply/"
- local batteries = args.batteries or (args.battery and {args.battery}) or {}
- local timeout = args.timeout or 30
- local settings = args.settings or function() end
+ local pspath = args.pspath or '/sys/class/power_supply/'
+ local batteries = args.batteries or (args.battery and { args.battery }) or {}
+ local timeout = args.timeout or 30
+ local settings = args.settings or function() end
- if #batteries == 0 then
- helpers.line_callback("ls -1 " .. pspath, function(line)
- local bstr = string.match(line, "BAT%w+")
- if bstr then batteries[#batteries + 1] = bstr end
- end)
- end
+ if #batteries == 0 then
+ helpers.line_callback('ls -1 ' .. pspath, function(line)
+ local bstr = string.match(line, 'BAT%w+')
+ if bstr then
+ batteries[#batteries + 1] = bstr
+ end
+ end)
+ end
- local all_batteries_installed = true
+ local all_batteries_installed = true
- for _, battery in ipairs(batteries) do
- if not tp_smapi.installed(battery) then
- naughty.notify {
- preset = naughty.config.critical,
- title = "tp_smapi: error while creating widget",
- text = string.format("battery %s is not installed", battery)
- }
- all_batteries_installed = false
- break
- end
- end
+ for _, battery in ipairs(batteries) do
+ if not tp_smapi.installed(battery) then
+ naughty.notify({
+ preset = naughty.config.critical,
+ title = 'tp_smapi: error while creating widget',
+ text = string.format('battery %s is not installed', battery),
+ })
+ all_batteries_installed = false
+ break
+ end
+ end
- if not all_batteries_installed then return end
+ if not all_batteries_installed then
+ return
+ end
- tpbat = {
- batteries = batteries,
- widget = args.widget or wibox.widget.textbox()
- }
+ tpbat = {
+ batteries = batteries,
+ widget = args.widget or wibox.widget.textbox(),
+ }
- function tpbat.update()
- tpbat_now = {
- n_status = {},
- n_perc = {},
- n_time = {},
- status = "N/A"
- }
+ function tpbat.update()
+ tpbat_now = {
+ n_status = {},
+ n_perc = {},
+ n_time = {},
+ status = 'N/A',
+ }
- for i = 1, #batteries do
- tpbat_now.n_status[i] = tp_smapi.status(batteries[i]) or "N/A"
- tpbat_now.n_perc[i] = tp_smapi.percentage(batteries[i])
- tpbat_now.n_time[i] = tp_smapi.time(batteries[i]) or "N/A"
+ for i = 1, #batteries do
+ tpbat_now.n_status[i] = tp_smapi.status(batteries[i]) or 'N/A'
+ tpbat_now.n_perc[i] = tp_smapi.percentage(batteries[i])
+ tpbat_now.n_time[i] = tp_smapi.time(batteries[i]) or 'N/A'
- if not tpbat_now.n_status[i]:lower():match("full") then
- tpbat_now.status = tpbat_now.n_status[i]
- end
- end
+ if not tpbat_now.n_status[i]:lower():match('full') then
+ tpbat_now.status = tpbat_now.n_status[i]
+ end
+ end
- widget = tpbat.widget -- backwards compatibility
- settings()
- end
+ widget = tpbat.widget -- backwards compatibility
+ settings()
+ end
- helpers.newtimer("thinkpad-batteries", timeout, tpbat.update)
+ helpers.newtimer('thinkpad-batteries', timeout, tpbat.update)
- return tpbat
- end
+ return tpbat
+ end
- return tp_smapi
+ return tp_smapi
end
return factory
diff --git a/awesome/lain/widget/cpu.lua b/awesome/lain/widget/cpu.lua
index 6c51115..7f590cd 100644
--- a/awesome/lain/widget/cpu.lua
+++ b/awesome/lain/widget/cpu.lua
@@ -6,70 +6,69 @@
--]]
-local helpers = require("lain.helpers")
-local wibox = require("wibox")
-local math = math
-local string = string
+local helpers = require('lain.helpers')
+local wibox = require('wibox')
+local math = math
+local string = string
-- CPU usage
-- lain.widget.cpu
local function factory(args)
- args = args or {}
+ args = args or {}
- local cpu = { core = {}, widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 2
- local settings = args.settings or function() end
+ local cpu = { core = {}, widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 2
+ local settings = args.settings or function() end
- function cpu.update()
- -- Read the amount of time the CPUs have spent performing
- -- different kinds of work. Read the first line of /proc/stat
- -- which is the sum of all CPUs.
- for index,time in pairs(helpers.lines_match("cpu","/proc/stat")) do
- local coreid = index - 1
- local core = cpu.core[coreid] or
- { last_active = 0 , last_total = 0, usage = 0 }
- local at = 1
- local idle = 0
- local total = 0
+ function cpu.update()
+ -- Read the amount of time the CPUs have spent performing
+ -- different kinds of work. Read the first line of /proc/stat
+ -- which is the sum of all CPUs.
+ for index, time in pairs(helpers.lines_match('cpu', '/proc/stat')) do
+ local coreid = index - 1
+ local core = cpu.core[coreid] or { last_active = 0, last_total = 0, usage = 0 }
+ local at = 1
+ local idle = 0
+ local total = 0
- for field in string.gmatch(time, "[%s]+([^%s]+)") do
- -- 4 = idle, 5 = ioWait. Essentially, the CPUs have done
- -- nothing during these times.
- if at == 4 or at == 5 then
- idle = idle + field
- end
- total = total + field
- at = at + 1
- end
+ for field in string.gmatch(time, '[%s]+([^%s]+)') do
+ -- 4 = idle, 5 = ioWait. Essentially, the CPUs have done
+ -- nothing during these times.
+ if at == 4 or at == 5 then
+ idle = idle + field
+ end
+ total = total + field
+ at = at + 1
+ end
- local active = total - idle
+ local active = total - idle
- if core.last_active ~= active or core.last_total ~= total then
- -- Read current data and calculate relative values.
- local dactive = active - core.last_active
- local dtotal = total - core.last_total
- local usage = math.ceil(math.abs((dactive / dtotal) * 100))
+ if core.last_active ~= active or core.last_total ~= total then
+ -- Read current data and calculate relative values.
+ local dactive = active - core.last_active
+ local dtotal = total - core.last_total
+ local usage = math.ceil(math.abs((dactive / dtotal) * 100))
- core.last_active = active
- core.last_total = total
- core.usage = usage
+ core.last_active = active
+ core.last_total = total
+ core.usage = usage
- -- Save current data for the next run.
- cpu.core[coreid] = core
- end
- end
+ -- Save current data for the next run.
+ cpu.core[coreid] = core
+ end
+ end
- cpu_now = cpu.core
- cpu_now.usage = cpu_now[0].usage
- widget = cpu.widget
+ cpu_now = cpu.core
+ cpu_now.usage = cpu_now[0].usage
+ widget = cpu.widget
- settings()
- end
+ settings()
+ end
- helpers.newtimer("cpu", timeout, cpu.update)
+ helpers.newtimer('cpu', timeout, cpu.update)
- return cpu
+ return cpu
end
return factory
diff --git a/awesome/lain/widget/fs.lua b/awesome/lain/widget/fs.lua
index b3a2dad..10e830f 100644
--- a/awesome/lain/widget/fs.lua
+++ b/awesome/lain/widget/fs.lua
@@ -7,150 +7,168 @@
--]]
-local helpers = require("lain.helpers")
-local Gio = require("lgi").Gio
-local focused = require("awful.screen").focused
-local wibox = require("wibox")
-local naughty = require("naughty")
-local gears = require("gears")
-local math = math
-local string = string
-local tconcat = table.concat
-local type = type
+local helpers = require('lain.helpers')
+local Gio = require('lgi').Gio
+local focused = require('awful.screen').focused
+local wibox = require('wibox')
+local naughty = require('naughty')
+local gears = require('gears')
+local math = math
+local string = string
+local tconcat = table.concat
+local type = type
local query_size = Gio.FILE_ATTRIBUTE_FILESYSTEM_SIZE
local query_free = Gio.FILE_ATTRIBUTE_FILESYSTEM_FREE
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
-- lain.widget.fs
local function factory(args)
- args = args or {}
+ args = args or {}
- local fs = {
- widget = args.widget or wibox.widget.textbox(),
- units = {
- [1] = "Kb", [2] = "Mb", [3] = "Gb",
- [4] = "Tb", [5] = "Pb", [6] = "Eb",
- [7] = "Zb", [8] = "Yb"
- }
- }
+ local fs = {
+ widget = args.widget or wibox.widget.textbox(),
+ units = {
+ [1] = 'Kb',
+ [2] = 'Mb',
+ [3] = 'Gb',
+ [4] = 'Tb',
+ [5] = 'Pb',
+ [6] = 'Eb',
+ [7] = 'Zb',
+ [8] = 'Yb',
+ },
+ }
- function fs.hide()
- if not fs.notification then return end
- naughty.destroy(fs.notification)
- fs.notification = nil
- end
+ function fs.hide()
+ if not fs.notification then
+ return
+ end
+ naughty.destroy(fs.notification)
+ fs.notification = nil
+ end
- function fs.show(seconds, scr)
- fs.hide()
- fs.update(function()
- fs.notification_preset.screen = fs.followtag and focused() or scr or 1
- fs.notification = naughty.notify {
- preset = fs.notification_preset,
- timeout = type(seconds) == "number" and seconds or 5
- }
- end)
- end
+ function fs.show(seconds, scr)
+ fs.hide()
+ fs.update(function()
+ fs.notification_preset.screen = fs.followtag and focused() or scr or 1
+ fs.notification = naughty.notify({
+ preset = fs.notification_preset,
+ timeout = type(seconds) == 'number' and seconds or 5,
+ })
+ end)
+ end
- local timeout = args.timeout or 600
- local partition = args.partition
- local threshold = args.threshold or 99
- local showpopup = args.showpopup or "on"
- local settings = args.settings or function() end
+ local timeout = args.timeout or 600
+ local partition = args.partition
+ local threshold = args.threshold or 99
+ local showpopup = args.showpopup or 'on'
+ local settings = args.settings or function() end
- fs.followtag = args.followtag or false
- fs.notification_preset = args.notification_preset
+ fs.followtag = args.followtag or false
+ fs.notification_preset = args.notification_preset
- if not fs.notification_preset then
- fs.notification_preset = {
- font = "Monospace 10",
- fg = "#FFFFFF",
- bg = "#000000"
- }
- end
+ if not fs.notification_preset then
+ fs.notification_preset = {
+ font = 'Monospace 10',
+ fg = '#FFFFFF',
+ bg = '#000000',
+ }
+ end
- local function update_synced()
- local pathlen = 10
- fs_now = {}
+ local function update_synced()
+ local pathlen = 10
+ fs_now = {}
- local notifypaths = {}
- for _, mount in ipairs(Gio.unix_mounts_get()) do
- local path = Gio.unix_mount_get_mount_path(mount)
- local root = Gio.File.new_for_path(path)
- local info = root:query_filesystem_info(query)
+ local notifypaths = {}
+ for _, mount in ipairs(Gio.unix_mounts_get()) do
+ local path = Gio.unix_mount_get_mount_path(mount)
+ local root = Gio.File.new_for_path(path)
+ local info = root:query_filesystem_info(query)
- if info then
- local size = info:get_attribute_uint64(query_size)
- local used = info:get_attribute_uint64(query_used)
- local free = info:get_attribute_uint64(query_free)
+ if info then
+ local size = info:get_attribute_uint64(query_size)
+ local used = info:get_attribute_uint64(query_used)
+ local free = info:get_attribute_uint64(query_free)
- if size > 0 then
- local units = math.floor(math.log(size)/math.log(1024))
+ if size > 0 then
+ local units = math.floor(math.log(size) / math.log(1024))
- fs_now[path] = {
- units = fs.units[units],
- percentage = math.floor(100 * used / size), -- used percentage
- size = size / math.pow(1024, units),
- used = used / math.pow(1024, units),
- free = free / math.pow(1024, units)
- }
+ fs_now[path] = {
+ units = fs.units[units],
+ percentage = math.floor(100 * used / size), -- used percentage
+ size = size / math.pow(1024, units),
+ used = used / math.pow(1024, units),
+ free = free / math.pow(1024, units),
+ }
- if fs_now[path].percentage > 0 then -- don't notify unused file systems
- notifypaths[#notifypaths+1] = path
+ if fs_now[path].percentage > 0 then -- don't notify unused file systems
+ notifypaths[#notifypaths + 1] = path
- if #path > pathlen then
- pathlen = #path
- end
- end
- end
- end
- end
+ if #path > pathlen then
+ pathlen = #path
+ end
+ end
+ end
+ end
+ end
- widget = fs.widget
- settings()
+ widget = fs.widget
+ settings()
- if partition and fs_now[partition] and fs_now[partition].percentage >= threshold then
- if not helpers.get_map(partition) then
- naughty.notify {
- preset = naughty.config.presets.critical,
- title = "Warning",
- text = string.format("%s is above %d%% (%d%%)", partition, threshold, fs_now[partition].percentage)
- }
- helpers.set_map(partition, true)
- else
- helpers.set_map(partition, false)
- end
- end
+ if partition and fs_now[partition] and fs_now[partition].percentage >= threshold then
+ if not helpers.get_map(partition) then
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = 'Warning',
+ text = string.format('%s is above %d%% (%d%%)', partition, threshold, fs_now[partition].percentage),
+ })
+ helpers.set_map(partition, true)
+ else
+ helpers.set_map(partition, false)
+ end
+ end
- local fmt = "%-" .. tostring(pathlen) .. "s %4s\t%6s\t%6s\n"
- local notifytable = { [1] = string.format(fmt, "path", "used", "free", "size") }
- fmt = "\n%-" .. tostring(pathlen) .. "s %3s%%\t%6.2f\t%6.2f %s"
- for _, path in ipairs(notifypaths) do
- notifytable[#notifytable+1] = string.format(fmt, path, fs_now[path].percentage, fs_now[path].free, fs_now[path].size, fs_now[path].units)
- end
+ local fmt = '%-' .. tostring(pathlen) .. 's %4s\t%6s\t%6s\n'
+ local notifytable = { [1] = string.format(fmt, 'path', 'used', 'free', 'size') }
+ fmt = '\n%-' .. tostring(pathlen) .. 's %3s%%\t%6.2f\t%6.2f %s'
+ for _, path in ipairs(notifypaths) do
+ notifytable[#notifytable + 1] = string.format(
+ fmt,
+ path,
+ fs_now[path].percentage,
+ fs_now[path].free,
+ fs_now[path].size,
+ fs_now[path].units
+ )
+ end
- fs.notification_preset.text = tconcat(notifytable)
- end
+ fs.notification_preset.text = tconcat(notifytable)
+ end
- function fs.update(callback)
- Gio.Async.start(gears.protected_call.call)(function()
- update_synced()
- if type(callback) == "function" and callback then
- callback()
- end
- end)
- end
+ function fs.update(callback)
+ Gio.Async.start(gears.protected_call.call)(function()
+ update_synced()
+ if type(callback) == 'function' and callback then
+ callback()
+ end
+ end)
+ end
- if showpopup == "on" then
- fs.widget:connect_signal('mouse::enter', function () fs.show(0) end)
- fs.widget:connect_signal('mouse::leave', function () fs.hide() end)
- end
+ if showpopup == 'on' then
+ fs.widget:connect_signal('mouse::enter', function()
+ fs.show(0)
+ end)
+ fs.widget:connect_signal('mouse::leave', function()
+ fs.hide()
+ end)
+ end
- helpers.newtimer(partition or "fs", timeout, fs.update)
+ helpers.newtimer(partition or 'fs', timeout, fs.update)
- return fs
+ return fs
end
return factory
diff --git a/awesome/lain/widget/imap.lua b/awesome/lain/widget/imap.lua
index e3f7baa..59aafc6 100644
--- a/awesome/lain/widget/imap.lua
+++ b/awesome/lain/widget/imap.lua
@@ -5,90 +5,111 @@
--]]
-local helpers = require("lain.helpers")
-local naughty = require("naughty")
-local wibox = require("wibox")
-local awful = require("awful")
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local awful = require('awful')
+local string = string
+local type = type
local tonumber = tonumber
-- Mail IMAP check
-- lain.widget.imap
local function factory(args)
- args = args or {}
+ args = args or {}
- local imap = { widget = args.widget or wibox.widget.textbox() }
- local server = args.server
- local mail = args.mail
- local password = args.password
- local port = args.port or 993
- local timeout = args.timeout or 60
- local pwdtimeout = args.pwdtimeout or 10
- local is_plain = args.is_plain or false
- local followtag = args.followtag or false
- local notify = args.notify or "on"
- local settings = args.settings or function() end
+ local imap = { widget = args.widget or wibox.widget.textbox() }
+ local server = args.server
+ local mail = args.mail
+ local password = args.password
+ local port = args.port or 993
+ local timeout = args.timeout or 60
+ local pwdtimeout = args.pwdtimeout or 10
+ local is_plain = args.is_plain or false
+ local followtag = args.followtag or false
+ local notify = args.notify or 'on'
+ local settings = args.settings or function() end
- local head_command = "curl --connect-timeout 3 -fsm 3"
- local request = "-X 'STATUS INBOX (MESSAGES RECENT UNSEEN)'"
+ 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"
- }
+ mail_notification_preset = {
+ icon = helpers.icons_dir .. 'mail.png',
+ position = 'top_left',
+ }
- helpers.set_map(mail, 0)
+ 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)
- elseif type(password) == "function" then
- imap.pwdtimer = helpers.newtimer(mail .. "-password", pwdtimeout, function()
- local retrieved_password, try_again = password()
- if not try_again then
- imap.pwdtimer:stop() -- stop trying to retrieve
- password = retrieved_password or "" -- failsafe
- end
- end, true, true)
- end
- end
+ if not is_plain then
+ if type(password) == 'string' or type(password) == 'table' then
+ 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()
+ if not try_again then
+ imap.pwdtimer:stop() -- stop trying to retrieve
+ password = retrieved_password or '' -- failsafe
+ end
+ end, true, true)
+ end
+ end
- function imap.update()
- -- do not update if the password has not been retrieved yet
- if type(password) ~= "string" then return end
+ function imap.update()
+ -- do not update if the password has not been retrieved yet
+ 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 }
+ 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
- mailcount = imap_now["UNSEEN"] -- backwards compatibility
- widget = imap.widget
+ 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()
+ 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 {
- preset = mail_notification_preset,
- text = string.format("%s has %d new message%s", mail, mailcount, mailcount == 1 and "" or "s")
- }
- end
+ 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({
+ preset = mail_notification_preset,
+ text = string.format(
+ '%s has %d new message%s',
+ mail,
+ mailcount,
+ mailcount == 1 and '' or 's'
+ ),
+ })
+ end
- helpers.set_map(mail, imap_now["UNSEEN"])
- end)
+ helpers.set_map(mail, imap_now['UNSEEN'])
+ end)
+ end
- end
+ imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true)
- imap.timer = helpers.newtimer(mail, timeout, imap.update, true, true)
-
- return imap
+ return imap
end
return factory
diff --git a/awesome/lain/widget/init.lua b/awesome/lain/widget/init.lua
index 57b86bb..1ba8be9 100644
--- a/awesome/lain/widget/init.lua
+++ b/awesome/lain/widget/init.lua
@@ -11,9 +11,9 @@
--]]
-local wrequire = require("lain.helpers").wrequire
+local wrequire = require('lain.helpers').wrequire
local setmetatable = setmetatable
-local widget = { _NAME = "lain.widget" }
+local widget = { _NAME = 'lain.widget' }
return setmetatable(widget, { __index = wrequire })
diff --git a/awesome/lain/widget/mem.lua b/awesome/lain/widget/mem.lua
index 0318494..597d15f 100644
--- a/awesome/lain/widget/mem.lua
+++ b/awesome/lain/widget/mem.lua
@@ -6,46 +6,53 @@
--]]
-local helpers = require("lain.helpers")
-local wibox = require("wibox")
+local helpers = require('lain.helpers')
+local wibox = require('wibox')
local gmatch, lines, floor = string.gmatch, io.lines, math.floor
-- Memory usage (ignoring caches)
-- lain.widget.mem
local function factory(args)
- args = args or {}
+ args = args or {}
- local mem = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 2
- local settings = args.settings or function() end
+ local mem = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 2
+ local settings = args.settings or function() end
- function mem.update()
- mem_now = {}
- for line in lines("/proc/meminfo") do
- for k, v in gmatch(line, "([%a]+):[%s]+([%d]+).+") do
- if k == "MemTotal" then mem_now.total = floor(v / 1024 + 0.5)
- elseif k == "MemFree" then mem_now.free = floor(v / 1024 + 0.5)
- elseif k == "Buffers" then mem_now.buf = floor(v / 1024 + 0.5)
- elseif k == "Cached" then mem_now.cache = floor(v / 1024 + 0.5)
- elseif k == "SwapTotal" then mem_now.swap = floor(v / 1024 + 0.5)
- elseif k == "SwapFree" then mem_now.swapf = floor(v / 1024 + 0.5)
- elseif k == "SReclaimable" then mem_now.srec = floor(v / 1024 + 0.5)
- end
- end
- end
+ function mem.update()
+ mem_now = {}
+ for line in lines('/proc/meminfo') do
+ for k, v in gmatch(line, '([%a]+):[%s]+([%d]+).+') do
+ if k == 'MemTotal' then
+ mem_now.total = floor(v / 1024 + 0.5)
+ elseif k == 'MemFree' then
+ mem_now.free = floor(v / 1024 + 0.5)
+ elseif k == 'Buffers' then
+ mem_now.buf = floor(v / 1024 + 0.5)
+ elseif k == 'Cached' then
+ mem_now.cache = floor(v / 1024 + 0.5)
+ elseif k == 'SwapTotal' then
+ mem_now.swap = floor(v / 1024 + 0.5)
+ elseif k == 'SwapFree' then
+ mem_now.swapf = floor(v / 1024 + 0.5)
+ elseif k == 'SReclaimable' then
+ mem_now.srec = floor(v / 1024 + 0.5)
+ end
+ end
+ end
- mem_now.used = mem_now.total - mem_now.free - mem_now.buf - mem_now.cache - mem_now.srec
- mem_now.swapused = mem_now.swap - mem_now.swapf
- mem_now.perc = math.floor(mem_now.used / mem_now.total * 100)
+ mem_now.used = mem_now.total - mem_now.free - mem_now.buf - mem_now.cache - mem_now.srec
+ mem_now.swapused = mem_now.swap - mem_now.swapf
+ mem_now.perc = math.floor(mem_now.used / mem_now.total * 100)
- widget = mem.widget
- settings()
- end
+ widget = mem.widget
+ settings()
+ end
- helpers.newtimer("mem", timeout, mem.update)
+ helpers.newtimer('mem', timeout, mem.update)
- return mem
+ return mem
end
return factory
diff --git a/awesome/lain/widget/mpd.lua b/awesome/lain/widget/mpd.lua
index 55d3649..d786d14 100644
--- a/awesome/lain/widget/mpd.lua
+++ b/awesome/lain/widget/mpd.lua
@@ -6,130 +6,154 @@
--]]
-local helpers = require("lain.helpers")
-local shell = require("awful.util").shell
-local escape_f = require("awful.util").escape
-local focused = require("awful.screen").focused
-local naughty = require("naughty")
-local wibox = require("wibox")
-local os = os
-local string = string
+local helpers = require('lain.helpers')
+local shell = require('awful.util').shell
+local escape_f = require('awful.util').escape
+local focused = require('awful.screen').focused
+local naughty = require('naughty')
+local wibox = require('wibox')
+local os = os
+local string = string
-- MPD infos
-- lain.widget.mpd
local function factory(args)
- args = args or {}
+ args = args or {}
- local mpd = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 2
- local password = (args.password and #args.password > 0 and string.format("password %s\\n", args.password)) or ""
- local host = args.host or os.getenv("MPD_HOST") or "127.0.0.1"
- local port = args.port or os.getenv("MPD_PORT") or "6600"
- local music_dir = args.music_dir or os.getenv("HOME") .. "/Music"
- local cover_pattern = args.cover_pattern or "*\\.(jpg|jpeg|png|gif)$"
- local cover_size = args.cover_size or 100
- local default_art = args.default_art
- local notify = args.notify or "on"
- local followtag = args.followtag or false
- local settings = args.settings or function() end
+ local mpd = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 2
+ local password = (args.password and #args.password > 0 and string.format('password %s\\n', args.password)) or ''
+ local host = args.host or os.getenv('MPD_HOST') or '127.0.0.1'
+ local port = args.port or os.getenv('MPD_PORT') or '6600'
+ local music_dir = args.music_dir or os.getenv('HOME') .. '/Music'
+ local cover_pattern = args.cover_pattern or '*\\.(jpg|jpeg|png|gif)$'
+ local cover_size = args.cover_size or 100
+ local default_art = args.default_art
+ local notify = args.notify or 'on'
+ local followtag = args.followtag or false
+ local settings = args.settings or function() end
- local mpdh = string.format("telnet://%s:%s", host, port)
- local echo = string.format("printf \"%sstatus\\ncurrentsong\\nclose\\n\"", password)
- local cmd = string.format("%s | curl --connect-timeout 1 -fsm 3 %s", echo, mpdh)
+ local mpdh = string.format('telnet://%s:%s', host, port)
+ local echo = string.format('printf "%sstatus\\ncurrentsong\\nclose\\n"', password)
+ local cmd = string.format('%s | curl --connect-timeout 1 -fsm 3 %s', echo, mpdh)
- mpd_notification_preset = { title = "Now playing", timeout = 6 }
+ mpd_notification_preset = { title = 'Now playing', timeout = 6 }
- helpers.set_map("current mpd track", nil)
+ helpers.set_map('current mpd track', nil)
- function mpd.update()
- helpers.async({ shell, "-c", cmd }, function(f)
- mpd_now = {
- random_mode = false,
- single_mode = false,
- repeat_mode = false,
- consume_mode = false,
- pls_pos = "N/A",
- pls_len = "N/A",
- state = "N/A",
- file = "N/A",
- name = "N/A",
- artist = "N/A",
- title = "N/A",
- album = "N/A",
- genre = "N/A",
- track = "N/A",
- date = "N/A",
- time = "N/A",
- elapsed = "N/A",
- volume = "N/A"
- }
+ function mpd.update()
+ helpers.async({ shell, '-c', cmd }, function(f)
+ mpd_now = {
+ random_mode = false,
+ single_mode = false,
+ repeat_mode = false,
+ consume_mode = false,
+ pls_pos = 'N/A',
+ pls_len = 'N/A',
+ state = 'N/A',
+ file = 'N/A',
+ name = 'N/A',
+ artist = 'N/A',
+ title = 'N/A',
+ album = 'N/A',
+ genre = 'N/A',
+ track = 'N/A',
+ date = 'N/A',
+ time = 'N/A',
+ elapsed = 'N/A',
+ volume = 'N/A',
+ }
- for line in string.gmatch(f, "[^\n]+") do
- for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do
- if k == "state" then mpd_now.state = v
- elseif k == "file" then mpd_now.file = v
- elseif k == "Name" then mpd_now.name = escape_f(v)
- elseif k == "Artist" then mpd_now.artist = escape_f(v)
- elseif k == "Title" then mpd_now.title = escape_f(v)
- elseif k == "Album" then mpd_now.album = escape_f(v)
- elseif k == "Genre" then mpd_now.genre = escape_f(v)
- elseif k == "Track" then mpd_now.track = escape_f(v)
- elseif k == "Date" then mpd_now.date = escape_f(v)
- elseif k == "Time" then mpd_now.time = v
- elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+")
- elseif k == "song" then mpd_now.pls_pos = v
- elseif k == "playlistlength" then mpd_now.pls_len = v
- elseif k == "repeat" then mpd_now.repeat_mode = v ~= "0"
- elseif k == "single" then mpd_now.single_mode = v ~= "0"
- elseif k == "random" then mpd_now.random_mode = v ~= "0"
- elseif k == "consume" then mpd_now.consume_mode = v ~= "0"
- elseif k == "volume" then mpd_now.volume = v
- end
- end
- end
+ for line in string.gmatch(f, '[^\n]+') do
+ for k, v in string.gmatch(line, '([%w]+):[%s](.*)$') do
+ if k == 'state' then
+ mpd_now.state = v
+ elseif k == 'file' then
+ mpd_now.file = v
+ elseif k == 'Name' then
+ mpd_now.name = escape_f(v)
+ elseif k == 'Artist' then
+ mpd_now.artist = escape_f(v)
+ elseif k == 'Title' then
+ mpd_now.title = escape_f(v)
+ elseif k == 'Album' then
+ mpd_now.album = escape_f(v)
+ elseif k == 'Genre' then
+ mpd_now.genre = escape_f(v)
+ elseif k == 'Track' then
+ mpd_now.track = escape_f(v)
+ elseif k == 'Date' then
+ mpd_now.date = escape_f(v)
+ elseif k == 'Time' then
+ mpd_now.time = v
+ elseif k == 'elapsed' then
+ mpd_now.elapsed = string.match(v, '%d+')
+ elseif k == 'song' then
+ mpd_now.pls_pos = v
+ elseif k == 'playlistlength' then
+ mpd_now.pls_len = v
+ elseif k == 'repeat' then
+ mpd_now.repeat_mode = v ~= '0'
+ elseif k == 'single' then
+ mpd_now.single_mode = v ~= '0'
+ elseif k == 'random' then
+ mpd_now.random_mode = v ~= '0'
+ elseif k == 'consume' then
+ mpd_now.consume_mode = v ~= '0'
+ elseif k == 'volume' then
+ mpd_now.volume = v
+ end
+ end
+ end
- mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist,
- mpd_now.album, mpd_now.date, mpd_now.title)
- widget = mpd.widget
- settings()
+ mpd_notification_preset.text =
+ string.format('%s (%s) - %s\n%s', mpd_now.artist, mpd_now.album, mpd_now.date, mpd_now.title)
+ widget = mpd.widget
+ settings()
- if mpd_now.state == "play" then
- if notify == "on" and mpd_now.title ~= helpers.get_map("current mpd track") then
- helpers.set_map("current mpd track", mpd_now.title)
+ if mpd_now.state == 'play' then
+ if notify == 'on' and mpd_now.title ~= helpers.get_map('current mpd track') then
+ helpers.set_map('current mpd track', mpd_now.title)
- if followtag then mpd_notification_preset.screen = focused() end
+ if followtag then
+ mpd_notification_preset.screen = focused()
+ end
- local common = {
- preset = mpd_notification_preset,
- icon = default_art,
- icon_size = cover_size,
- replaces_id = mpd.id
- }
+ local common = {
+ preset = mpd_notification_preset,
+ icon = default_art,
+ icon_size = cover_size,
+ replaces_id = mpd.id,
+ }
- if not string.match(mpd_now.file, "http.*://") then -- local file instead of http stream
- local path = string.format("%s/%s", music_dir, string.match(mpd_now.file, ".*/"))
- local cover = string.format("find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'",
- path:gsub("'", "'\\''"), cover_pattern)
- helpers.async({ shell, "-c", cover }, function(current_icon)
- common.icon = current_icon:gsub("\n", "")
- if #common.icon == 0 then common.icon = nil end
- mpd.id = naughty.notify(common).id
- end)
- else
- mpd.id = naughty.notify(common).id
- end
+ if not string.match(mpd_now.file, 'http.*://') then -- local file instead of http stream
+ local path = string.format('%s/%s', music_dir, string.match(mpd_now.file, '.*/'))
+ local cover = string.format(
+ "find '%s' -maxdepth 1 -type f | egrep -i -m1 '%s'",
+ path:gsub("'", "'\\''"),
+ cover_pattern
+ )
+ helpers.async({ shell, '-c', cover }, function(current_icon)
+ common.icon = current_icon:gsub('\n', '')
+ if #common.icon == 0 then
+ common.icon = nil
+ end
+ mpd.id = naughty.notify(common).id
+ end)
+ else
+ mpd.id = naughty.notify(common).id
+ end
+ end
+ elseif mpd_now.state ~= 'pause' then
+ helpers.set_map('current mpd track', nil)
+ end
+ end)
+ end
- end
- elseif mpd_now.state ~= "pause" then
- helpers.set_map("current mpd track", nil)
- end
- end)
- end
+ mpd.timer = helpers.newtimer('mpd', timeout, mpd.update, true, true)
- mpd.timer = helpers.newtimer("mpd", timeout, mpd.update, true, true)
-
- return mpd
+ return mpd
end
return factory
diff --git a/awesome/lain/widget/net.lua b/awesome/lain/widget/net.lua
index 9b7b165..5a95900 100644
--- a/awesome/lain/widget/net.lua
+++ b/awesome/lain/widget/net.lua
@@ -6,117 +6,128 @@
--]]
-local helpers = require("lain.helpers")
-local naughty = require("naughty")
-local wibox = require("wibox")
-local string = string
+local helpers = require('lain.helpers')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local string = string
-- Network infos
-- lain.widget.net
local function factory(args)
- args = args or {}
+ args = args or {}
- local net = { widget = args.widget or wibox.widget.textbox(), devices = {} }
- local timeout = args.timeout or 2
- local units = args.units or 1024 -- KB
- local notify = args.notify or "on"
- local wifi_state = args.wifi_state or "off"
- local eth_state = args.eth_state or "off"
- local screen = args.screen or 1
- local format = args.format or "%.1f"
- local settings = args.settings or function() end
+ local net = { widget = args.widget or wibox.widget.textbox(), devices = {} }
+ local timeout = args.timeout or 2
+ local units = args.units or 1024 -- KB
+ local notify = args.notify or 'on'
+ local wifi_state = args.wifi_state or 'off'
+ local eth_state = args.eth_state or 'off'
+ local screen = args.screen or 1
+ local format = args.format or '%.1f'
+ local settings = args.settings or function() end
- -- Compatibility with old API where iface was a string corresponding to 1 interface
- net.iface = (args.iface and (type(args.iface) == "string" and {args.iface}) or
- (type(args.iface) == "table" and args.iface)) or {}
+ -- Compatibility with old API where iface was a string corresponding to 1 interface
+ net.iface = (
+ args.iface and (type(args.iface) == 'string' and { args.iface })
+ or (type(args.iface) == 'table' and args.iface)
+ ) or {}
- function net.get_devices()
- net.iface = {} -- reset at every call
- helpers.line_callback("ip link", function(line)
- net.iface[#net.iface + 1] = not string.match(line, "LOOPBACK") and string.match(line, "(%w+): <") or nil
- end)
- end
+ function net.get_devices()
+ net.iface = {} -- reset at every call
+ helpers.line_callback('ip link', function(line)
+ net.iface[#net.iface + 1] = not string.match(line, 'LOOPBACK') and string.match(line, '(%w+): <') or nil
+ end)
+ end
- if #net.iface == 0 then net.get_devices() end
+ if #net.iface == 0 then
+ net.get_devices()
+ end
- function net.update()
- -- These are the totals over all specified interfaces
- net_now = {
- devices = {},
- -- Bytes since last iteration
- sent = 0,
- received = 0
- }
+ function net.update()
+ -- These are the totals over all specified interfaces
+ net_now = {
+ devices = {},
+ -- Bytes since last iteration
+ sent = 0,
+ received = 0,
+ }
- for _, dev in ipairs(net.iface) do
- local dev_now = {}
- local dev_before = net.devices[dev] or { last_t = 0, last_r = 0 }
- local now_t = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/tx_bytes", dev)) or 0)
- local now_r = tonumber(helpers.first_line(string.format("/sys/class/net/%s/statistics/rx_bytes", dev)) or 0)
+ for _, dev in ipairs(net.iface) do
+ local dev_now = {}
+ local dev_before = net.devices[dev] or { last_t = 0, last_r = 0 }
+ local now_t = tonumber(helpers.first_line(string.format('/sys/class/net/%s/statistics/tx_bytes', dev)) or 0)
+ local now_r = tonumber(helpers.first_line(string.format('/sys/class/net/%s/statistics/rx_bytes', dev)) or 0)
- dev_now.carrier = helpers.first_line(string.format("/sys/class/net/%s/carrier", dev)) or "0"
- dev_now.state = helpers.first_line(string.format("/sys/class/net/%s/operstate", dev)) or "down"
+ dev_now.carrier = helpers.first_line(string.format('/sys/class/net/%s/carrier', dev)) or '0'
+ dev_now.state = helpers.first_line(string.format('/sys/class/net/%s/operstate', dev)) or 'down'
- dev_now.sent = (now_t - dev_before.last_t) / timeout / units
- dev_now.received = (now_r - dev_before.last_r) / timeout / units
+ dev_now.sent = (now_t - dev_before.last_t) / timeout / units
+ dev_now.received = (now_r - dev_before.last_r) / timeout / units
- net_now.sent = net_now.sent + dev_now.sent
- net_now.received = net_now.received + dev_now.received
+ net_now.sent = net_now.sent + dev_now.sent
+ net_now.received = net_now.received + dev_now.received
- dev_now.sent = string.format(format, dev_now.sent)
- dev_now.received = string.format(format, dev_now.received)
+ dev_now.sent = string.format(format, dev_now.sent)
+ dev_now.received = string.format(format, dev_now.received)
- dev_now.last_t = now_t
- dev_now.last_r = now_r
+ dev_now.last_t = now_t
+ dev_now.last_r = now_r
- if wifi_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) == "DEVTYPE=wlan" then
- dev_now.wifi = true
- if string.match(dev_now.carrier, "1") then
- dev_now.signal = tonumber(string.match(helpers.lines_from("/proc/net/wireless")[3], "(%-%d+%.)")) or nil
- end
- else
- dev_now.wifi = false
- end
+ if
+ wifi_state == 'on'
+ and helpers.first_line(string.format('/sys/class/net/%s/uevent', dev)) == 'DEVTYPE=wlan'
+ then
+ dev_now.wifi = true
+ if string.match(dev_now.carrier, '1') then
+ dev_now.signal = tonumber(string.match(helpers.lines_from('/proc/net/wireless')[3], '(%-%d+%.)'))
+ or nil
+ end
+ else
+ dev_now.wifi = false
+ end
- if eth_state == "on" and helpers.first_line(string.format("/sys/class/net/%s/uevent", dev)) ~= "DEVTYPE=wlan" then
- dev_now.ethernet = true
- else
- dev_now.ethernet = false
- end
+ if
+ eth_state == 'on'
+ and helpers.first_line(string.format('/sys/class/net/%s/uevent', dev)) ~= 'DEVTYPE=wlan'
+ then
+ dev_now.ethernet = true
+ else
+ dev_now.ethernet = false
+ end
- net.devices[dev] = dev_now
+ net.devices[dev] = dev_now
- -- Notify only once when connection is lost
- if string.match(dev_now.carrier, "0") and notify == "on" and helpers.get_map(dev) then
- naughty.notify {
- title = dev,
- text = "No carrier",
- icon = helpers.icons_dir .. "no_net.png",
- screen = screen
- }
- helpers.set_map(dev, false)
- elseif string.match(dev_now.carrier, "1") then
- helpers.set_map(dev, true)
- end
+ -- Notify only once when connection is lost
+ if string.match(dev_now.carrier, '0') and notify == 'on' and helpers.get_map(dev) then
+ naughty.notify({
+ title = dev,
+ text = 'No carrier',
+ icon = helpers.icons_dir .. 'no_net.png',
+ screen = screen,
+ })
+ helpers.set_map(dev, false)
+ elseif string.match(dev_now.carrier, '1') then
+ helpers.set_map(dev, true)
+ end
- net_now.carrier = dev_now.carrier
- net_now.state = dev_now.state
- net_now.devices[dev] = dev_now
- -- net_now.sent and net_now.received will be
- -- the totals across all specified devices
- end
+ net_now.carrier = dev_now.carrier
+ net_now.state = dev_now.state
+ net_now.devices[dev] = dev_now
+ -- net_now.sent and net_now.received will be
+ -- the totals across all specified devices
+ end
- net_now.sent = string.format(format, net_now.sent)
- net_now.received = string.format(format, net_now.received)
+ net_now.sent = string.format(format, net_now.sent)
+ net_now.received = string.format(format, net_now.received)
- widget = net.widget
- settings()
- end
+ widget = net.widget
+ settings()
+ end
- helpers.newtimer("network", timeout, net.update)
+ helpers.newtimer('network', timeout, net.update)
- return net
+ return net
end
return factory
diff --git a/awesome/lain/widget/pulse.lua b/awesome/lain/widget/pulse.lua
index 69f4d70..7c3845c 100644
--- a/awesome/lain/widget/pulse.lua
+++ b/awesome/lain/widget/pulse.lua
@@ -5,54 +5,56 @@
--]]
-local helpers = require("lain.helpers")
-local shell = require("awful.util").shell
-local wibox = require("wibox")
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local shell = require('awful.util').shell
+local wibox = require('wibox')
+local string = string
+local type = type
-- PulseAudio volume
-- lain.widget.pulse
local function factory(args)
- args = args or {}
+ args = args or {}
- local pulse = { widget = args.widget or wibox.widget.textbox(), device = "N/A" }
- local timeout = args.timeout or 5
- local settings = args.settings or function() end
+ local pulse = { widget = args.widget or wibox.widget.textbox(), device = 'N/A' }
+ local timeout = args.timeout or 5
+ local settings = args.settings or function() end
- pulse.devicetype = args.devicetype or "sink"
- pulse.cmd = args.cmd or "pacmd list-" .. pulse.devicetype .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
+ pulse.devicetype = args.devicetype or 'sink'
+ pulse.cmd = args.cmd
+ or 'pacmd list-'
+ .. pulse.devicetype
+ .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
- function pulse.update()
- helpers.async({ shell, "-c", type(pulse.cmd) == "string" and pulse.cmd or pulse.cmd() },
- function(s)
- volume_now = {
- index = string.match(s, "index: (%S+)") or "N/A",
- device = string.match(s, "device.string = \"(%S+)\"") or "N/A",
- muted = string.match(s, "muted: (%S+)") or "N/A"
- }
+ function pulse.update()
+ helpers.async({ shell, '-c', type(pulse.cmd) == 'string' and pulse.cmd or pulse.cmd() }, function(s)
+ volume_now = {
+ index = string.match(s, 'index: (%S+)') or 'N/A',
+ device = string.match(s, 'device.string = "(%S+)"') or 'N/A',
+ muted = string.match(s, 'muted: (%S+)') or 'N/A',
+ }
- pulse.device = volume_now.index
+ pulse.device = volume_now.index
- local ch = 1
- volume_now.channel = {}
- for v in string.gmatch(s, ":.-(%d+)%%") do
- volume_now.channel[ch] = v
- ch = ch + 1
- end
+ local ch = 1
+ volume_now.channel = {}
+ for v in string.gmatch(s, ':.-(%d+)%%') do
+ volume_now.channel[ch] = v
+ ch = ch + 1
+ end
- volume_now.left = volume_now.channel[1] or "N/A"
- volume_now.right = volume_now.channel[2] or "N/A"
+ volume_now.left = volume_now.channel[1] or 'N/A'
+ volume_now.right = volume_now.channel[2] or 'N/A'
- widget = pulse.widget
- settings()
- end)
- end
+ widget = pulse.widget
+ settings()
+ end)
+ end
- helpers.newtimer("pulse", timeout, pulse.update)
+ helpers.newtimer('pulse', timeout, pulse.update)
- return pulse
+ return pulse
end
return factory
diff --git a/awesome/lain/widget/pulsebar.lua b/awesome/lain/widget/pulsebar.lua
index 19e73b9..3cd5f07 100644
--- a/awesome/lain/widget/pulsebar.lua
+++ b/awesome/lain/widget/pulsebar.lua
@@ -6,170 +6,180 @@
--]]
-local helpers = require("lain.helpers")
-local awful = require("awful")
-local naughty = require("naughty")
-local wibox = require("wibox")
-local math = math
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local awful = require('awful')
+local naughty = require('naughty')
+local wibox = require('wibox')
+local math = math
+local string = string
+local type = type
local tonumber = tonumber
-- PulseAudio volume bar
-- lain.widget.pulsebar
local function factory(args)
- local pulsebar = {
- colors = {
- background = "#000000",
- mute_background = "#000000",
- mute = "#EB8F8F",
- unmute = "#A4CE8A"
- },
+ local pulsebar = {
+ colors = {
+ background = '#000000',
+ mute_background = '#000000',
+ mute = '#EB8F8F',
+ unmute = '#A4CE8A',
+ },
- _current_level = 0,
- _mute = "no",
- device = "N/A"
- }
+ _current_level = 0,
+ _mute = 'no',
+ device = 'N/A',
+ }
- args = args or {}
+ args = args or {}
- local timeout = args.timeout or 5
- local settings = args.settings or function() end
- local width = args.width or 63
- local height = args.height or 1
- local margins = args.margins or 1
- local paddings = args.paddings or 1
- local ticks = args.ticks or false
- local ticks_size = args.ticks_size or 7
- local tick = args.tick or "|"
- local tick_pre = args.tick_pre or "["
- local tick_post = args.tick_post or "]"
- local tick_none = args.tick_none or " "
+ local timeout = args.timeout or 5
+ local settings = args.settings or function() end
+ local width = args.width or 63
+ local height = args.height or 1
+ local margins = args.margins or 1
+ local paddings = args.paddings or 1
+ local ticks = args.ticks or false
+ local ticks_size = args.ticks_size or 7
+ local tick = args.tick or '|'
+ local tick_pre = args.tick_pre or '['
+ local tick_post = args.tick_post or ']'
+ local tick_none = args.tick_none or ' '
- pulsebar.colors = args.colors or pulsebar.colors
- pulsebar.followtag = args.followtag or false
- pulsebar.notification_preset = args.notification_preset
- pulsebar.devicetype = args.devicetype or "sink"
- pulsebar.cmd = args.cmd or "pacmd list-" .. pulsebar.devicetype .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
+ pulsebar.colors = args.colors or pulsebar.colors
+ pulsebar.followtag = args.followtag or false
+ pulsebar.notification_preset = args.notification_preset
+ pulsebar.devicetype = args.devicetype or 'sink'
+ pulsebar.cmd = args.cmd
+ or 'pacmd list-'
+ .. pulsebar.devicetype
+ .. "s | sed -n -e '/*/,$!d' -e '/index/p' -e '/base volume/d' -e '/volume:/p' -e '/muted:/p' -e '/device\\.string/p'"
- if not pulsebar.notification_preset then
- pulsebar.notification_preset = {
- font = "Monospace 10"
- }
- end
+ if not pulsebar.notification_preset then
+ pulsebar.notification_preset = {
+ font = 'Monospace 10',
+ }
+ end
- pulsebar.bar = wibox.widget {
- color = pulsebar.colors.unmute,
- background_color = pulsebar.colors.background,
- forced_height = height,
- forced_width = width,
- margins = margins,
- paddings = paddings,
- ticks = ticks,
- ticks_size = ticks_size,
- widget = wibox.widget.progressbar,
- }
+ pulsebar.bar = wibox.widget({
+ color = pulsebar.colors.unmute,
+ background_color = pulsebar.colors.background,
+ forced_height = height,
+ forced_width = width,
+ margins = margins,
+ paddings = paddings,
+ ticks = ticks,
+ ticks_size = ticks_size,
+ widget = wibox.widget.progressbar,
+ })
- pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
+ pulsebar.tooltip = awful.tooltip({ objects = { pulsebar.bar } })
- function pulsebar.update(callback)
- helpers.async({ awful.util.shell, "-c", type(pulsebar.cmd) == "string" and pulsebar.cmd or pulsebar.cmd() },
- function(s)
- volume_now = {
- index = string.match(s, "index: (%S+)") or "N/A",
- device = string.match(s, "device.string = \"(%S+)\"") or "N/A",
- muted = string.match(s, "muted: (%S+)") or "N/A"
- }
+ function pulsebar.update(callback)
+ helpers.async(
+ { awful.util.shell, '-c', type(pulsebar.cmd) == 'string' and pulsebar.cmd or pulsebar.cmd() },
+ function(s)
+ volume_now = {
+ index = string.match(s, 'index: (%S+)') or 'N/A',
+ device = string.match(s, 'device.string = "(%S+)"') or 'N/A',
+ muted = string.match(s, 'muted: (%S+)') or 'N/A',
+ }
- pulsebar.device = volume_now.index
+ pulsebar.device = volume_now.index
- local ch = 1
- volume_now.channel = {}
- for v in string.gmatch(s, ":.-(%d+)%%") do
- volume_now.channel[ch] = v
- ch = ch + 1
- end
+ local ch = 1
+ volume_now.channel = {}
+ for v in string.gmatch(s, ':.-(%d+)%%') do
+ volume_now.channel[ch] = v
+ ch = ch + 1
+ end
- volume_now.left = volume_now.channel[1] or "N/A"
- volume_now.right = volume_now.channel[2] or "N/A"
+ volume_now.left = volume_now.channel[1] or 'N/A'
+ volume_now.right = volume_now.channel[2] or 'N/A'
- local volu = volume_now.left
- local mute = volume_now.muted
+ local volu = volume_now.left
+ local mute = volume_now.muted
- if volu:match("N/A") or mute:match("N/A") then return end
+ if volu:match('N/A') or mute:match('N/A') then
+ return
+ end
- if volu ~= pulsebar._current_level or mute ~= pulsebar._mute then
- pulsebar._current_level = tonumber(volu)
- pulsebar.bar:set_value(pulsebar._current_level / 100)
- if pulsebar._current_level == 0 or mute == "yes" then
- pulsebar._mute = mute
- pulsebar.tooltip:set_text ("[muted]")
- pulsebar.bar.color = pulsebar.colors.mute
- pulsebar.bar.background_color = pulsebar.colors.mute_background
- else
- pulsebar._mute = "no"
- pulsebar.tooltip:set_text(string.format("%s %s: %s", pulsebar.devicetype, pulsebar.device, volu))
- pulsebar.bar.color = pulsebar.colors.unmute
- pulsebar.bar.background_color = pulsebar.colors.background
- end
+ if volu ~= pulsebar._current_level or mute ~= pulsebar._mute then
+ pulsebar._current_level = tonumber(volu)
+ pulsebar.bar:set_value(pulsebar._current_level / 100)
+ if pulsebar._current_level == 0 or mute == 'yes' then
+ pulsebar._mute = mute
+ pulsebar.tooltip:set_text('[muted]')
+ pulsebar.bar.color = pulsebar.colors.mute
+ pulsebar.bar.background_color = pulsebar.colors.mute_background
+ else
+ pulsebar._mute = 'no'
+ pulsebar.tooltip:set_text(
+ string.format('%s %s: %s', pulsebar.devicetype, pulsebar.device, volu)
+ )
+ pulsebar.bar.color = pulsebar.colors.unmute
+ pulsebar.bar.background_color = pulsebar.colors.background
+ end
- settings()
+ settings()
- if type(callback) == "function" then callback() end
- end
- end)
- end
+ if type(callback) == 'function' then
+ callback()
+ end
+ end
+ end
+ )
+ end
- function pulsebar.notify()
- pulsebar.update(function()
- local preset = pulsebar.notification_preset
+ function pulsebar.notify()
+ pulsebar.update(function()
+ local preset = pulsebar.notification_preset
- preset.title = string.format("%s %s - %s%%", pulsebar.devicetype, pulsebar.device, pulsebar._current_level)
+ preset.title = string.format('%s %s - %s%%', pulsebar.devicetype, pulsebar.device, pulsebar._current_level)
- if pulsebar._mute == "yes" then
- preset.title = preset.title .. " muted"
- end
+ if pulsebar._mute == 'yes' then
+ preset.title = preset.title .. ' muted'
+ end
- -- tot is the maximum number of ticks to display in the notification
- -- fallback: default horizontal wibox height
- local wib, tot = awful.screen.focused().mywibox, 20
+ -- tot is the maximum number of ticks to display in the notification
+ -- fallback: default horizontal wibox height
+ local wib, tot = awful.screen.focused().mywibox, 20
- -- if we can grab mywibox, tot is defined as its height if
- -- horizontal, or width otherwise
- if wib then
- if wib.position == "left" or wib.position == "right" then
- tot = wib.width
- else
- tot = wib.height
- end
- end
+ -- if we can grab mywibox, tot is defined as its height if
+ -- horizontal, or width otherwise
+ if wib then
+ if wib.position == 'left' or wib.position == 'right' then
+ tot = wib.width
+ else
+ tot = wib.height
+ end
+ end
- local int = math.modf((pulsebar._current_level / 100) * tot)
- preset.text = string.format(
- "%s%s%s%s",
- tick_pre,
- string.rep(tick, int),
- string.rep(tick_none, tot - int),
- tick_post
- )
+ local int = math.modf((pulsebar._current_level / 100) * tot)
+ preset.text =
+ string.format('%s%s%s%s', tick_pre, string.rep(tick, int), string.rep(tick_none, tot - int), tick_post)
- if pulsebar.followtag then preset.screen = awful.screen.focused() end
+ if pulsebar.followtag then
+ preset.screen = awful.screen.focused()
+ end
- if not pulsebar.notification then
- pulsebar.notification = naughty.notify {
- preset = preset,
- destroy = function() pulsebar.notification = nil end
- }
- else
- naughty.replace_text(pulsebar.notification, preset.title, preset.text)
- end
- end)
- end
+ if not pulsebar.notification then
+ pulsebar.notification = naughty.notify({
+ preset = preset,
+ destroy = function()
+ pulsebar.notification = nil
+ end,
+ })
+ else
+ naughty.replace_text(pulsebar.notification, preset.title, preset.text)
+ end
+ end)
+ end
- helpers.newtimer(string.format("pulsebar-%s-%s", pulsebar.devicetype, pulsebar.device), timeout, pulsebar.update)
+ helpers.newtimer(string.format('pulsebar-%s-%s', pulsebar.devicetype, pulsebar.device), timeout, pulsebar.update)
- return pulsebar
+ return pulsebar
end
return factory
diff --git a/awesome/lain/widget/sysload.lua b/awesome/lain/widget/sysload.lua
index 7260524..1704432 100644
--- a/awesome/lain/widget/sysload.lua
+++ b/awesome/lain/widget/sysload.lua
@@ -6,34 +6,34 @@
--]]
-local helpers = require("lain.helpers")
-local wibox = require("wibox")
+local helpers = require('lain.helpers')
+local wibox = require('wibox')
local open, match = io.open, string.match
-- System load
-- lain.widget.sysload
local function factory(args)
- args = args or {}
+ args = args or {}
- local sysload = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 2
- local settings = args.settings or function() end
+ local sysload = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 2
+ local settings = args.settings or function() end
- function sysload.update()
- local f = open("/proc/loadavg")
- local ret = f:read("*all")
- f:close()
+ function sysload.update()
+ local f = open('/proc/loadavg')
+ local ret = f:read('*all')
+ f:close()
- load_1, load_5, load_15 = match(ret, "([^%s]+) ([^%s]+) ([^%s]+)")
+ load_1, load_5, load_15 = match(ret, '([^%s]+) ([^%s]+) ([^%s]+)')
- widget = sysload.widget
- settings()
- end
+ widget = sysload.widget
+ settings()
+ end
- helpers.newtimer("sysload", timeout, sysload.update)
+ helpers.newtimer('sysload', timeout, sysload.update)
- return sysload
+ return sysload
end
return factory
diff --git a/awesome/lain/widget/temp.lua b/awesome/lain/widget/temp.lua
index 99f8700..ed0f24a 100644
--- a/awesome/lain/widget/temp.lua
+++ b/awesome/lain/widget/temp.lua
@@ -5,46 +5,46 @@
--]]
-local helpers = require("lain.helpers")
-local wibox = require("wibox")
+local helpers = require('lain.helpers')
+local wibox = require('wibox')
local tonumber = tonumber
-- {thermal,core} temperature info
-- lain.widget.temp
local function factory(args)
- args = args or {}
+ args = args or {}
- local temp = { widget = args.widget or wibox.widget.textbox() }
- local timeout = args.timeout or 30
- local tempfile = args.tempfile or "/sys/devices/virtual/thermal/thermal_zone0/temp"
- local format = args.format or "%.1f"
- local settings = args.settings or function() end
+ local temp = { widget = args.widget or wibox.widget.textbox() }
+ local timeout = args.timeout or 30
+ local tempfile = args.tempfile or '/sys/devices/virtual/thermal/thermal_zone0/temp'
+ local format = args.format or '%.1f'
+ local settings = args.settings or function() end
- function temp.update()
- helpers.async({"find", "/sys/devices", "-type", "f", "-name", "*temp*"}, function(f)
- temp_now = {}
- local temp_fl, temp_value
- for t in f:gmatch("[^\n]+") do
- temp_fl = helpers.first_line(t)
- if temp_fl then
- temp_value = tonumber(temp_fl)
- temp_now[t] = temp_value and temp_value/1e3 or temp_fl
- end
- end
- if temp_now[tempfile] then
- coretemp_now = string.format(format, temp_now[tempfile])
- else
- coretemp_now = "N/A"
- end
- widget = temp.widget
- settings()
- end)
- end
+ function temp.update()
+ helpers.async({ 'find', '/sys/devices', '-type', 'f', '-name', '*temp*' }, function(f)
+ temp_now = {}
+ local temp_fl, temp_value
+ for t in f:gmatch('[^\n]+') do
+ temp_fl = helpers.first_line(t)
+ if temp_fl then
+ temp_value = tonumber(temp_fl)
+ temp_now[t] = temp_value and temp_value / 1e3 or temp_fl
+ end
+ end
+ if temp_now[tempfile] then
+ coretemp_now = string.format(format, temp_now[tempfile])
+ else
+ coretemp_now = 'N/A'
+ end
+ widget = temp.widget
+ settings()
+ end)
+ end
- helpers.newtimer("thermal", timeout, temp.update)
+ helpers.newtimer('thermal', timeout, temp.update)
- return temp
+ return temp
end
return factory
diff --git a/awesome/lain/widget/weather.lua b/awesome/lain/widget/weather.lua
index 6937ca3..e042ab6 100644
--- a/awesome/lain/widget/weather.lua
+++ b/awesome/lain/widget/weather.lua
@@ -5,15 +5,15 @@
--]]
-local helpers = require("lain.helpers")
-local json = require("lain.util").dkjson
-local focused = require("awful.screen").focused
-local naughty = require("naughty")
-local wibox = require("wibox")
-local math = math
-local os = os
-local string = string
-local type = type
+local helpers = require('lain.helpers')
+local json = require('lain.util').dkjson
+local focused = require('awful.screen').focused
+local naughty = require('naughty')
+local wibox = require('wibox')
+local math = math
+local os = os
+local string = string
+local type = type
local tonumber = tonumber
-- OpenWeatherMap
@@ -21,126 +21,131 @@ local tonumber = tonumber
-- lain.widget.weather
local function factory(args)
- args = args or {}
+ args = args or {}
- local weather = { widget = args.widget or wibox.widget.textbox() }
- local APPID = args.APPID -- mandatory
- local timeout = args.timeout or 60 * 15 -- 15 min
- local current_call = args.current_call or "curl -s 'https://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s&APPID=%s'"
- local forecast_call = args.forecast_call or "curl -s 'https://api.openweathermap.org/data/2.5/forecast?id=%s&units=%s&lang=%s&APPID=%s'"
- local city_id = args.city_id or 0 -- placeholder
- local units = args.units or "metric"
- local lang = args.lang or "en"
- local cnt = args.cnt or 5
- local icons_path = args.icons_path or helpers.icons_dir .. "openweathermap/"
- local notification_preset = args.notification_preset or {}
- local notification_text_fun = args.notification_text_fun or
- function (wn)
- local day = os.date("%a %d", wn["dt"])
- local temp = math.floor(wn["main"]["temp"])
- local desc = wn["weather"][1]["description"]
- return string.format("%s: %s, %d ", day, desc, temp)
- end
- local weather_na_markup = args.weather_na_markup or " N/A "
- local followtag = args.followtag or false
- local showpopup = args.showpopup or "on"
- local settings = args.settings or function() end
+ local weather = { widget = args.widget or wibox.widget.textbox() }
+ local APPID = args.APPID -- mandatory
+ local timeout = args.timeout or 60 * 15 -- 15 min
+ local current_call = args.current_call
+ or "curl -s 'https://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s&APPID=%s'"
+ local forecast_call = args.forecast_call
+ or "curl -s 'https://api.openweathermap.org/data/2.5/forecast?id=%s&units=%s&lang=%s&APPID=%s'"
+ local city_id = args.city_id or 0 -- placeholder
+ local units = args.units or 'metric'
+ local lang = args.lang or 'en'
+ local cnt = args.cnt or 5
+ local icons_path = args.icons_path or helpers.icons_dir .. 'openweathermap/'
+ local notification_preset = args.notification_preset or {}
+ local notification_text_fun = args.notification_text_fun
+ or function(wn)
+ local day = os.date('%a %d', wn['dt'])
+ local temp = math.floor(wn['main']['temp'])
+ local desc = wn['weather'][1]['description']
+ return string.format('%s: %s, %d ', day, desc, temp)
+ end
+ local weather_na_markup = args.weather_na_markup or ' N/A '
+ local followtag = args.followtag or false
+ local showpopup = args.showpopup or 'on'
+ local settings = args.settings or function() end
- weather.widget:set_markup(weather_na_markup)
- weather.icon_path = icons_path .. "na.png"
- weather.icon = wibox.widget.imagebox(weather.icon_path)
+ weather.widget:set_markup(weather_na_markup)
+ weather.icon_path = icons_path .. 'na.png'
+ weather.icon = wibox.widget.imagebox(weather.icon_path)
- function weather.show(seconds)
- weather.hide()
+ function weather.show(seconds)
+ weather.hide()
- if followtag then
- notification_preset.screen = focused()
- end
+ if followtag then
+ notification_preset.screen = focused()
+ end
- if not weather.notification_text then
- weather.update()
- weather.forecast_update()
- end
+ if not weather.notification_text then
+ weather.update()
+ weather.forecast_update()
+ end
- weather.notification = naughty.notify {
- preset = notification_preset,
- text = weather.notification_text,
- icon = weather.icon_path,
- timeout = type(seconds) == "number" and seconds or notification_preset.timeout
- }
- end
+ weather.notification = naughty.notify({
+ preset = notification_preset,
+ text = weather.notification_text,
+ icon = weather.icon_path,
+ timeout = type(seconds) == 'number' and seconds or notification_preset.timeout,
+ })
+ end
- function weather.hide()
- if weather.notification then
- naughty.destroy(weather.notification)
- weather.notification = nil
- end
- end
+ function weather.hide()
+ if weather.notification then
+ naughty.destroy(weather.notification)
+ weather.notification = nil
+ end
+ end
- function weather.attach(obj)
- obj:connect_signal("mouse::enter", function()
- weather.show(0)
- end)
- obj:connect_signal("mouse::leave", function()
- weather.hide()
- end)
- end
+ function weather.attach(obj)
+ obj:connect_signal('mouse::enter', function()
+ weather.show(0)
+ end)
+ obj:connect_signal('mouse::leave', function()
+ weather.hide()
+ end)
+ end
- function weather.forecast_update()
- local cmd = string.format(forecast_call, city_id, units, lang, APPID)
- helpers.async(cmd, function(f)
- local err
- weather_now, _, err = json.decode(f, 1, nil)
+ function weather.forecast_update()
+ local cmd = string.format(forecast_call, city_id, units, lang, APPID)
+ helpers.async(cmd, function(f)
+ local err
+ weather_now, _, err = json.decode(f, 1, nil)
- if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
- weather.notification_text = ""
- for i = 1, weather_now["cnt"], math.floor(weather_now["cnt"] / cnt) do
- weather.notification_text = weather.notification_text ..
- notification_text_fun(weather_now["list"][i])
- if i < weather_now["cnt"] then
- weather.notification_text = weather.notification_text .. "\n"
- end
- end
- end
- end)
- end
+ if not err and type(weather_now) == 'table' and tonumber(weather_now['cod']) == 200 then
+ weather.notification_text = ''
+ for i = 1, weather_now['cnt'], math.floor(weather_now['cnt'] / cnt) do
+ weather.notification_text = weather.notification_text
+ .. notification_text_fun(weather_now['list'][i])
+ if i < weather_now['cnt'] then
+ weather.notification_text = weather.notification_text .. '\n'
+ end
+ end
+ end
+ end)
+ end
- function weather.update()
- local cmd = string.format(current_call, city_id, units, lang, APPID)
- helpers.async(cmd, function(f)
- local err
- weather_now, _, err = json.decode(f, 1, nil)
+ function weather.update()
+ local cmd = string.format(current_call, city_id, units, lang, APPID)
+ helpers.async(cmd, function(f)
+ local err
+ weather_now, _, err = json.decode(f, 1, nil)
- if not err and type(weather_now) == "table" and tonumber(weather_now["cod"]) == 200 then
- local sunrise = tonumber(weather_now["sys"]["sunrise"])
- local sunset = tonumber(weather_now["sys"]["sunset"])
- local icon = weather_now["weather"][1]["icon"]
- local loc_now = os.time()
+ if not err and type(weather_now) == 'table' and tonumber(weather_now['cod']) == 200 then
+ local sunrise = tonumber(weather_now['sys']['sunrise'])
+ local sunset = tonumber(weather_now['sys']['sunset'])
+ local icon = weather_now['weather'][1]['icon']
+ local loc_now = os.time()
- if sunrise <= loc_now and loc_now <= sunset then
- icon = string.gsub(icon, "n", "d")
- else
- icon = string.gsub(icon, "d", "n")
- end
+ if sunrise <= loc_now and loc_now <= sunset then
+ icon = string.gsub(icon, 'n', 'd')
+ else
+ icon = string.gsub(icon, 'd', 'n')
+ end
- weather.icon_path = icons_path .. icon .. ".png"
- widget = weather.widget
- settings()
- else
- weather.icon_path = icons_path .. "na.png"
- weather.widget:set_markup(weather_na_markup)
- end
+ weather.icon_path = icons_path .. icon .. '.png'
+ widget = weather.widget
+ settings()
+ else
+ weather.icon_path = icons_path .. 'na.png'
+ weather.widget:set_markup(weather_na_markup)
+ end
- weather.icon:set_image(weather.icon_path)
- end)
- end
+ weather.icon:set_image(weather.icon_path)
+ end)
+ end
- if showpopup == "on" then weather.attach(weather.widget) end
+ if showpopup == 'on' then
+ weather.attach(weather.widget)
+ end
- weather.timer = helpers.newtimer("weather-" .. city_id, timeout, weather.update, false, true)
- weather.timer_forecast = helpers.newtimer("weather_forecast-" .. city_id, timeout, weather.forecast_update, false, true)
+ weather.timer = helpers.newtimer('weather-' .. city_id, timeout, weather.update, false, true)
+ weather.timer_forecast =
+ helpers.newtimer('weather_forecast-' .. city_id, timeout, weather.forecast_update, false, true)
- return weather
+ return weather
end
return factory
diff --git a/awesome/theme.lua b/awesome/theme.lua
index b3810f2..2b0347f 100644
--- a/awesome/theme.lua
+++ b/awesome/theme.lua
@@ -10,13 +10,29 @@ local lain = require('lain')
local awful = require('awful')
local wibox = require('wibox')
local dpi = require('beautiful.xresources').apply_dpi
+local naughty = require('naughty')
+local settings = (function()
+ local status, settings = pcall(function()
+ return dofile(os.getenv('HOME') .. '/.config/awesome/settings.lua')
+ end)
+ if status then
+ return settings
+ else
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = 'Error while parsing settings!',
+ text = settings,
+ })
+ return {}
+ end
+end)()
local os = os
local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
local theme = {}
theme.confdir = os.getenv('HOME') .. '/.config/awesome/'
-theme.wallpaper = os.getenv('HOME') .. '/.config/awesome/wall.png'
+theme.wallpaper = os.getenv('HOME') .. '/.config/awesome/' .. (settings['wallpaper'] or 'wall.png')
theme.font = 'Terminus 8'
theme.menu_bg_normal = '#000000'
theme.menu_bg_focus = '#000000'
@@ -146,29 +162,39 @@ local cpu = lain.widget.cpu({
end,
})
+local optional = {}
+
-- Coretemp
---[[local tempicon = wibox.widget.imagebox(theme.widget_temp)
-local temp = lain.widget.temp({
- settings = function()
- widget:set_markup(markup.fontfg(theme.font, "#f1af5f", coretemp_now .. "°C "))
- end
-})]]
---
+if settings['show_temp'] == true then
+ local tempicon = wibox.widget.imagebox(theme.widget_temp)
+ local temp = lain.widget.temp({
+ settings = function()
+ -- luacheck: globals widget coretemp_now
+ widget:set_markup(markup.fontfg(theme.font, '#f1af5f', coretemp_now .. '°C '))
+ end,
+ })
+ table.insert(optional, tempicon)
+ table.insert(optional, temp)
+end
-- Battery
---[[local baticon = wibox.widget.imagebox(theme.widget_batt)
-local bat = lain.widget.bat({
- settings = function()
- local perc = bat_now.perc ~= "N/A" and bat_now.perc .. "%" or bat_now.perc
+if settings['show_battery'] == true then
+ local baticon = wibox.widget.imagebox(theme.widget_batt)
+ local bat = lain.widget.bat({
+ settings = function()
+ -- luacheck: globals widget bat_now
+ local perc = bat_now.perc ~= 'N/A' and bat_now.perc .. '%' or bat_now.perc
- if bat_now.ac_status == 1 then
- perc = perc .. " plug"
- end
+ if bat_now.ac_status == 1 then
+ perc = perc .. ' plug'
+ end
- widget:set_markup(markup.fontfg(theme.font, theme.fg_normal, perc .. " "))
- end
-})]]
---
+ widget:set_markup(markup.fontfg(theme.font, theme.fg_normal, perc .. ' '))
+ end,
+ })
+ table.insert(optional, baticon)
+ table.insert(optional, bat)
+end
-- ALSA volume
local volicon = wibox.widget.imagebox(theme.widget_vol)
@@ -331,44 +357,43 @@ function theme.at_screen_connect(s)
},
s.mytasklist, -- Middle widget
--nil,
- { -- Right widgets
- layout = wibox.layout.fixed.horizontal,
- wibox.widget.systray(),
- --mailicon,
- --theme.mail.widget,
- {
+ gears.table.join(
+ { -- Right widgets
+ layout = wibox.layout.fixed.horizontal,
+ wibox.widget.systray(),
+ --mailicon,
+ --theme.mail.widget,
{
{
- layout = wibox.layout.fixed.horizontal,
- netdownicon,
- netdowninfo,
- netupicon,
- netupinfo.widget,
+ {
+ layout = wibox.layout.fixed.horizontal,
+ netdownicon,
+ netdowninfo,
+ netupicon,
+ netupinfo.widget,
+ },
+ halign = 'right',
+ widget = wibox.container.place,
},
- halign = 'right',
- widget = wibox.container.place,
+ width = 120,
+ strategy = 'exact',
+ layout = wibox.layout.constraint,
},
- width = 120,
- strategy = 'exact',
- layout = wibox.layout.constraint,
+ volicon,
+ theme.volume.widget,
+ memicon,
+ memory.widget,
+ cpuicon,
+ cpu.widget,
+ fsicon,
+ theme.fs.widget,
},
- volicon,
- theme.volume.widget,
- memicon,
- memory.widget,
- cpuicon,
- cpu.widget,
- fsicon,
- theme.fs.widget,
- --weathericon,
- --theme.weather.widget,
- --tempicon,
- --temp.widget,
- --baticon,
- --bat.widget,
- clockicon,
- mytextclock,
- },
+ optional,
+ {
+ clockicon,
+ mytextclock,
+ }
+ ),
})
end
diff --git a/awesome/wall2.png b/awesome/wall2.png
new file mode 100644
index 0000000..308bebd
Binary files /dev/null and b/awesome/wall2.png differ