diff options
Diffstat (limited to '.config/luastatus-scripts-dwm')
19 files changed, 665 insertions, 0 deletions
diff --git a/.config/luastatus-scripts-dwm/alsa-gauge.lua b/.config/luastatus-scripts-dwm/alsa-gauge.lua new file mode 100644 index 0000000..966e625 --- /dev/null +++ b/.config/luastatus-scripts-dwm/alsa-gauge.lua @@ -0,0 +1,18 @@ +local GAUGE_NCHARS = 10 + +local function mk_gauge(level, full, empty) + local nfull = math.floor(level * GAUGE_NCHARS + 0.5) + return full:rep(nfull) .. empty:rep(GAUGE_NCHARS - nfull) +end + +widget = { + plugin = 'alsa', + cb = function(t) + local level = (t.vol.cur - t.vol.min) / (t.vol.max - t.vol.min) + if t.mute then + return mk_gauge(level, '×', '—') + else + return mk_gauge(level, '●', '○') + end + end, +} diff --git a/.config/luastatus-scripts-dwm/alsa.lua b/.config/luastatus-scripts-dwm/alsa.lua new file mode 100644 index 0000000..054a806 --- /dev/null +++ b/.config/luastatus-scripts-dwm/alsa.lua @@ -0,0 +1,11 @@ +widget = { + plugin = 'alsa', + cb = function(t) + if t.mute then + return '[mute]' + else + local percent = (t.vol.cur - t.vol.min) / (t.vol.max - t.vol.min) * 100 + return string.format('[%3d%%]', math.floor(0.5 + percent)) + end + end, +} diff --git a/.config/luastatus-scripts-dwm/backlight.lua b/.config/luastatus-scripts-dwm/backlight.lua new file mode 100644 index 0000000..37267ed --- /dev/null +++ b/.config/luastatus-scripts-dwm/backlight.lua @@ -0,0 +1,18 @@ +-- Note that this widget only shows backlight level when it changes. +widget = luastatus.require_plugin('backlight-linux').widget{ + cb = function(level) + if level ~= nil then + local brightness = level * 100 + + local icon = "" + if brightness < 30 then + icon = "" + elseif brightness < 70 then + icon = "" + end + + io.write(level * 100) + return string.format(' %s %3.0f%%', icon, brightness) + end + end, +} diff --git a/.config/luastatus-scripts-dwm/battery.lua b/.config/luastatus-scripts-dwm/battery.lua new file mode 100644 index 0000000..377a30e --- /dev/null +++ b/.config/luastatus-scripts-dwm/battery.lua @@ -0,0 +1,53 @@ +widget = luastatus.require_plugin('battery-linux').widget{ + period = 2, + cb = function(t) + icon = "" + if t.status == "Discharging" then + if t.capacity < 10 then + icon = "" + elseif t.capacity < 20 then + icon = "" + elseif t.capacity < 30 then + icon = "" + elseif t.capacity < 40 then + icon = "" + elseif t.capacity < 50 then + icon = "" + elseif t.capacity < 60 then + icon = "" + elseif t.capacity < 70 then + icon = "" + elseif t.capacity < 80 then + icon = "" + elseif t.capacity < 90 then + icon = "" + else + icon = "" + end + else + if t.capacity < 10 then + icon = "" + elseif t.capacity < 20 then + icon = "" + elseif t.capacity < 30 then + icon = "" + elseif t.capacity < 40 then + icon = "" + elseif t.capacity < 50 then + icon = "" + elseif t.capacity < 60 then + icon = "" + elseif t.capacity < 70 then + icon = "" + elseif t.capacity < 80 then + icon = "" + elseif t.capacity < 90 then + icon = "" + else + icon = "" + end + end + + return string.format('%s %3d%% ', icon, t.capacity) + end, +} diff --git a/.config/luastatus-scripts-dwm/bluetooth.lua b/.config/luastatus-scripts-dwm/bluetooth.lua new file mode 100644 index 0000000..baf4b8c --- /dev/null +++ b/.config/luastatus-scripts-dwm/bluetooth.lua @@ -0,0 +1,178 @@ +-- A widget to display currently connected and paired bluetooth devices. +-- To change output format modify reprint_devices function. + +separator = " " + +-- Object paths look like /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX/somethingsomething +function get_device_mac_address(device_object_path) + return device_object_path:gsub("/.*/dev_", ""):gsub("/.*", ""):gsub("_", ":") +end + +-- For reference bluetoothctl devices output looks like that: +-- Device XX:XX:XX:XX:XX:XX JBL T450BT +-- Device YY:YY:YY:YY:YY:YY Redmi 8 +-- +-- Function returns mac addresses of all devices. +function get_devices() + local devices = {} + local handle = io.popen(string.format("bluetoothctl devices")) + for line in handle:lines() do + table.insert(devices, string.match(line, "Device ([%x:]+)")) + end + handle:close() + return devices +end + +function get_power_state() + local handle = io.popen(string.format("bluetoothctl show")) + local power_state = false + for line in handle:lines() do + local state = string.match(line, "^%s*PowerState:%s*(%w+)") + if state then + if state == "off" then + power_state = false + else + power_state = true + end + break + end + end + handle:close() + + return power_state +end + +-- For reference bluetoothctl info output looks like that: +-- Device XX:XX:XX:XX:XX:XX (public) +-- Name: JBL T450BT +-- Alias: JBL T450BT +-- Class: 0xFFFFFFFF +-- Icon: audio-card +-- Paired: yes +-- Trusted: yes +-- Blocked: no +-- Connected: yes +-- LegacyPairing: no +-- UUID: Headset (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) +-- ... +-- UUID: Handsfree (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) +-- +-- Given this input function returns a following table: +-- [alias] string JBL T450BT +-- [blocked] boolean false +-- [class] string 0x00240404 +-- [connected] boolean true +-- [icon] string audio +-- [legacypairing] boolean false +-- [name] string JBL T450BT +-- [paired] boolean true +-- [trusted] boolean true +function get_device_info(mac_address) + if mac_address == nil then + mac_address = "" + end + local device_info = {} + local handle = io.popen(string.format("bluetoothctl info %s", mac_address)) + for line in handle:lines() do + local key, value = string.match(line, "(%w+): (.*)") + -- Filter junk + if key ~= "UUID" and key ~= nil and value ~= nil then + key = string.lower(key) + if key ~= "name" and key ~= "alias" and key ~= "icon" then + if value == "yes" then + value = true + end + if value == "no" then + value = false + end + end + device_info[key] = value + end + end + handle:close() + return device_info +end + +devices = {} + +function reprint_devices(power_state) + if power_state then + local t = {} + for mac_address, device in pairs(devices) do + -- table.insert(t, string.format(" %s", device["alias"])) + return " " + end + if next(t) == nil then + return "" + else + return table.concat(t, separator) + end + else + return "" + end +end + +widget = { + plugin = "dbus", + opts = { + greet = true, + -- https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt + signals = { + { + sender = "org.bluez", + interface = "org.freedesktop.DBus.Properties", + signal = "PropertiesChanged", + arg0 = "org.bluez.Device1", + bus = "system" + }, { + sender = "org.bluez", + interface = "org.freedesktop.DBus.Properties", + signal = "PropertiesChanged", + arg0 = "org.bluez.Adapter1", + bus = "system" + } + } + }, + cb = function(t) + local power_state = false + if t.what == "hello" then + power_state = get_power_state() + local mac_addresses = get_devices() + for i, mac_address in pairs(mac_addresses) do + local device = get_device_info(mac_address) + if device["connected"] and device["paired"] then + devices[mac_address] = device + end + end + elseif t.what == "signal" then + -- For reference message from dbus looks like that: + -- table + -- [1] string org.bluez.Device1 + -- [2] table + -- [2] [1] table + -- [2] [1] [1] string SomethingSomething + -- [2] [1] [2] boolean false + -- [2] [2] table + -- [2] [2] [1] string Connected + -- [2] [2] [2] boolean true + -- [3] table + if t.signal == "PropertiesChanged" then + power_state = get_power_state() + for i, message in pairs(t.parameters[2]) do + if message[1] == "Connected" or message[1] == "Paired" then + local mac_address = get_device_mac_address(t.object_path) + if message[2] then + local device = get_device_info(mac_address) + if device["paired"] then + devices[mac_address] = device + end + else + devices[mac_address] = nil + end + end + end + end + end + return " " .. reprint_devices(power_state) + end +} diff --git a/.config/luastatus-scripts-dwm/cpu-temperature.lua b/.config/luastatus-scripts-dwm/cpu-temperature.lua new file mode 100644 index 0000000..38b25d0 --- /dev/null +++ b/.config/luastatus-scripts-dwm/cpu-temperature.lua @@ -0,0 +1,45 @@ +paths = {} +do + -- Replace "*" with "[^0]*" in the first glob if your zeroeth thermal sensor is virtual (and + -- thus useless): + local f = assert(io.popen([[ + #for file in /sys/class/thermal/thermal_zone*/temp + #do + # [ -e "$file" ] || break + # printf "%s\n" "$file" + #done +for dir in /sys/class/hwmon/* +do + [ -e "$dir" ] || break + IFS= read -r monitor_name < "$dir"/name + # You may have more than one hardware monitor enabled + # If so, disable ones that are not needed + case "$monitor_name" in + coretemp|fam15h_power|k10temp) + printf "%s\n" "$dir"/temp*_input + esac +done +]])) + for p in f:lines() do + table.insert(paths, p) + end + f:close() +end + +widget = { + plugin = 'timer', + opts = {period = 2}, + cb = function() + for _, p in ipairs(paths) do + local f = assert(io.open(p, 'r')) + local temp = f:read('*number') / 1000 + local icon = "" + if temp > 55 then + icon = "" + elseif temp > 80 then + icon = "" + end + return string.format('%s %.0f°C', icon, temp) + end + end, +} diff --git a/.config/luastatus-scripts-dwm/cpu-usage.lua b/.config/luastatus-scripts-dwm/cpu-usage.lua new file mode 100644 index 0000000..90c75ed --- /dev/null +++ b/.config/luastatus-scripts-dwm/cpu-usage.lua @@ -0,0 +1,7 @@ +widget = luastatus.require_plugin('cpu-usage-linux').widget{ + cb = function(usage) + if usage ~= nil then + return string.format('%5.1f%%', usage * 100) + end + end, +} diff --git a/.config/luastatus-scripts-dwm/file-contents.lua b/.config/luastatus-scripts-dwm/file-contents.lua new file mode 100644 index 0000000..1ed02ac --- /dev/null +++ b/.config/luastatus-scripts-dwm/file-contents.lua @@ -0,0 +1,7 @@ +widget = luastatus.require_plugin('file-contents-linux').widget{ + filename = "/tmp/bar_status", + cb = function(f) + -- show the first line of the file + return string.format(" %s", f:read('*line')) + end, +} diff --git a/.config/luastatus-scripts-dwm/fs.lua b/.config/luastatus-scripts-dwm/fs.lua new file mode 100644 index 0000000..e780dc6 --- /dev/null +++ b/.config/luastatus-scripts-dwm/fs.lua @@ -0,0 +1,14 @@ +widget = { + plugin = 'fs', + opts = { + paths = {'/', '/home'}, + }, + cb = function(t) + local res = {} + for k, v in pairs(t) do + table.insert(res, string.format('%s %.0f%%', k, + (1 - v.avail / v.total) * 100)) + end + return res + end, +} diff --git a/.config/luastatus-scripts-dwm/ip.lua b/.config/luastatus-scripts-dwm/ip.lua new file mode 100644 index 0000000..37bc43a --- /dev/null +++ b/.config/luastatus-scripts-dwm/ip.lua @@ -0,0 +1,20 @@ +widget = { + plugin = 'network-linux', + cb = function(t) + local r = {} + for iface, params in pairs(t) do + local addr = params.ipv4 + if addr then + -- strip out "label" from the interface name + iface = iface:gsub(':.*', '') + -- strip out "zone index" from the address + addr = addr:gsub('%%.*', '') + + if iface ~= 'lo' then + r[#r + 1] = string.format('[%s: %s]', iface, addr) + end + end + end + return r + end, +} diff --git a/.config/luastatus-scripts-dwm/mem-usage.lua b/.config/luastatus-scripts-dwm/mem-usage.lua new file mode 100644 index 0000000..1c34219 --- /dev/null +++ b/.config/luastatus-scripts-dwm/mem-usage.lua @@ -0,0 +1,7 @@ +widget = luastatus.require_plugin('mem-usage-linux').widget{ + timer_opts = {period = 2}, + cb = function(t) + local used_kb = t.total.value - t.avail.value + return string.format(' %3.2f GiB ', used_kb / 1024 / 1024) + end, +} diff --git a/.config/luastatus-scripts-dwm/mpd.lua b/.config/luastatus-scripts-dwm/mpd.lua new file mode 100644 index 0000000..32cddc6 --- /dev/null +++ b/.config/luastatus-scripts-dwm/mpd.lua @@ -0,0 +1,32 @@ +-- you need to install 'utf8' module (e.g. with luarocks) if using Lua <=5.2. +utf8 = require 'utf8' + +titlewidth = 40 + +widget = { + plugin = 'mpd', + cb = function(t) + if t.what == 'update' then + local title + if t.song.Title then + title = t.song.Title + if t.song.Artist then + title = t.song.Artist .. ': ' .. title + end + else + title = t.song.file or '' + end + title = (utf8.len(title) <= titlewidth) + and title + or utf8.sub(title, 1, titlewidth - 1) .. '…' + + return string.format('%s %s', + ({play = '▶', pause = '‖', stop = '■'})[t.status.state], + title + ) + else + -- 'connecting' or 'error' + return t.what + end + end +} diff --git a/.config/luastatus-scripts-dwm/network.lua b/.config/luastatus-scripts-dwm/network.lua new file mode 100644 index 0000000..4ec808a --- /dev/null +++ b/.config/luastatus-scripts-dwm/network.lua @@ -0,0 +1,72 @@ +local MIN_DBM, MAX_DBM = -90, -20 +local NGAUGE = 5 +local COLOR_DIM = '#709080' + +local function round(x) + return math.floor(x + 0.5) +end + +local function make_wifi_gauge(dbm) + if dbm < MIN_DBM then dbm = MIN_DBM end + if dbm > MAX_DBM then dbm = MAX_DBM end + local nbright = round(NGAUGE * (1 - 0.7 * (MAX_DBM - dbm) / (MAX_DBM - MIN_DBM))) + + if nbright == 0 then + return "" + elseif nbright == 1 then + return "" + elseif nbright == 2 then + return "" + elseif nbright == 3 then + return "" + elseif nbright == 4 then + return "" + else + return "" + end +end + +widget = { + plugin = 'network-linux', + opts = { + wireless = true, + timeout = 10, + }, + cb = function(t) + if not t then + return nil + end + + local x = "" + local sep = " " + + if t.eno1 then + if t.eno1.ipv4 or t.eno1.ipv6 then + x = "" + end + end + + if t.enp5s0f3u1 then + if x ~= "" then + x = x .. sep + end + if t.enp5s0f3u1.ipv4 or t.enp5s0f3u1.ipv6 then + x = x .. "" + end + end + + if t.wlo1.wireless then + if x ~= "" then + x = x .. sep + end + if t.wlo1.wireless.signal_dbm then + x = x .. make_wifi_gauge(t.wlo1.wireless.signal_dbm) + else + x = x .. "" + end + end + + x = " " .. x .. " " + return x + end, +} diff --git a/.config/luastatus-scripts-dwm/pulse-gauge.lua b/.config/luastatus-scripts-dwm/pulse-gauge.lua new file mode 100644 index 0000000..dbc5c67 --- /dev/null +++ b/.config/luastatus-scripts-dwm/pulse-gauge.lua @@ -0,0 +1,18 @@ +local GAUGE_NCHARS = 10 + +local function mk_gauge(level, full, empty) + local nfull = math.floor(level * GAUGE_NCHARS + 0.5) + return full:rep(nfull) .. empty:rep(GAUGE_NCHARS - nfull) +end + +widget = { + plugin = 'pulse', + cb = function(t) + local level = t.cur / t.norm + if t.mute then + return mk_gauge(level, '×', '—') + else + return mk_gauge(level, '●', '○') + end + end, +} diff --git a/.config/luastatus-scripts-dwm/pulse.lua b/.config/luastatus-scripts-dwm/pulse.lua new file mode 100644 index 0000000..59b73e8 --- /dev/null +++ b/.config/luastatus-scripts-dwm/pulse.lua @@ -0,0 +1,10 @@ +widget = { + plugin = 'pulse', + cb = function(t) + if t.mute then + return '[mute]' + end + local percent = (t.cur / t.norm) * 100 + return string.format('[%3d%%]', math.floor(0.5 + percent)) + end, +} diff --git a/.config/luastatus-scripts-dwm/time-date.lua b/.config/luastatus-scripts-dwm/time-date.lua new file mode 100644 index 0000000..8fce7a1 --- /dev/null +++ b/.config/luastatus-scripts-dwm/time-date.lua @@ -0,0 +1,58 @@ +months = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'} +wday = {'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'} +widget = { + plugin = 'timer', + cb = function() + local d = os.date('*t') + + if d.hour < 12 then + suffix = "a.m." + else + suffix = "p.m." + d.hour = d.hour - 12 + end + + local date_suffix = "th" + if not (d.day % 100 >= 11 and d.day % 100 <= 13) then + local last_digit = d.day % 10 + if last_digit == 1 then + date_suffix = "st" + elseif last_digit == 2 then + date_suffix = "nd" + elseif last_digit == 3 then + date_suffix = "rd" + end + end + + local time_icon = "" + if d.hour == 0 or d.hour == 12 then + time_icon = "" + elseif d.hour == 1 then + time_icon = "" + elseif d.hour == 2 then + time_icon = "" + elseif d.hour == 3 then + time_icon = "" + elseif d.hour == 4 then + time_icon = "" + elseif d.hour == 5 then + time_icon = "" + elseif d.hour == 6 then + time_icon = "" + elseif d.hour == 7 then + time_icon = "" + elseif d.hour == 8 then + time_icon = "" + elseif d.hour == 9 then + time_icon = "" + elseif d.hour == 10 then + time_icon = "" + elseif d.hour == 11 then + time_icon = "" + end + + return { + string.format(' %d%s %s %d (%s) %s %d:%02d %s ', d.day, date_suffix, months[d.month], d.year, wday[d.wday], time_icon, d.hour, d.min, suffix), + } + end, +} diff --git a/.config/luastatus-scripts-dwm/tor.lua b/.config/luastatus-scripts-dwm/tor.lua new file mode 100644 index 0000000..db97225 --- /dev/null +++ b/.config/luastatus-scripts-dwm/tor.lua @@ -0,0 +1,13 @@ +-- Trivial but somewhat useful widget showing if the Tor daemon is running. + +widget = { + plugin = 'timer', + opts = {period = 5}, + cb = function() + local f = io.open('/var/run/tor/tor.pid', 'r') + if f then + f:close() + return '[TOR]' + end + end, +} diff --git a/.config/luastatus-scripts-dwm/weather.lua b/.config/luastatus-scripts-dwm/weather.lua new file mode 100644 index 0000000..d626689 --- /dev/null +++ b/.config/luastatus-scripts-dwm/weather.lua @@ -0,0 +1,67 @@ +-- you need to install 'luasec' module (e.g. with luarocks) +-- you can look up all available flags here: https://github.com/chubin/wttr.in#one-line-output + +local https = require('ssl.https') +local ltn12 = require('ltn12') + +-- All the arguments except for 'url' may be absent or nil; default method is GET. +-- Returns: code (integer), body (string), headers (table), status (string). +function request(url, headers, method, body) + local out_body = {} + local is_ok, code_or_errmsg, out_headers, status = https.request( + { + url = url, + sink = ltn12.sink.table(out_body), + redirect = false, + cafile = '/etc/ssl/certs/ca-certificates.crt', + verify = 'peer', + method = method, + headers = headers, + }, + body) + assert(is_ok, code_or_errmsg) + return code_or_errmsg, table.concat(out_body), out_headers, status +end + +-- Arguments are the same to those of 'request'. +-- Returns: body (string), headers (table). +function request_check_code(...) + local code, body, headers, status = request(...) + assert(code == 200, string.format('HTTP %s %s', code, status)) + return body, headers +end + +function urlencode(s) + return string.gsub(s, '[^-_.~a-zA-Z0-9]', function(c) + return string.format('%%%02X', string.byte(c)) + end) +end + +local BASE_URL = 'wttr.in' +local LANG = 'en' +local LOCATION = '' + +function get_weather(format) + -- encoding is needed to allow usage of special use characters + format = urlencode(format) + local url = string.format('https://%s.%s/%s?format=%s', LANG, BASE_URL, LOCATION, format) + local is_ok, body = pcall(request_check_code, url) + if is_ok then + return body:gsub("\n", "") + else + return nil + end +end + +widget = { + plugin = 'timer', + opts = {period = 15 * 60}, + cb = function() + local text = get_weather('%l: %C %t(%f)') + if text == nil then + luastatus.plugin.push_period(60) -- retry in 60 seconds + text = '......' + end + return text + end, +} diff --git a/.config/luastatus-scripts-dwm/xkb.lua b/.config/luastatus-scripts-dwm/xkb.lua new file mode 100644 index 0000000..358f0d7 --- /dev/null +++ b/.config/luastatus-scripts-dwm/xkb.lua @@ -0,0 +1,17 @@ +widget = { + plugin = 'xkb', + cb = function(t) + if t.name then + local base_layout = t.name:match('[^(]+') + if base_layout == 'gb' or base_layout == 'us' then + return '[En]' + elseif base_layout == 'ru' then + return '[Ru]' + else + return '[' .. base_layout:sub(1, 1):upper() .. base_layout:sub(2) .. ']' + end + else + return '[? ID ' .. t.id .. ']' + end + end, +} |