diff --git a/config/awesome/dpmsstatus.lua b/config/awesome/dpmsstatus.lua
new file mode 100644
index 0000000..7d37038
--- /dev/null
+++ b/config/awesome/dpmsstatus.lua
@@ -0,0 +1,24 @@
+-- {{{ Grab environment
+local setmetatable = setmetatable
+-- }}}
+
+
+local temp = {};
+
+-- {{{ Date widget type
+local function worker(format, warg)
+
+ local f = io.popen("xset q | grep 'DPMS is' | awk '/ / {print $3}'")
+
+ temp[0] = "";
+ for line in f:lines() do
+ temp[0] = temp[0] .. line
+ end
+
+ io.close(f)
+
+ return temp
+end
+-- }}}
+
+return setmetatable(temp, { __call = function(_, ...) return worker(...) end })
diff --git a/config/awesome/gputemp.lua b/config/awesome/gputemp.lua
new file mode 100644
index 0000000..59585ca
--- /dev/null
+++ b/config/awesome/gputemp.lua
@@ -0,0 +1,23 @@
+-- {{{ Grab environment
+local setmetatable = setmetatable
+-- }}}
+
+local temp = {};
+
+-- {{{ Date widget type
+local function worker(format, warg)
+
+ local f = io.popen("gputemp.py")
+
+ temp[0] = "";
+ for line in f:lines() do
+ temp[0] = temp[0] .. line
+ end
+
+ io.close(f)
+
+ return temp
+end
+-- }}}
+
+return setmetatable(temp, { __call = function(_, ...) return worker(...) end })
diff --git a/config/awesome/hubic.lua b/config/awesome/hubic.lua
new file mode 100644
index 0000000..50b01d9
--- /dev/null
+++ b/config/awesome/hubic.lua
@@ -0,0 +1,23 @@
+-- {{{ Grab environment
+local setmetatable = setmetatable
+-- }}}
+
+local temp = {};
+
+-- {{{ Date widget type
+local function worker(format, warg)
+
+ local f = io.popen("hubic.py")
+
+ temp[0] = "";
+ for line in f:lines() do
+ temp[0] = temp[0] .. line
+ end
+
+ io.close(f)
+
+ return temp
+end
+-- }}}
+
+return setmetatable(temp, { __call = function(_, ...) return worker(...) end })
diff --git a/config/awesome/lanxu/README.md b/config/awesome/lanxu/README.md
new file mode 100644
index 0000000..8eb3628
--- /dev/null
+++ b/config/awesome/lanxu/README.md
@@ -0,0 +1,35 @@
+lanxu awesome scripts
+=====================
+
+Requirements
+------------
+
+- dkjson (for parsing json. Available with this widget)
+
+How to use
+----------
+You may create your widget like this:
+
+~~~lua
+local mcstatus = require("lanxu/mcstatus")
+myserverstatus = mcstatus({
+ settings = function()
+ widget.markup = "PLAYERS " .. totalplayers .. ""
+ end
+})
+~~~
+
+After this you can use "myserverstatus" like any other textbox widget
+
+full list of available settings below
+
+~~~lua
+myserverstatus = mcstatus({
+ hideempty = false,
+ hideoffline = true,
+ calluri = "https://page.not.found/mc_stats.php?type=server_status",
+ settings = function()
+ widget.markup = "PLAYERS " .. totalplayers .. ""
+ end
+})
+~~~
diff --git a/config/awesome/lanxu/cloudstatus.lua b/config/awesome/lanxu/cloudstatus.lua
new file mode 100644
index 0000000..ce5b585
--- /dev/null
+++ b/config/awesome/lanxu/cloudstatus.lua
@@ -0,0 +1,80 @@
+local naughty = require("naughty")
+local wibox = require("wibox")
+local gears = require("gears")
+local focused = require("awful.screen").focused
+local easy_async = require("awful.spawn").easy_async
+
+local function factory(args)
+ local args = args or {}
+ local timeout = args.timeout or 5
+ local status_cmd = args.status_cmd or "hubic status"
+ local full_cmd = args.full_cmd or "hubic status"
+ local cloud = { widget = wibox.widget.textbox() }
+ local settings = args.settings or function() end
+ local followtag = args.followtag or true
+ local notification_preset = args.notification_preset or { font = "Monospace 10" }
+
+ cloud.widget:set_markup("N/A")
+
+ function cloud.show(tout)
+ cloud.hide()
+
+ if followtag then
+ notification_preset.screen = focused()
+ end
+
+ cloud.notification = naughty.notify({
+ text = cloud.notification_text,
+ -- icon = cloud.icon
+ timeout = 0,
+ preset = notification_preset,
+ })
+ end
+
+ function cloud.hide()
+ if cloud.notification then
+ naughty.destroy(cloud.notification)
+ end
+ end
+
+ function cloud.attach(obj)
+ obj:connect_signal("mouse::enter", function()
+ cloud.show()
+ end)
+
+ obj:connect_signal("mouse::leave", function()
+ cloud.hide()
+ end)
+
+ obj:connect_signal("button::press", function()
+ cloud.update()
+ cloud.show()
+ end)
+ end
+
+ function cloud.update()
+ local cmd = string.format(full_cmd)
+ easy_async(cmd, function(response, stderr, reason, exit_code)
+ local res = string.match(response, 'State: (.-)Up')
+ res = res:gsub("%s+", "")
+ res = string.gsub(res, "%s+", "")
+ currentstatus = res or "No"
+ cloud.notification_text = response
+ widget = cloud.widget
+ settings()
+ end)
+ end
+
+ cloud.attach(cloud.widget)
+ gears.timer {
+ timeout = timeout,
+ autostart = true,
+ callback = cloud.update
+ }
+
+ cloud.update()
+
+ return cloud
+end
+
+return factory
diff --git a/config/awesome/lanxu/dkjson.lua b/config/awesome/lanxu/dkjson.lua
new file mode 100644
index 0000000..fa50b9f
--- /dev/null
+++ b/config/awesome/lanxu/dkjson.lua
@@ -0,0 +1,714 @@
+-- Module options:
+local always_try_using_lpeg = true
+local register_global_module_table = false
+local global_module_name = 'json'
+
+--[==[
+
+David Kolf's JSON module for Lua 5.1/5.2
+
+Version 2.5
+
+
+For the documentation see the corresponding readme.txt or visit
+.
+
+You can contact the author by sending an e-mail to 'david' at the
+domain 'dkolf.de'.
+
+
+Copyright (C) 2010-2013 David Heiko Kolf
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+--]==]
+
+-- global dependencies:
+local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset =
+ pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset
+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
+local strmatch = string.match
+local concat = table.concat
+
+local json = { version = "dkjson 2.5" }
+
+if register_global_module_table then
+ _G[global_module_name] = json
+end
+
+local _ENV = nil -- blocking globals in Lua 5.2
+
+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
+})
+
+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"
+}
+
+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
+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 .. "\""
+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
+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") .. "]+"
+end
+
+updatedecpoint()
+
+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
+end
+
+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
+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)
+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
+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
+end
+
+function json.encodeexception(reason, value, state, defaultmessage)
+ return quotestring("<" .. defaultmessage .. ">")
+end
+
+encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state)
+ local valtype = type (value)
+ local valmeta = getmetatable (value)
+ valmeta = type (valmeta) == 'table' and valmeta -- only tables
+ 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 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
+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)
+end
+
+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
+end
+
+local escapechars = {
+ ["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["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
+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 len = strlen (str)
+ 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
+end
+
+local function optionalmetatables(...)
+ 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)
+end
+
+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
+
+ 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 Err (msg)
+ return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall)
+ 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 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"\"" + Err "unterminated 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 npos
+ local t, nt = {}, 0
+ repeat
+ obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state)
+ if not npos then break end
+ pos = npos
+ nt = nt + 1
+ t[nt] = obj
+ until cont == 'last'
+ return pos, setmetatable (t, state.arraymeta)
+ end
+
+ local function parseobject (str, pos, nullval, state)
+ local obj, key, cont
+ local npos
+ local t = {}
+ repeat
+ key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state)
+ if not npos then break end
+ pos = npos
+ t[key] = obj
+ until cont == 'last'
+ return pos, setmetatable (t, state.objectmeta)
+ end
+
+ local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected")
+ local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected")
+ local Value = Space * (Array + Object + SimpleValue)
+ local ExpectedValue = Value + Space * Err "value expected"
+ ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
+ local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue)
+ ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp()
+ local DecodeValue = ExpectedValue * g.Cp ()
+
+ function json.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
+
+ -- use this function only once:
+ json.use_lpeg = function () return json end
+
+ json.using_lpeg = true
+
+ return json -- so you can get the module using json = require "dkjson".use_lpeg()
+end
+
+if always_try_using_lpeg then
+ pcall (json.use_lpeg)
+end
+
+return json
+
diff --git a/config/awesome/lanxu/ip.lua b/config/awesome/lanxu/ip.lua
new file mode 100644
index 0000000..0a4fcb2
--- /dev/null
+++ b/config/awesome/lanxu/ip.lua
@@ -0,0 +1,53 @@
+local naughty = require("naughty")
+local wibox = require("wibox")
+local json = require("lanxu/dkjson")
+local gears = require("gears")
+local focused = require("awful.screen").focused
+local easy_async = require("awful.spawn").easy_async
+
+local function factory(args)
+ local args = args or {}
+ local calluri = args.uri or "https://api.ipify.org"
+ local settings = args.settings or function() end
+ local homeaddress = args.homeaddress or nil
+
+ local ip = { widget = wibox.widget.textbox() }
+ ip.widget:set_markup("N/A")
+
+ function ip.attach(obj)
+ obj:connect_signal("button::press", function()
+ ip.update()
+ end)
+ end
+
+ function ip.update()
+ local cmd = string.format("curl -s " .. "'" .. calluri .. "'")
+
+ address = "N/A"
+ settings()
+
+ easy_async(cmd, function(response, stderr, reason, exit_code)
+ address = response
+ address = string.gsub(address, "[^0-9.]", "")
+ if address == homeaddress then
+ address = "Home"
+ end
+
+ ip.address = address
+ widget = ip.widget
+
+ settings()
+ end)
+ end
+
+ ip.attach(ip.widget)
+
+ address = "N/A"
+ settings()
+
+ ip.update()
+
+ return ip
+end
+
+return factory
diff --git a/config/awesome/lanxu/mcstatus.lua b/config/awesome/lanxu/mcstatus.lua
new file mode 100644
index 0000000..ba4afbc
--- /dev/null
+++ b/config/awesome/lanxu/mcstatus.lua
@@ -0,0 +1,116 @@
+local naughty = require("naughty")
+local wibox = require("wibox")
+local json = require("lanxu/dkjson")
+local gears = require("gears")
+local focused = require("awful.screen").focused
+local easy_async = require("awful.spawn").easy_async
+
+local function factory(args)
+ local args = args or {}
+ local timeout = args.timeout or 600
+ local calluri = args.uri or "https://masa.dy.fi/api/games/stats/minecraft/?type=server_status"
+ local minecraft = { widget = wibox.widget.textbox() }
+ local settings = args.settings or function() end
+ local hideempty = args.hideempty or false
+ local hideoffline = args.hideoffline or true
+ local followtag = args.followtag or true
+ local notification_preset = args.notification_preset or { font = "Monospace 10" }
+
+ minecraft.widget:set_markup("N/A")
+
+ function minecraft.show(tout)
+ minecraft.hide()
+
+ if followtag then
+ notification_preset.screen = focused()
+ end
+
+ minecraft.notification = naughty.notify({
+ text = minecraft.notification_text,
+ -- icon = minecraft.icon
+ timeout = 0,
+ preset = notification_preset,
+ })
+ end
+
+ function minecraft.hide()
+ if minecraft.notification then
+ naughty.destroy(minecraft.notification)
+ end
+ end
+
+ function minecraft.attach(obj)
+ obj:connect_signal("mouse::enter", function()
+ minecraft.show()
+ end)
+
+ obj:connect_signal("mouse::leave", function()
+ minecraft.hide()
+ end)
+
+ obj:connect_signal("button::press", function()
+ minecraft.update()
+ minecraft.show()
+ end)
+ end
+
+ function minecraft.update()
+ local cmd = string.format("curl -s " .. "'" .. calluri .. "'")
+
+ easy_async(cmd, function(response, stderr, reason, exit_code)
+ local obj, pos, err = json.decode(response, 1, nil)
+
+ totalplayers = 0
+
+ if not err then
+ -- First get the length of the longest server name, for proper column alignment
+ local max_len = 6 -- Initialize to the length of "Server"
+ for k, v in pairs(obj) do
+ if (tonumber(v.num_players) > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
+ local tmp = string.len(v.server_name)
+ if tmp > max_len then
+ max_len = tmp
+ end
+ end
+ end
+
+ local fmt = string.format("%%-%ds %%-8s %%-7s\n", max_len)
+ local text = string.format(fmt, "Server", "Version", "Players")
+
+ for k, v in pairs(obj) do
+ local players = tonumber(v.num_players)
+
+ if (players > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
+ text = text .. string.format(fmt, v.server_name, v.version, v.num_players)
+
+ if v.players then
+ for i, p in pairs(v.players) do
+ text = text .. ' > ' .. p .. '\n'
+ end
+ end
+ end
+
+ totalplayers = totalplayers + players
+ end
+
+ minecraft.notification_text = text
+ minecraft.totalplayers = totalplayers;
+ widget = minecraft.widget
+ settings()
+ end
+ end)
+ end
+
+ minecraft.attach(minecraft.widget)
+ gears.timer {
+ timeout = timeout,
+ autostart = true,
+ callback = minecraft.update
+ }
+
+ minecraft.update()
+
+ return minecraft
+end
+
+return factory
diff --git a/config/awesome/lanxu/mcstatustest.lua b/config/awesome/lanxu/mcstatustest.lua
new file mode 100644
index 0000000..4359f3f
--- /dev/null
+++ b/config/awesome/lanxu/mcstatustest.lua
@@ -0,0 +1,23 @@
+local json = require ("dkjson")
+local https = require("ssl.https")
+local url = "https://masa.dy.fi/~masa/testailu/mc_stats_dev/dev_json.php?type=server_status"
+local response, error = https.request(url)
+
+local obj, pos, err = json.decode (response, 1, nil)
+
+local text = ""
+for k, v in pairs(obj) do
+ text = text .. v.status .. "\t"
+ text = text .. v.version .. "\t"
+ text = text .. v.num_players .. "\t"
+ text = text .. v.server_name .. "\t"
+ text = text .. "\n"
+ if v.players then
+ for i, p in pairs(v.players) do
+ text = text .. '\t\t' .. p .. '\n'
+ end
+ end
+end
+
+print(text)
+
diff --git a/config/awesome/rc.lua b/config/awesome/rc.lua
new file mode 100644
index 0000000..da14620
--- /dev/null
+++ b/config/awesome/rc.lua
@@ -0,0 +1,774 @@
+-- Standard awesome library
+local gears = require("gears")
+local awful = require("awful")
+require("awful.autofocus")
+-- Widget and layout library
+local wibox = require("wibox")
+-- Theme handling library
+local beautiful = require("beautiful")
+-- Notification library
+local naughty = require("naughty")
+local menubar = require("menubar")
+local hotkeys_popup = require("awful.hotkeys_popup").widget
+local lain = require("lain")
+
+naughty.config.defaults.timeout = 5
+naughty.config.defaults.screen = 1
+naughty.config.defaults.position = "top_right"
+naughty.config.defaults.margin = 8
+naughty.config.defaults.gap = 1
+naughty.config.defaults.ontop = true
+naughty.config.defaults.font = "sans 8"
+naughty.config.defaults.icon = "/usr/share/icons/Adwaita/48x48/status/dialog-information.png"
+naughty.config.defaults.icon_size = 48
+naughty.config.defaults.fg = beautiful.fg_tooltip
+naughty.config.defaults.bg = beautiful.bg_tooltip
+naughty.config.defaults.border_color = beautiful.border_tooltip
+naughty.config.defaults.border_width = 1
+naughty.config.defaults.hover_timeout = nil
+
+-- {{{ Error handling
+-- Check if awesome encountered an error during startup and fell back to
+-- another config (This code will only ever execute for the fallback config)
+if awesome.startup_errors then
+ naughty.notify({ preset = naughty.config.presets.critical,
+ title = "Oops, there were errors during startup!",
+ text = awesome.startup_errors })
+end
+
+-- Handle runtime errors after startup
+do
+ local in_error = false
+ awesome.connect_signal("debug::error", function (err)
+ -- Make sure we don't go into an endless error loop
+ if in_error then return end
+ in_error = true
+
+ naughty.notify({ preset = naughty.config.presets.critical,
+ title = "Oops, an error happened!",
+ text = tostring(err) })
+ in_error = false
+ end)
+end
+-- }}}
+
+-- {{{ Variable definitions
+-- Themes define colours, icons, font and wallpapers.
+beautiful.init(awful.util.getdir("config") .. "/themes/lanxu/theme.lua")
+
+local widgets = require("widgets");
+
+-- This is used later as the default terminal and editor to run.
+terminal = "termite"
+editor = os.getenv("EDITOR") or "vim"
+editor_cmd = terminal .. " -e " .. editor
+
+-- Default modkey.
+-- Usually, Mod4 is the key with a logo between Control and Alt.
+-- If you do not like this or do not have such a key,
+-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
+-- However, you can use another modifier like Mod1, but it may interact with others.
+modkey = "Mod4"
+
+-- Table of layouts to cover with awful.layout.inc, order matters.
+awful.layout.layouts = {
+ awful.layout.suit.floating,
+ awful.layout.suit.tile,
+ awful.layout.suit.tile.left,
+ awful.layout.suit.tile.bottom,
+ awful.layout.suit.tile.top,
+ awful.layout.suit.fair,
+ awful.layout.suit.fair.horizontal,
+ awful.layout.suit.spiral,
+ awful.layout.suit.spiral.dwindle,
+ awful.layout.suit.max,
+ awful.layout.suit.max.fullscreen,
+ awful.layout.suit.magnifier,
+ awful.layout.suit.corner.nw,
+ -- awful.layout.suit.corner.ne,
+ -- awful.layout.suit.corner.sw,
+ -- awful.layout.suit.corner.se,
+}
+-- }}}
+
+-- {{{ Helper functions
+local function client_menu_toggle_fn()
+ local instance = nil
+
+ return function ()
+ if instance and instance.wibox.visible then
+ instance:hide()
+ instance = nil
+ else
+ instance = awful.menu.clients({ theme = { width = 250 } })
+ end
+ end
+end
+-- }}}
+
+-- {{{ Menu
+-- Create a launcher widget and a main menu
+myawesomemenu = {
+ { "hotkeys", function() return false, hotkeys_popup.show_help end},
+ { "manual", terminal .. " -e man awesome" },
+ { "edit config", editor_cmd .. " " .. awesome.conffile },
+ { "restart", awesome.restart },
+ { "quit", function() awesome.quit() end}
+}
+lock = function()
+ -- Sync disks before lock (just in case)
+ awful.util.spawn("sync")
+
+ -- Lock screen
+ awful.util.spawn("xdg-screensaver lock")
+ --awful.util.spawn("xautolock -locknow")
+ --awful.util.spawn("xlock")
+end
+mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
+ { "open terminal", terminal },
+ { "lock", lock},
+ { "suspend", "systemctl suspend"}
+ }
+ })
+
+mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
+ menu = mymainmenu })
+
+-- Menubar configuration
+menubar.utils.terminal = terminal -- Set the terminal for applications that require it
+-- }}}
+
+-- Keyboard map indicator and switcher
+mykeyboardlayout = awful.widget.keyboardlayout()
+
+-- {{{ Wibar
+-- Create a textclock widget
+--mytextclock = wibox.widget.textclock()
+
+-- Create a wibox for each screen and add it
+local taglist_buttons = awful.util.table.join(
+ awful.button({ }, 1, function(t) t:view_only() end),
+ awful.button({ modkey }, 1, function(t)
+ if client.focus then
+ client.focus:move_to_tag(t)
+ end
+ end),
+ awful.button({ }, 3, awful.tag.viewtoggle),
+ awful.button({ modkey }, 3, function(t)
+ if client.focus then
+ client.focus:toggle_tag(t)
+ end
+ end),
+ awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
+ awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
+ )
+
+local tasklist_buttons = awful.util.table.join(
+ awful.button({ }, 1, function (c)
+ if c == client.focus then
+ c.minimized = true
+ else
+ -- Without this, the following
+ -- :isvisible() makes no sense
+ c.minimized = false
+ if not c:isvisible() and c.first_tag then
+ c.first_tag:view_only()
+ end
+ -- This will also un-minimize
+ -- the client, if needed
+ client.focus = c
+ c:raise()
+ end
+ end),
+ awful.button({ }, 3, client_menu_toggle_fn()),
+ awful.button({ }, 4, function ()
+ awful.client.focus.byidx(1)
+ end),
+ awful.button({ }, 5, function ()
+ awful.client.focus.byidx(-1)
+ end))
+
+local function set_wallpaper(s)
+ -- Wallpaper
+ if beautiful.wallpaper then
+ local wallpaper = beautiful.wallpaper
+ -- If wallpaper is a function, call it with the screen
+ if type(wallpaper) == "function" then
+ wallpaper = wallpaper(s)
+ end
+ gears.wallpaper.maximized(wallpaper, s, true)
+ end
+end
+
+
+-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
+screen.connect_signal("property::geometry", set_wallpaper)
+
+-- Tags
+-- Define a tag table which hold all screen tags.
+primary_screen = 1
+secondary_screen = screen:count()
+
+tags = {
+ names = {
+ 'IRC',
+ 'Code',
+ 'Net',
+ 'GFX',
+ 'Other',
+ },
+ layout = {
+ awful.layout.layouts[3], -- 1:IRC
+ awful.layout.layouts[4], -- 2:Code
+ awful.layout.layouts[10], -- 3:Net
+ awful.layout.layouts[10], -- 4:GFX
+ awful.layout.layouts[1],
+ }
+}
+
+awful.screen.connect_for_each_screen(function(s)
+ -- Wallpaper
+ set_wallpaper(s)
+
+ -- Each screen has its own tag table.
+ --awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, s, awful.layout.layouts[1])
+ tags[s] = awful.tag(tags.names, s, tags.layout)
+
+ -- Create a promptbox for each screen
+ s.mypromptbox = awful.widget.prompt()
+ -- Create an imagebox widget which will contains an icon indicating which layout we're using.
+ -- We need one layoutbox per screen.
+ s.mylayoutbox = awful.widget.layoutbox(s)
+ s.mylayoutbox:buttons(awful.util.table.join(
+ awful.button({ }, 1, function () awful.layout.inc( 1) end),
+ awful.button({ }, 3, function () awful.layout.inc(-1) end),
+ awful.button({ }, 4, function () awful.layout.inc( 1) end),
+ awful.button({ }, 5, function () awful.layout.inc(-1) end)))
+ -- Create a taglist widget
+ s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, taglist_buttons)
+
+ -- Create a tasklist widget
+ s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, tasklist_buttons)
+
+ -- Create the wibox
+ s.mywibox = awful.wibar({ position = "top", screen = s })
+
+ local right_widgets = {
+ layout = wibox.layout.fixed.horizontal,
+ --mykeyboardlayout,
+ wibox.widget.systray(),
+ spacer,
+ --myserverstatus,
+ ipaddress,
+ spacer,
+ volume,
+ spacer,
+ mydpmsstatus,
+ spacer,
+ --mycloudstatus,
+ --spacer,
+ mycpu,
+ spacer,
+ mymem,
+ spacer,
+ myweather,
+ spacer,
+ mycputemp,
+ mygputemp,
+ mytextclock,
+ s.mylayoutbox,
+ }
+ -- Only show everything on the first screen
+ if s.index > 1 then
+ right_widgets = {
+ layout = wibox.layout.fixed.horizontal,
+ s.mylayoutbox,
+ }
+ end
+
+ -- Add widgets to the wibox
+ s.mywibox:setup {
+ layout = wibox.layout.align.horizontal,
+ { -- Left widgets
+ layout = wibox.layout.fixed.horizontal,
+ mylauncher,
+ s.mytaglist,
+ s.mypromptbox,
+ },
+ s.mytasklist, -- Middle widget
+ right_widgets,
+ }
+end)
+-- }}}
+
+-- {{{ Mouse bindings
+root.buttons(awful.util.table.join(
+ awful.button({ }, 3, function () mymainmenu:toggle() end),
+ awful.button({ }, 4, awful.tag.viewnext),
+ awful.button({ }, 5, awful.tag.viewprev)
+))
+-- }}}
+
+-- {{{ Key bindings
+globalkeys = awful.util.table.join(
+ awful.key({ modkey, }, "s", hotkeys_popup.show_help,
+ {description="show help", group="awesome"}),
+ awful.key({ modkey, }, "Left", awful.tag.viewprev,
+ {description = "view previous", group = "tag"}),
+ awful.key({ modkey, }, "Right", awful.tag.viewnext,
+ {description = "view next", group = "tag"}),
+ awful.key({ modkey, }, "Escape", awful.tag.history.restore,
+ {description = "go back", group = "tag"}),
+
+ awful.key({ modkey, }, "j",
+ function ()
+ awful.client.focus.byidx( 1)
+ end,
+ {description = "focus next by index", group = "client"}
+ ),
+ awful.key({ modkey, }, "k",
+ function ()
+ awful.client.focus.byidx(-1)
+ end,
+ {description = "focus previous by index", group = "client"}
+ ),
+ awful.key({ modkey, }, "w", function () mymainmenu:show() end,
+ {description = "show main menu", group = "awesome"}),
+
+ awful.key({ modkey, "Shift" }, "l", lock,
+ {description = "lock screen", group = "screen"}),
+ -- Layout manipulation
+ awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
+ {description = "swap with next client by index", group = "client"}),
+ awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
+ {description = "swap with previous client by index", group = "client"}),
+ awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
+ {description = "focus the next screen", group = "screen"}),
+ awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
+ {description = "focus the previous screen", group = "screen"}),
+ awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
+ {description = "jump to urgent client", group = "client"}),
+ awful.key({ modkey, }, "Tab",
+ function ()
+ awful.client.focus.history.previous()
+ if client.focus then
+client.focus:raise()
+ end
+ end,
+ {description = "go back", group = "client"}),
+
+ -- Standard program
+ awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
+ {description = "open a terminal", group = "launcher"}),
+ awful.key({ modkey, "Control" }, "r", awesome.restart,
+ {description = "reload awesome", group = "awesome"}),
+ awful.key({ modkey, "Shift" }, "q", awesome.quit,
+ {description = "quit awesome", group = "awesome"}),
+
+ awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
+ {description = "increase master width factor", group = "layout"}),
+ awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
+ {description = "decrease master width factor", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
+ {description = "increase the number of master clients", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
+ {description = "decrease the number of master clients", group = "layout"}),
+ awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
+ {description = "increase the number of columns", group = "layout"}),
+ awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
+ {description = "decrease the number of columns", group = "layout"}),
+ awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
+ {description = "select next", group = "layout"}),
+ awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
+ {description = "select previous", group = "layout"}),
+
+ awful.key({ modkey, "Control" }, "n",
+ function ()
+ local c = awful.client.restore()
+ -- Focus restored client
+ if c then
+ client.focus = c
+ c:raise()
+ end
+ end,
+ {description = "restore minimized", group = "client"}),
+
+ -- Prompt
+ awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
+ {description = "run prompt", group = "launcher"}),
+
+ awful.key({ modkey }, "x",
+ function ()
+ awful.prompt.run {
+ prompt = "Run Lua code: ",
+ textbox = awful.screen.focused().mypromptbox.widget,
+ exe_callback = awful.util.eval,
+ history_path = awful.util.get_cache_dir() .. "/history_eval"
+ }
+ end,
+ {description = "lua execute prompt", group = "awesome"}),
+ -- Menubar
+ awful.key({ modkey }, "p", function() menubar.show() end,
+ {description = "show the menubar", group = "launcher"}),
+ -- Menubar (dmenu)
+ awful.key({ modkey }, "d",
+ function()
+ --awful.spawn(string.format("dmenu_run -i -b -l 20 -fn 'Fura Code Nerd Font:size=10:style=Regular'"))
+ awful.spawn(string.format("rofi -show combi -combi-modi 'window,run,ssh' -modi combi"))
+ end,
+ {description = "show the menubar", group = "launcher"})
+ )
+
+clientkeys = awful.util.table.join(
+ awful.key({ modkey, }, "f",
+ function (c)
+ c.fullscreen = not c.fullscreen
+ c:raise()
+ end,
+ {description = "toggle fullscreen", group = "client"}),
+ awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
+ {description = "close", group = "client"}),
+ awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
+ {description = "toggle floating", group = "client"}),
+ awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
+ {description = "move to master", group = "client"}),
+ awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
+ {description = "move to screen", group = "client"}),
+ awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
+ {description = "toggle keep on top", group = "client"}),
+ awful.key({ modkey, }, "n",
+ function (c)
+ -- The client currently has the input focus, so it cannot be
+ -- minimized, since minimized clients can't have the focus.
+ c.minimized = true
+ end ,
+ {description = "minimize", group = "client"}),
+ awful.key({ modkey, }, "m",
+ function (c)
+ c.maximized = not c.maximized
+ c:raise()
+ end ,
+ {description = "maximize", group = "client"})
+)
+
+local commands = {
+ print = false
+}
+
+-- Bind all key numbers to tags.
+-- Be careful: we use keycodes to make it works on any keyboard layout.
+-- This should map on the top row of your keyboard, usually 1 to 9.
+for i = 1, 9 do
+ globalkeys = awful.util.table.join(globalkeys,
+ -- View tag only.
+ awful.key({ modkey }, "#" .. i + 9,
+ function ()
+ local screen = awful.screen.focused()
+ local tag = screen.tags[i]
+ if tag then
+ tag:view_only()
+ end
+ end,
+ {description = "view tag #"..i, group = "tag"}),
+ -- Toggle tag display.
+ awful.key({ modkey, "Control" }, "#" .. i + 9,
+ function ()
+ local screen = awful.screen.focused()
+ local tag = screen.tags[i]
+ if tag then
+ awful.tag.viewtoggle(tag)
+ end
+ end,
+ {description = "toggle tag #" .. i, group = "tag"}),
+ -- Move client to tag.
+ awful.key({ modkey, "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:move_to_tag(tag)
+ end
+ end
+ end,
+ {description = "move focused client to tag #"..i, group = "tag"}),
+ -- Toggle tag on focused client.
+ awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
+ function ()
+ if client.focus then
+ local tag = client.focus.screen.tags[i]
+ if tag then
+ client.focus:toggle_tag(tag)
+ end
+ end
+ end,
+ {description = "toggle focused client on tag #" .. i, group = "tag"})
+
+ )
+ end
+ globalkeys = awful.util.table.join(globalkeys,
+
+ -- Pulseaudio
+ awful.key({ any }, "XF86AudioRaiseVolume", function()
+ awful.spawn(string.format("pactl set-sink-volume %s +1%%", volume.device))
+ volume.update()
+ end,
+ {description = "Raise audio volume", group = "audio"}), awful.key({ any }, "XF86AudioLowerVolume", function()
+ awful.spawn(string.format("pactl set-sink-volume %s -1%%", volume.device))
+ volume.update()
+ end,
+ {description = "Lower audio volume", group = "audio"}),
+ awful.key({ any }, "XF86AudioMute",
+ function()
+ awful.spawn(string.format("pactl set-sink-mute %s 1", volume.device))
+ volume.update()
+ end,
+ {description = "mute audio", group = "audio"}),
+ awful.key({ 'Shift' }, "XF86AudioMute",
+ function()
+ awful.spawn(string.format("pactl set-sink-mute %s 0", volume.device))
+ volume.update()
+ end,
+ {description = "unmute audio", group = "audio"}),
+ awful.key({ }, "Print",
+ function ()
+ --local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']]
+ for i=1,screen:count() do
+ local command = "bash -c 'flameshot screen -n ".. i-1 .." -p \"$(xdg-user-dir PICTURES)/\"'"
+ awful.spawn.easy_async(command, function(stdout, stderr)
+ --naughty.notify {
+ -- title = "Screenshot saved!",
+ -- text = stdout,
+ --}
+ end)
+ end
+ end,
+ {description = "Take screenshot", group = "video"}),
+ awful.key({ 'Shift' }, "Print",
+ function ()
+ --local command = [[bash -c 'escrotum "$(xdg-user-dir PICTURES)/%Y-%m-%d_%T_screenshot.png"']]
+ for i=1,screen:count() do
+ local command = "bash -c 'flameshot gui -p \"$(xdg-user-dir PICTURES)/\"'"
+ awful.spawn.easy_async(command, function(stdout, stderr)
+ --naughty.notify {
+ -- title = "Screenshot saved!",
+ -- text = stdout,
+ --}
+ end)
+ end
+ end,
+ {description = "Take screenshot", group = "video"})
+ )
+
+clientbuttons = awful.util.table.join(
+ awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
+ awful.button({ modkey }, 1, awful.mouse.client.move),
+ awful.button({ modkey }, 3, awful.mouse.client.resize))
+
+-- Set keys
+root.keys(globalkeys)
+-- }}}
+
+-- {{{ Rules
+-- Rules to apply to new clients (through the "manage" signal).
+awful.rules.rules = {
+ -- All clients will match this rule.
+ { rule = { },
+ properties = { border_width = beautiful.border_width,
+ border_color = beautiful.border_normal,
+ focus = awful.client.focus.filter,
+ raise = true,
+ keys = clientkeys,
+ buttons = clientbuttons,
+ screen = awful.screen.preferred,
+ placement = awful.placement.no_overlap+awful.placement.no_offscreen
+ }
+ },
+ -- Maximized clients.
+ { rule_any = {
+ instance = {
+ },
+ class = {
+ "Zathura",
+ "MComix"
+ },
+ name = {
+ },
+ role = {
+ }
+ }, properties = {
+ floating = true,
+ maximized = true
+ }
+ },
+
+ -- Floating clients.
+ { rule_any = {
+ instance = {
+ },
+ class = {
+ "Arandr",
+ "cantata",
+ "Steam",
+ "itch",
+ "Wine",
+ "mpv",
+ "Vlc",
+ "Sxiv",
+ "Plugin-container"
+ },
+ name = {
+ },
+ role = {
+ "pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
+ }
+ }, properties = {
+ floating = true
+ }
+ },
+
+ -- Add titlebars to normal clients and dialogs
+ { rule_any = {type = { "normal", "dialog" }
+ }, properties = { titlebars_enabled = false }
+ },
+
+ -- Window positioning
+ { rule = { class = "Chromium" },
+ properties = { screen = primary_screen, tag = "Net" } },
+ { rule = { class = "Firefox" },
+ properties = { screen = primary_screen, tag = "Net" } },
+ { rule = { class = "Inkscape" },
+ properties = { screen = primary_screen, tag = "GFX" } },
+ { rule = { class = "Gimp" },
+ properties = { screen = primary_screen, tag = "GFX" } },
+ { rule = { class = "Blender" },
+ properties = { screen = primary_screen, tag = "GFX" } },
+ { rule = { class = "Steam", name = "Friends List" },
+ properties = { screen = secondary_screen, tag = "Other", width = 300, height = 800, x = 3530, y = 30 } },
+ { rule = { class = "Steam", name = "Steam" },
+ properties = { screen = secondary_screen, tag = "Other" } },
+}
+-- }}}
+
+-- {{{ Signals
+-- Signal function to execute when a new client appears.
+client.connect_signal("manage", function (c)
+ -- Set the windows at the slave,
+ -- i.e. put it at the end of others instead of setting it master.
+ -- if not awesome.startup then awful.client.setslave(c) end
+
+ if awesome.startup and
+ not c.size_hints.user_position
+ and not c.size_hints.program_position then
+ -- Prevent clients from being unreachable after screen count changes.
+ awful.placement.no_offscreen(c)
+ end
+end)
+
+-- Add a titlebar if titlebars_enabled is set to true in the rules.
+client.connect_signal("request::titlebars", function(c)
+ -- buttons for the titlebar
+ local buttons = awful.util.table.join(
+ awful.button({ }, 1, function()
+ client.focus = c
+ c:raise()
+ awful.mouse.client.move(c)
+ end),
+ awful.button({ }, 3, function()
+ client.focus = c
+ c:raise()
+ awful.mouse.client.resize(c)
+ end)
+ )
+
+ awful.titlebar(c) : setup {
+ { -- Left
+ awful.titlebar.widget.iconwidget(c),
+ buttons = buttons,
+ layout = wibox.layout.fixed.horizontal
+ },
+ { -- Middle
+ { -- Title
+ align = "center",
+ widget = awful.titlebar.widget.titlewidget(c)
+ },
+ buttons = buttons,
+ layout = wibox.layout.flex.horizontal
+ },
+ { -- Right
+ awful.titlebar.widget.floatingbutton (c),
+ awful.titlebar.widget.maximizedbutton(c),
+ awful.titlebar.widget.stickybutton (c),
+ awful.titlebar.widget.ontopbutton (c),
+ awful.titlebar.widget.closebutton (c),
+ layout = wibox.layout.fixed.horizontal()
+ },
+ layout = wibox.layout.align.horizontal
+ }
+end)
+
+-- Enable sloppy focus, so that focus follows mouse.
+client.connect_signal("mouse::enter", function(c)
+ if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
+ and awful.client.focus.filter(c) then
+ client.focus = c
+ end
+end)
+
+client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
+client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
+-- }}}
+
+local fullscreened_clients = {}
+
+local function remove_client(tabl, c)
+ local index = awful.util.table.hasitem(tabl, c)
+ if index then
+ table.remove(tabl, index)
+ if #tabl == 0 then
+ awful.util.spawn("xset s blank")
+ awful.util.spawn("xset s on")
+ awful.util.spawn("xset +dpms")
+ naughty.notify({ preset = naughty.config.presets.low,
+ title = "DPMS information",
+ text = "Display power management is now back ON"})
+ end
+ end
+end
+
+client.connect_signal("property::fullscreen", function(c)
+ if c.fullscreen then
+ table.insert(fullscreened_clients, c)
+ if #fullscreened_clients == 1 then
+ awful.util.spawn("xset s noblank")
+ awful.util.spawn("xset s off")
+ awful.util.spawn("xset -dpms")
+ naughty.notify({
+ preset = naughty.config.presets.low,
+ title = "DPMS information",
+ text = "Display power management is now OFF"
+ })
+ end
+ else
+ remove_client(fullscreened_clients, c)
+ end
+end)
+
+client.connect_signal("unmanage", function(c)
+ if c.fullscreen then
+ remove_client(fullscreened_clients, c)
+ end
+end)
+
+awful.util.spawn_with_shell("run-once pasystray")
+awful.util.spawn_with_shell("run-once blueman-applet")
+awful.util.spawn_with_shell("run-once nm-applet")
+awful.util.spawn_with_shell("run-once 'nextcloud --background'")
+awful.util.spawn_with_shell("run-once 'udiskie --tray --notify --automount'")
+awful.util.spawn_with_shell("run-once 'mpd /home/lanxu/.config/mpd/mpd.conf'")
+awful.util.spawn_with_shell("run-once 'xscreensaver -no-splash'")
+--awful.util.spawn_with_shell("run-once conky")
+--awful.util.spawn_with_shell("run-once light-locker")
+--awful.util.spawn_with_shell("run-once firefox-developer-edition")
+--awful.util.spawn_with_shell("run-once firefox")
+
+--awful.util.spawn_with_shell("run-once syncthing-gtk")
diff --git a/config/awesome/themes/lanxu/background.png b/config/awesome/themes/lanxu/background.png
new file mode 100644
index 0000000..28d5059
Binary files /dev/null and b/config/awesome/themes/lanxu/background.png differ
diff --git a/config/awesome/themes/lanxu/icons/cpu.png b/config/awesome/themes/lanxu/icons/cpu.png
new file mode 100644
index 0000000..b9891e3
Binary files /dev/null and b/config/awesome/themes/lanxu/icons/cpu.png differ
diff --git a/config/awesome/themes/lanxu/icons/gpu.png b/config/awesome/themes/lanxu/icons/gpu.png
new file mode 100644
index 0000000..4926699
Binary files /dev/null and b/config/awesome/themes/lanxu/icons/gpu.png differ
diff --git a/config/awesome/themes/lanxu/icons/ram.png b/config/awesome/themes/lanxu/icons/ram.png
new file mode 100644
index 0000000..7f61ac2
Binary files /dev/null and b/config/awesome/themes/lanxu/icons/ram.png differ
diff --git a/config/awesome/themes/lanxu/icons/wall-clock.png b/config/awesome/themes/lanxu/icons/wall-clock.png
new file mode 100644
index 0000000..6b262ad
Binary files /dev/null and b/config/awesome/themes/lanxu/icons/wall-clock.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornerne.png b/config/awesome/themes/lanxu/layouts/cornerne.png
new file mode 100644
index 0000000..e7fb61b
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornerne.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornernew.png b/config/awesome/themes/lanxu/layouts/cornernew.png
new file mode 100644
index 0000000..aeaf331
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornernew.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornernw.png b/config/awesome/themes/lanxu/layouts/cornernw.png
new file mode 100644
index 0000000..bac5672
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornernw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornernww.png b/config/awesome/themes/lanxu/layouts/cornernww.png
new file mode 100644
index 0000000..93b6706
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornernww.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornerse.png b/config/awesome/themes/lanxu/layouts/cornerse.png
new file mode 100644
index 0000000..092a905
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornerse.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornersew.png b/config/awesome/themes/lanxu/layouts/cornersew.png
new file mode 100644
index 0000000..35e900b
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornersew.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornersw.png b/config/awesome/themes/lanxu/layouts/cornersw.png
new file mode 100644
index 0000000..0d519b5
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornersw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/cornersww.png b/config/awesome/themes/lanxu/layouts/cornersww.png
new file mode 100644
index 0000000..2d744fd
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/cornersww.png differ
diff --git a/config/awesome/themes/lanxu/layouts/dwindle.png b/config/awesome/themes/lanxu/layouts/dwindle.png
new file mode 100644
index 0000000..0ec7a35
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/dwindle.png differ
diff --git a/config/awesome/themes/lanxu/layouts/dwindlew.png b/config/awesome/themes/lanxu/layouts/dwindlew.png
new file mode 100644
index 0000000..8457892
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/dwindlew.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fairh.png b/config/awesome/themes/lanxu/layouts/fairh.png
new file mode 100644
index 0000000..3c2d36b
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fairh.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fairhw.png b/config/awesome/themes/lanxu/layouts/fairhw.png
new file mode 100644
index 0000000..410e292
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fairhw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fairv.png b/config/awesome/themes/lanxu/layouts/fairv.png
new file mode 100644
index 0000000..ad99f4b
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fairv.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fairvw.png b/config/awesome/themes/lanxu/layouts/fairvw.png
new file mode 100644
index 0000000..1a4ee27
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fairvw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/floating.png b/config/awesome/themes/lanxu/layouts/floating.png
new file mode 100644
index 0000000..bf74990
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/floating.png differ
diff --git a/config/awesome/themes/lanxu/layouts/floatingw.png b/config/awesome/themes/lanxu/layouts/floatingw.png
new file mode 100644
index 0000000..7aecb06
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/floatingw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fullscreen.png b/config/awesome/themes/lanxu/layouts/fullscreen.png
new file mode 100644
index 0000000..d02f6fc
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fullscreen.png differ
diff --git a/config/awesome/themes/lanxu/layouts/fullscreenw.png b/config/awesome/themes/lanxu/layouts/fullscreenw.png
new file mode 100644
index 0000000..5c35bfa
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/fullscreenw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/magnifier.png b/config/awesome/themes/lanxu/layouts/magnifier.png
new file mode 100644
index 0000000..2ea2792
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/magnifier.png differ
diff --git a/config/awesome/themes/lanxu/layouts/magnifierw.png b/config/awesome/themes/lanxu/layouts/magnifierw.png
new file mode 100644
index 0000000..5cd5e16
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/magnifierw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/max.png b/config/awesome/themes/lanxu/layouts/max.png
new file mode 100644
index 0000000..8d20844
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/max.png differ
diff --git a/config/awesome/themes/lanxu/layouts/maxw.png b/config/awesome/themes/lanxu/layouts/maxw.png
new file mode 100644
index 0000000..85f5ce3
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/maxw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/spiral.png b/config/awesome/themes/lanxu/layouts/spiral.png
new file mode 100644
index 0000000..ca41814
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/spiral.png differ
diff --git a/config/awesome/themes/lanxu/layouts/spiralw.png b/config/awesome/themes/lanxu/layouts/spiralw.png
new file mode 100644
index 0000000..d128461
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/spiralw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tile.png b/config/awesome/themes/lanxu/layouts/tile.png
new file mode 100644
index 0000000..db1ce15
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tile.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tilebottom.png b/config/awesome/themes/lanxu/layouts/tilebottom.png
new file mode 100644
index 0000000..73a72fe
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tilebottom.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tilebottomw.png b/config/awesome/themes/lanxu/layouts/tilebottomw.png
new file mode 100644
index 0000000..64aa289
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tilebottomw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tileleft.png b/config/awesome/themes/lanxu/layouts/tileleft.png
new file mode 100644
index 0000000..829475a
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tileleft.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tileleftw.png b/config/awesome/themes/lanxu/layouts/tileleftw.png
new file mode 100644
index 0000000..24c3941
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tileleftw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tiletop.png b/config/awesome/themes/lanxu/layouts/tiletop.png
new file mode 100644
index 0000000..1964d4d
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tiletop.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tiletopw.png b/config/awesome/themes/lanxu/layouts/tiletopw.png
new file mode 100644
index 0000000..d2eee79
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tiletopw.png differ
diff --git a/config/awesome/themes/lanxu/layouts/tilew.png b/config/awesome/themes/lanxu/layouts/tilew.png
new file mode 100644
index 0000000..4451a66
Binary files /dev/null and b/config/awesome/themes/lanxu/layouts/tilew.png differ
diff --git a/config/awesome/themes/lanxu/logo.png b/config/awesome/themes/lanxu/logo.png
new file mode 100644
index 0000000..83e8156
Binary files /dev/null and b/config/awesome/themes/lanxu/logo.png differ
diff --git a/config/awesome/themes/lanxu/logo16.png b/config/awesome/themes/lanxu/logo16.png
new file mode 100644
index 0000000..f2cfbd5
Binary files /dev/null and b/config/awesome/themes/lanxu/logo16.png differ
diff --git a/config/awesome/themes/lanxu/submenu.png b/config/awesome/themes/lanxu/submenu.png
new file mode 100644
index 0000000..b2778e2
Binary files /dev/null and b/config/awesome/themes/lanxu/submenu.png differ
diff --git a/config/awesome/themes/lanxu/taglist/squarefw.png b/config/awesome/themes/lanxu/taglist/squarefw.png
new file mode 100644
index 0000000..2a86430
Binary files /dev/null and b/config/awesome/themes/lanxu/taglist/squarefw.png differ
diff --git a/config/awesome/themes/lanxu/taglist/squarew.png b/config/awesome/themes/lanxu/taglist/squarew.png
new file mode 100644
index 0000000..913f2ca
Binary files /dev/null and b/config/awesome/themes/lanxu/taglist/squarew.png differ
diff --git a/config/awesome/themes/lanxu/theme.lua b/config/awesome/themes/lanxu/theme.lua
new file mode 100644
index 0000000..4edb719
--- /dev/null
+++ b/config/awesome/themes/lanxu/theme.lua
@@ -0,0 +1,127 @@
+---------------------------
+-- Default awesome theme --
+---------------------------
+local theme_assets = require("beautiful.theme_assets")
+local xresources = require("beautiful.xresources")
+local dpi = xresources.apply_dpi
+
+local theme = {}
+
+theme.dir = os.getenv("HOME") .. "/.config/awesome/themes/lanxu"
+theme.wallpaper = theme.dir .. "/background.png"
+theme.font = "Fira Sans 10"
+
+theme.bg_normal = "#222222"
+theme.bg_focus = "#8A2BE2"
+theme.bg_urgent = "#ff0000"
+theme.bg_minimize = "#444444"
+theme.bg_systray = theme.bg_normal
+
+theme.fg_normal = "#d0bce2"
+theme.fg_focus = "#ffffff"
+theme.fg_urgent = "#ffffff"
+theme.fg_minimize = "#ffffff"
+
+theme.useless_gap = dpi(0)
+theme.border_width = dpi(1)
+theme.border_normal = "#000000"
+theme.border_focus = "#535d6c"
+theme.border_marked = "#91231c"
+
+theme.wibar_height = 20
+-- theme.wibar_border_width = 2
+-- theme.wibar_border_color = "#222222"
+-- There are other variable sets
+-- overriding the default one when
+-- defined, the sets are:
+-- taglist_[bg|fg]_[focus|urgent|occupied|empty]
+-- tasklist_[bg|fg]_[focus|urgent]
+-- titlebar_[bg|fg]_[normal|focus]
+-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
+-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
+-- Example:
+--theme.taglist_bg_focus = "#ff0000"
+
+-- Display the taglist squares
+--theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png"
+--theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png"
+local taglist_square_size = dpi(4)
+theme.taglist_squares_sel = theme_assets.taglist_squares_sel(
+ taglist_square_size, theme.fg_normal
+)
+theme.taglist_squares_unsel = theme_assets.taglist_squares_unsel(
+ taglist_square_size, theme.fg_normal
+)
+
+-- Variables set for theming the menu:
+-- menu_[bg|fg]_[normal|focus]
+-- menu_[border_color|border_width]
+theme.menu_submenu_icon = theme.dir .. "/submenu.png"
+theme.menu_height = dpi(15)
+theme.menu_width = dpi(100)
+
+-- You can add as many variables as
+-- you wish and access them by using
+-- beautiful.variable in your rc.lua
+--theme.bg_widget = "#cc0000"
+
+-- Define the image to load
+theme.titlebar_close_button_normal = theme.dir .. "/titlebar/close_normal.png"
+theme.titlebar_close_button_focus = theme.dir .. "/titlebar/close_focus.png"
+
+theme.titlebar_minimize_button_normal = theme.dir .. "/titlebar/minimize_normal.png"
+theme.titlebar_minimize_button_focus = theme.dir .. "/titlebar/minimize_focus.png"
+
+theme.titlebar_ontop_button_normal_inactive = theme.dir .. "/titlebar/ontop_normal_inactive.png"
+theme.titlebar_ontop_button_focus_inactive = theme.dir .. "/titlebar/ontop_focus_inactive.png"
+theme.titlebar_ontop_button_normal_active = theme.dir .. "/titlebar/ontop_normal_active.png"
+theme.titlebar_ontop_button_focus_active = theme.dir .. "/titlebar/ontop_focus_active.png"
+
+theme.titlebar_sticky_button_normal_inactive = theme.dir .. "/titlebar/sticky_normal_inactive.png"
+theme.titlebar_sticky_button_focus_inactive = theme.dir .. "/titlebar/sticky_focus_inactive.png"
+theme.titlebar_sticky_button_normal_active = theme.dir .. "/titlebar/sticky_normal_active.png"
+theme.titlebar_sticky_button_focus_active = theme.dir .. "/titlebar/sticky_focus_active.png"
+
+theme.titlebar_floating_button_normal_inactive = theme.dir .. "/titlebar/floating_normal_inactive.png"
+theme.titlebar_floating_button_focus_inactive = theme.dir .. "/titlebar/floating_focus_inactive.png"
+theme.titlebar_floating_button_normal_active = theme.dir .. "/titlebar/floating_normal_active.png"
+theme.titlebar_floating_button_focus_active = theme.dir .. "/titlebar/floating_focus_active.png"
+
+theme.titlebar_maximized_button_normal_inactive = theme.dir .. "/titlebar/maximized_normal_inactive.png"
+theme.titlebar_maximized_button_focus_inactive = theme.dir .. "/titlebar/maximized_focus_inactive.png"
+theme.titlebar_maximized_button_normal_active = theme.dir .. "/titlebar/maximized_normal_active.png"
+theme.titlebar_maximized_button_focus_active = theme.dir .. "/titlebar/maximized_focus_active.png"
+
+theme.wallpaper = theme.dir .. "/background.png"
+
+-- You can use your own layout icons like this:
+theme.layout_fairh = theme.dir .. "/layouts/fairhw.png"
+theme.layout_fairv = theme.dir .. "/layouts/fairvw.png"
+theme.layout_floating = theme.dir .. "/layouts/floatingw.png"
+theme.layout_magnifier = theme.dir .. "/layouts/magnifierw.png"
+theme.layout_max = theme.dir .. "/layouts/maxw.png"
+theme.layout_fullscreen = theme.dir .. "/layouts/fullscreenw.png"
+theme.layout_tilebottom = theme.dir .. "/layouts/tilebottomw.png"
+theme.layout_tileleft = theme.dir .. "/layouts/tileleftw.png"
+theme.layout_tile = theme.dir .. "/layouts/tilew.png"
+theme.layout_tiletop = theme.dir .. "/layouts/tiletopw.png"
+theme.layout_spiral = theme.dir .. "/layouts/spiralw.png"
+theme.layout_dwindle = theme.dir .. "/layouts/dwindlew.png"
+theme.layout_cornernw = theme.dir .. "/layouts/cornernww.png"
+theme.layout_cornerne = theme.dir .. "/layouts/cornernew.png"
+theme.layout_cornersw = theme.dir .. "/layouts/cornersww.png"
+theme.layout_cornerse = theme.dir .. "/layouts/cornersew.png"
+
+theme.awesome_icon = theme_assets.awesome_icon(
+ theme.menu_height, theme.bg_focus, theme.fg_focus
+)
+
+--theme.awesome_icon = theme.dir .. "/logo16.png"
+
+-- Define the icon theme for application icons. If not set then the icons
+-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
+theme.icon_theme = nil
+
+return theme
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/config/awesome/themes/lanxu/titlebar/close_focus.png b/config/awesome/themes/lanxu/titlebar/close_focus.png
new file mode 100644
index 0000000..e4763b6
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/close_focus.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/close_normal.png b/config/awesome/themes/lanxu/titlebar/close_normal.png
new file mode 100644
index 0000000..7702839
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/close_normal.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/floating_focus_active.png b/config/awesome/themes/lanxu/titlebar/floating_focus_active.png
new file mode 100644
index 0000000..80c1b4a
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/floating_focus_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/floating_focus_inactive.png b/config/awesome/themes/lanxu/titlebar/floating_focus_inactive.png
new file mode 100644
index 0000000..a96f00c
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/floating_focus_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/floating_normal_active.png b/config/awesome/themes/lanxu/titlebar/floating_normal_active.png
new file mode 100644
index 0000000..b9c70ca
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/floating_normal_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/floating_normal_inactive.png b/config/awesome/themes/lanxu/titlebar/floating_normal_inactive.png
new file mode 100644
index 0000000..55cbc0c
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/floating_normal_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/maximized_focus_active.png b/config/awesome/themes/lanxu/titlebar/maximized_focus_active.png
new file mode 100644
index 0000000..dad461d
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/maximized_focus_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/maximized_focus_inactive.png b/config/awesome/themes/lanxu/titlebar/maximized_focus_inactive.png
new file mode 100644
index 0000000..3cc46fe
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/maximized_focus_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/maximized_normal_active.png b/config/awesome/themes/lanxu/titlebar/maximized_normal_active.png
new file mode 100644
index 0000000..0bbbf6a
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/maximized_normal_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/maximized_normal_inactive.png b/config/awesome/themes/lanxu/titlebar/maximized_normal_inactive.png
new file mode 100644
index 0000000..5f1e98f
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/maximized_normal_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/minimize_focus.png b/config/awesome/themes/lanxu/titlebar/minimize_focus.png
new file mode 100644
index 0000000..ff427b3
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/minimize_focus.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/minimize_normal.png b/config/awesome/themes/lanxu/titlebar/minimize_normal.png
new file mode 100644
index 0000000..aa47447
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/minimize_normal.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/ontop_focus_active.png b/config/awesome/themes/lanxu/titlebar/ontop_focus_active.png
new file mode 100644
index 0000000..d79c8e2
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/ontop_focus_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/ontop_focus_inactive.png b/config/awesome/themes/lanxu/titlebar/ontop_focus_inactive.png
new file mode 100644
index 0000000..03aef5a
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/ontop_focus_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/ontop_normal_active.png b/config/awesome/themes/lanxu/titlebar/ontop_normal_active.png
new file mode 100644
index 0000000..e09f32d
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/ontop_normal_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/ontop_normal_inactive.png b/config/awesome/themes/lanxu/titlebar/ontop_normal_inactive.png
new file mode 100644
index 0000000..9917b9e
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/ontop_normal_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/sticky_focus_active.png b/config/awesome/themes/lanxu/titlebar/sticky_focus_active.png
new file mode 100644
index 0000000..8019463
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/sticky_focus_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/sticky_focus_inactive.png b/config/awesome/themes/lanxu/titlebar/sticky_focus_inactive.png
new file mode 100644
index 0000000..6d7fe40
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/sticky_focus_inactive.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/sticky_normal_active.png b/config/awesome/themes/lanxu/titlebar/sticky_normal_active.png
new file mode 100644
index 0000000..0d003ef
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/sticky_normal_active.png differ
diff --git a/config/awesome/themes/lanxu/titlebar/sticky_normal_inactive.png b/config/awesome/themes/lanxu/titlebar/sticky_normal_inactive.png
new file mode 100644
index 0000000..f1e8789
Binary files /dev/null and b/config/awesome/themes/lanxu/titlebar/sticky_normal_inactive.png differ
diff --git a/config/awesome/widgets.lua b/config/awesome/widgets.lua
new file mode 100644
index 0000000..e05f882
--- /dev/null
+++ b/config/awesome/widgets.lua
@@ -0,0 +1,172 @@
+local gputemp = require("gputemp")
+local hubic = require("hubic")
+local dpmsstatus = require("dpmsstatus")
+local lain = require("lain")
+local vicious = require("vicious") -- Custom
+local beautiful = require("beautiful") -- CPU temp
+local wibox = require("wibox")
+local gears = require("gears")
+
+-- Variables
+local valuecolor = "white"
+
+icons_dir = os.getenv("HOME") .. "/.config/awesome/themes/lanxu/icons/"
+cpuicon = wibox.widget.imagebox()
+cpuicon.image = icons_dir .. "cpu.png"
+cpuicon.resize = false
+
+-- Helpers
+function file_exists(name)
+ local f = io.open(name,"r")
+ if f ~= nil then io.close(f) return true else return false end
+end
+
+function create_markup(key, value, postfix, color)
+ return key .. " " .. value .. postfix ..""
+end
+
+-- Spacer
+spacer = wibox.widget.textbox()
+--spacer.text = "-"
+spacer.forced_width = 8;
+
+-- CPU
+mycpu = lain.widget.cpu({
+ settings = function()
+ widget.markup = create_markup("CPU", cpu_now.usage, " %", valuecolor)
+ end
+})
+
+-- MEM
+mymem = lain.widget.mem({
+ settings = function()
+ widget.markup = create_markup("MEM", mem_now.used, " MB", valuecolor)
+ end
+})
+
+-- GPU
+mygputemp_text = wibox.widget.textbox()
+mygputemp_text.align = "center"
+vicious.register(mygputemp_text, gputemp,
+function(widget, args)
+ temp = string.format("%.0f", tonumber(args[0]))
+ return create_markup("", temp, "℃", valuecolor)
+end, 15, "AMD")
+mygputemp = wibox.container.background()
+mygputemp.forced_width = 70
+mygputemp:set_widget(mygputemp_text)
+--mytextclock:set_shape(gears.shape.hexagon)
+mygputemp:set_bg('#5e35b1')
+
+-- Hubic
+myhubic = wibox.widget.textbox()
+vicious.register(myhubic, hubic, create_markup("CLOUD", "$0", "", valuecolor), 15, "HUBIC")
+
+-- Volume
+volume = lain.widget.pulse({
+ scallback = function()
+ return "pacmd list-sinks | grep -Paoz \"(?s)(\\* index.*$(pactl info | grep -e 'ink' | cut -d' ' -f3).*(index)?)\" | tr -d '\\000' | grep -e 'index' -e 'device.string' -e 'name:' -e 'volume: front' -e 'muted'"
+ end,
+ settings = function()
+ volstr = volume_now.left .. " "
+ volcolor = valuecolor
+ if volume_now.muted == "yes" then
+ volcolor = "red"
+ end
+ widget.markup = create_markup("VOL", volstr, "%", volcolor)
+ end
+})
+
+-- Text clock
+mytextclock_text = wibox.widget.textclock(create_markup("","%Y-%m-%d %H:%M","", valuecolor))
+mytextclock_text.align = "center"
+lain.widget.cal({
+ followtag = true,
+ attach_to = {mytextclock_text},
+ notification_preset = {
+ font = "Monospace 11", fg = "#FFFFFF", bg = "#000000"
+ }
+})
+
+mytextclock = wibox.container.background()
+mytextclock.forced_width = 130
+mytextclock:set_widget(mytextclock_text)
+mytextclock:set_bg('#512da8')
+
+-- CPU temperature
+local tempfile = "/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon1/temp1_input"
+if file_exists(tempfile) == false then
+ tempfile = "/sys/class/thermal/thermal_zone0/temp"
+end
+
+mycputemp_text = lain.widget.temp({
+ tempfile = tempfile,
+ settings = function()
+ temp = string.format("%.0f", tonumber(coretemp_now))
+ widget.markup = create_markup("", temp, "℃", valuecolor)
+ end
+})
+
+mycputemp_text.widget.align = "center"
+mycputemp = wibox.container.background()
+mycputemp.forced_width = 70
+mycputemp:set_widget(mycputemp_text.widget)
+mycputemp:set_bg('#9575cd')
+-- Weather Widget
+myweather = lain.widget.weather({
+ city_id = 634963,
+ lang = "fi",
+ followtag = true,
+ settings = function()
+ widget.markup = create_markup("Tampere", weather_now.main.temp, "℃", valuecolor)
+ end,
+ notification_preset = {
+ font = "Monospace 11", fg = "#FFFFFF", bg = "#000000"
+ }
+})
+
+-- DPMS
+mydpmsstatus = wibox.widget.textbox()
+-- mydpmsstatus.container.background.bg = '#ff0000'
+--mydpmsstatus = {
+-- widget = wibox.widget.textbox
+--}
+
+vicious.register(mydpmsstatus, dpmsstatus, function(widget, args)
+ color = valuecolor
+ if args[0] == "Enabled" then
+ return create_markup("DPMS", "ON", "", color)
+ else
+ color = "red"
+ return create_markup("DPMS", "OFF", "", color)
+ end
+end)
+
+local notification = {
+ font = "Monospace 10"
+}
+-- Servers
+--local mcstatus = require("lanxu/mcstatus")
+--myserverstatus = mcstatus({
+ --notification_preset = notification,
+ --settings = function()
+ --widget.markup = create_markup("PLAYERS", totalplayers, "", valuecolor)
+ --end
+--})
+
+--local cloudstatus = require("lanxu/cloudstatus")
+--mycloudstatus = cloudstatus({
+ --notification_preset = notification,
+ --settings = function()
+ --widget.markup = create_markup("CLOUD", currentstatus, "", valuecolor)
+ --end
+--})
+
+local ip = require("lanxu/ip")
+ipaddress = ip({
+ homeaddress = "91.157.104.247",
+ settings = function()
+ widget.markup = create_markup("IP", address, "", valuecolor)
+ end
+})
+
diff --git a/config/compton/compton.conf b/config/compton/compton.conf
new file mode 100644
index 0000000..6dbb71e
--- /dev/null
+++ b/config/compton/compton.conf
@@ -0,0 +1,9 @@
+# menu = { shadow = false; };
+dropdown_menu = { shadow = false; };
+popup_menu = { shadow = false; };
+utility = { shadow = false; };
+
+opacity-rule = [
+ "95:class_g = 'kitty' && focused",
+ "80:class_g = 'kitty' && !focused"
+];
diff --git a/config/dunst/dunstrc b/config/dunst/dunstrc
new file mode 100644
index 0000000..1d3be32
--- /dev/null
+++ b/config/dunst/dunstrc
@@ -0,0 +1,425 @@
+[global]
+ ### Display ###
+
+ # Which monitor should the notifications be displayed on.
+ monitor = 0
+
+ # Display notification on focused monitor. Possible modes are:
+ # mouse: follow mouse pointer
+ # keyboard: follow window with keyboard focus
+ # none: don't follow anything
+ #
+ # "keyboard" needs a window manager that exports the
+ # _NET_ACTIVE_WINDOW property.
+ # This should be the case for almost all modern window managers.
+ #
+ # If this option is set to mouse or keyboard, the monitor option
+ # will be ignored.
+ follow = mouse
+
+ # The geometry of the window:
+ # [{width}]x{height}[+/-{x}+/-{y}]
+ # The geometry of the message window.
+ # The height is measured in number of notifications everything else
+ # in pixels. If the width is omitted but the height is given
+ # ("-geometry x2"), the message window expands over the whole screen
+ # (dmenu-like). If width is 0, the window expands to the longest
+ # message displayed. A positive x is measured from the left, a
+ # negative from the right side of the screen. Y is measured from
+ # the top and down respectively.
+ # The width can be negative. In this case the actual width is the
+ # screen width minus the width defined in within the geometry option.
+ geometry = "300x5-30+20"
+
+ # Show how many messages are currently hidden (because of geometry).
+ indicate_hidden = yes
+
+ # Shrink window if it's smaller than the width. Will be ignored if
+ # width is 0.
+ shrink = no
+
+ # The transparency of the window. Range: [0; 100].
+ # This option will only work if a compositing window manager is
+ # present (e.g. xcompmgr, compiz, etc.).
+ transparency = 5
+
+ # The height of the entire notification. If the height is smaller
+ # than the font height and padding combined, it will be raised
+ # to the font height and padding.
+ notification_height = 0
+
+ # Draw a line of "separator_height" pixel height between two
+ # notifications.
+ # Set to 0 to disable.
+ separator_height = 2
+
+ # Padding between text and separator.
+ padding = 10
+
+ # Horizontal padding.
+ horizontal_padding = 8
+
+ # Defines width in pixels of frame around the notification window.
+ # Set to 0 to disable.
+ frame_width = 3
+
+ # Defines color of the frame around the notification window.
+ #frame_color = "#aaaaaa"
+ frame_color = foreground
+
+ # Define a color for the separator.
+ # possible values are:
+ # * auto: dunst tries to find a color fitting to the background;
+ # * foreground: use the same color as the foreground;
+ # * frame: use the same color as the frame;
+ # * anything else will be interpreted as a X color.
+ separator_color = frame
+
+ # Sort messages by urgency.
+ sort = yes
+
+ # Don't remove messages, if the user is idle (no mouse or keyboard input)
+ # for longer than idle_threshold seconds.
+ # Set to 0 to disable.
+ # A client can set the 'transient' hint to bypass this. See the rules
+ # section for how to disable this if necessary
+ idle_threshold = 120
+
+ ### Text ###
+
+ font = Monospace 10
+
+ # The spacing between lines. If the height is smaller than the
+ # font height, it will get raised to the font height.
+ line_height = 0
+
+ # Possible values are:
+ # full: Allow a small subset of html markup in notifications:
+ # bold
+ # italic
+ # strikethrough
+ # underline
+ #
+ # For a complete reference see
+ # .
+ #
+ # strip: This setting is provided for compatibility with some broken
+ # clients that send markup even though it's not enabled on the
+ # server. Dunst will try to strip the markup but the parsing is
+ # simplistic so using this option outside of matching rules for
+ # specific applications *IS GREATLY DISCOURAGED*.
+ #
+ # no: Disable markup parsing, incoming notifications will be treated as
+ # plain text. Dunst will not advertise that it has the body-markup
+ # capability if this is set as a global setting.
+ #
+ # It's important to note that markup inside the format option will be parsed
+ # regardless of what this is set to.
+ markup = full
+
+ # The format of the message. Possible variables are:
+ # %a appname
+ # %s summary
+ # %b body
+ # %i iconname (including its path)
+ # %I iconname (without its path)
+ # %p progress value if set ([ 0%] to [100%]) or nothing
+ # %n progress value if set without any extra characters
+ # %% Literal %
+ # Markup is allowed
+ format = "%s\n%b"
+
+ # Alignment of message text.
+ # Possible values are "left", "center" and "right".
+ alignment = left
+
+ # Show age of message if message is older than show_age_threshold
+ # seconds.
+ # Set to -1 to disable.
+ show_age_threshold = 60
+
+ # Split notifications into multiple lines if they don't fit into
+ # geometry.
+ word_wrap = yes
+
+ # When word_wrap is set to no, specify where to make an ellipsis in long lines.
+ # Possible values are "start", "middle" and "end".
+ ellipsize = middle
+
+ # Ignore newlines '\n' in notifications.
+ ignore_newline = no
+
+ # Stack together notifications with the same content
+ stack_duplicates = true
+
+ # Hide the count of stacked notifications with the same content
+ hide_duplicate_count = false
+
+ # Display indicators for URLs (U) and actions (A).
+ show_indicators = yes
+
+ ### Icons ###
+
+ # Align icons left/right/off
+ icon_position = left
+
+ # Scale larger icons down to this size, set to 0 to disable
+ max_icon_size = 32
+
+ # Paths to default icons.
+ icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
+
+ ### History ###
+
+ # Should a notification popped up from history be sticky or timeout
+ # as if it would normally do.
+ sticky_history = yes
+
+ # Maximum amount of notifications kept in history
+ history_length = 20
+
+ ### Misc/Advanced ###
+
+ # dmenu path.
+ dmenu = /usr/bin/rofi -p dunst:
+
+ # Browser for opening urls in context menu.
+ browser = /usr/bin/firefox -new-tab
+
+ # Always run rule-defined scripts, even if the notification is suppressed
+ always_run_script = true
+
+ # Define the title of the windows spawned by dunst
+ title = Dunst
+
+ # Define the class of the windows spawned by dunst
+ class = Dunst
+
+ # Print a notification on startup.
+ # This is mainly for error detection, since dbus (re-)starts dunst
+ # automatically after a crash.
+ startup_notification = false
+
+ # Manage dunst's desire for talking
+ # Can be one of the following values:
+ # crit: Critical features. Dunst aborts
+ # warn: Only non-fatal warnings
+ # mesg: Important Messages
+ # info: all unimportant stuff
+ # debug: all less than unimportant stuff
+ verbosity = mesg
+
+ # Define the corner radius of the notification window
+ # in pixel size. If the radius is 0, you have no rounded
+ # corners.
+ # The radius will be automatically lowered if it exceeds half of the
+ # notification height to avoid clipping text and/or icons.
+ corner_radius = 0
+
+ ### Legacy
+
+ # Use the Xinerama extension instead of RandR for multi-monitor support.
+ # This setting is provided for compatibility with older nVidia drivers that
+ # do not support RandR and using it on systems that support RandR is highly
+ # discouraged.
+ #
+ # By enabling this setting dunst will not be able to detect when a monitor
+ # is connected or disconnected which might break follow mode if the screen
+ # layout changes.
+ force_xinerama = false
+
+ ### mouse
+
+ # Defines action of mouse event
+ # Possible values are:
+ # * none: Don't do anything.
+ # * do_action: If the notification has exactly one action, or one is marked as default,
+ # invoke it. If there are multiple and no default, open the context menu.
+ # * close_current: Close current notification.
+ # * close_all: Close all notifications.
+ mouse_left_click = close_current
+ mouse_middle_click = do_action
+ mouse_right_click = close_all
+
+# Experimental features that may or may not work correctly. Do not expect them
+# to have a consistent behaviour across releases.
+[experimental]
+ # Calculate the dpi to use on a per-monitor basis.
+ # If this setting is enabled the Xft.dpi value will be ignored and instead
+ # dunst will attempt to calculate an appropriate dpi value for each monitor
+ # using the resolution and physical size. This might be useful in setups
+ # where there are multiple screens with very different dpi values.
+ per_monitor_dpi = false
+
+[shortcuts]
+
+ # Shortcuts are specified as [modifier+][modifier+]...key
+ # Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
+ # "mod3" and "mod4" (windows-key).
+ # Xev might be helpful to find names for keys.
+
+ # Close notification.
+ close = ctrl+space
+
+ # Close all notifications.
+ close_all = ctrl+shift+space
+
+ # Redisplay last message(s).
+ # On the US keyboard layout "grave" is normally above TAB and left
+ # of "1". Make sure this key actually exists on your keyboard layout,
+ # e.g. check output of 'xmodmap -pke'
+ history = ctrl+grave
+
+ # Context menu.
+ context = ctrl+shift+period
+
+[urgency_low]
+ # IMPORTANT: colors have to be defined in quotation marks.
+ # Otherwise the "#" and following would be interpreted as a comment.
+ # background = "#222222"
+ # foreground = "#888888"
+ background = "#fdf6e3"
+ foreground = "#93a1a1"
+ frame_color = "#93a1a1"
+ timeout = 10
+ # Icon for notifications with low urgency, uncomment to enable
+ #icon = /path/to/icon
+
+[urgency_normal]
+ background = "#fdf6e3"
+ foreground = "#002b36"
+ frame_color = "#002b36"
+ timeout = 10
+ # Icon for notifications with normal urgency, uncomment to enable
+ #icon = /path/to/icon
+
+[urgency_critical]
+ #background = "#900000"
+ #foreground = "#ffffff"
+ #frame_color = "#ff0000"
+ background = "#dc322f"
+ foreground = "#eee8d5"
+ frame_color = "#cb4b16"
+ timeout = 0
+ # Icon for notifications with critical urgency, uncomment to enable
+ #icon = /path/to/icon
+
+# Every section that isn't one of the above is interpreted as a rules to
+# override settings for certain messages.
+#
+# Messages can be matched by
+# appname (discouraged, see desktop_entry)
+# body
+# category
+# desktop_entry
+# icon
+# match_transient
+# msg_urgency
+# stack_tag
+# summary
+#
+# and you can override the
+# background
+# foreground
+# format
+# frame_color
+# fullscreen
+# new_icon
+# set_stack_tag
+# set_transient
+# timeout
+# urgency
+#
+# Shell-like globbing will get expanded.
+#
+# Instead of the appname filter, it's recommended to use the desktop_entry filter.
+# GLib based applications export their desktop-entry name. In comparison to the appname,
+# the desktop-entry won't get localized.
+#
+# SCRIPTING
+# You can specify a script that gets run when the rule matches by
+# setting the "script" option.
+# The script will be called as follows:
+# script appname summary body icon urgency
+# where urgency can be "LOW", "NORMAL" or "CRITICAL".
+#
+# NOTE: if you don't want a notification to be displayed, set the format
+# to "".
+# NOTE: It might be helpful to run dunst -print in a terminal in order
+# to find fitting options for rules.
+
+# Disable the transient hint so that idle_threshold cannot be bypassed from the
+# client
+#[transient_disable]
+# match_transient = yes
+# set_transient = no
+#
+# Make the handling of transient notifications more strict by making them not
+# be placed in history.
+#[transient_history_ignore]
+# match_transient = yes
+# history_ignore = yes
+
+# fullscreen values
+# show: show the notifications, regardless if there is a fullscreen window opened
+# delay: displays the new notification, if there is no fullscreen window active
+# If the notification is already drawn, it won't get undrawn.
+# pushback: same as delay, but when switching into fullscreen, the notification will get
+# withdrawn from screen again and will get delayed like a new notification
+#[fullscreen_delay_everything]
+# fullscreen = delay
+#[fullscreen_show_critical]
+# msg_urgency = critical
+# fullscreen = show
+
+#[espeak]
+# summary = "*"
+# script = dunst_espeak.sh
+
+#[script-test]
+# summary = "*script*"
+# script = dunst_test.sh
+
+#[ignore]
+# # This notification will not be displayed
+# summary = "foobar"
+# format = ""
+
+#[history-ignore]
+# # This notification will not be saved in history
+# summary = "foobar"
+# history_ignore = yes
+
+#[skip-display]
+# # This notification will not be displayed, but will be included in the history
+# summary = "foobar"
+# skip_display = yes
+
+#[signed_on]
+# appname = Pidgin
+# summary = "*signed on*"
+# urgency = low
+#
+#[signed_off]
+# appname = Pidgin
+# summary = *signed off*
+# urgency = low
+#
+#[says]
+# appname = Pidgin
+# summary = *says*
+# urgency = critical
+#
+#[twitter]
+# appname = Pidgin
+# summary = *twitter.com*
+# urgency = normal
+#
+#[stack-volumes]
+# appname = "some_volume_notifiers"
+# set_stack_tag = "volume"
+#
+# vim: ft=cfg
+[sound]
+ summary = "*"
+ script = ~/Scripts/dunst_message.sh
diff --git a/config/fontconfig/avail/01-noto.conf b/config/fontconfig/avail/01-noto.conf
new file mode 100644
index 0000000..84c8b03
--- /dev/null
+++ b/config/fontconfig/avail/01-noto.conf
@@ -0,0 +1,112 @@
+
+
+
+
+ Bitstream Vera Serif
+
+
+
+ Bitstream Vera Serif
+
+
+
+ serif
+
+
+
+
+
+
+ serif
+
+
+
+ Bitstream Vera Serif
+
+
+
+ Noto Color Emoji
+
+
+
+
+
+
+ Bitstream Vera Sans
+
+
+
+ Bitstream Vera Sans
+
+
+
+ sans-serif
+
+
+
+
+
+
+ sans-serif
+
+
+
+ Bitstream Vera Sans
+
+
+
+ Noto Color Emoji
+
+
+
+
+
+
+ Bitstream Vera Sans Mono
+
+
+
+ Bitstream Vera Sans Mono
+
+
+
+ monospace
+
+
+
+
+
+
+ monospace
+
+
+
+ Bitstream Vera Sans Mono
+
+
+
+ Noto Color Emoji
+
+
+
+
+
+ emoji
+ Noto Color Emoji
+
+
+
+
+ Apple Color Emoji
+ Noto Color Emoji
+ sans-serif
+
+
+ Segoe UI Emoji
+ Noto Color Emoji
+ sans-serif
+
+
diff --git a/config/fontconfig/avail/69-emoji-monospace.conf b/config/fontconfig/avail/69-emoji-monospace.conf
new file mode 100644
index 0000000..18dd393
--- /dev/null
+++ b/config/fontconfig/avail/69-emoji-monospace.conf
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+ monospace
+
+ emoji
+ Liberation Mono
+ Fira Mono
+
+
+
+
diff --git a/config/fontconfig/avail/69-emoji.conf b/config/fontconfig/avail/69-emoji.conf
new file mode 100644
index 0000000..b688183
--- /dev/null
+++ b/config/fontconfig/avail/69-emoji.conf
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+ sans-serif
+
+ emoji
+
+
+
+
+ serif
+
+ emoji
+
+
+
+
diff --git a/config/fontconfig/avail/70-no-dejavu.conf b/config/fontconfig/avail/70-no-dejavu.conf
new file mode 100644
index 0000000..d09ec74
--- /dev/null
+++ b/config/fontconfig/avail/70-no-dejavu.conf
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+ DejaVu Sans
+
+
+
+
+ DejaVu Serif
+
+
+
+
+ DejaVu Sans Mono
+
+
+
+
+
+
diff --git a/config/fontconfig/avail/70-no-mozilla-emoji.conf b/config/fontconfig/avail/70-no-mozilla-emoji.conf
new file mode 100644
index 0000000..4eea6ed
--- /dev/null
+++ b/config/fontconfig/avail/70-no-mozilla-emoji.conf
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+ EmojiOne Mozilla
+
+
+
+
+ Twemoji Mozilla
+
+
+
+
+
+
diff --git a/config/fontconfig/fonts.conf b/config/fontconfig/fonts.conf
new file mode 100644
index 0000000..374a45d
--- /dev/null
+++ b/config/fontconfig/fonts.conf
@@ -0,0 +1,64 @@
+
+
+
+
+
+ true
+ true
+ lcddefault
+ hintnone
+
+
+ rgb
+
+
+
+ 15
+ hintnone
+ lcdlight
+
+
+
+ 12
+ hintnone
+ lcdlight
+
+
+
+ 0
+ hintnone
+ lcdlight
+
+
+ verdana
+ Bitstream Vera Sans
+
+
+
+
+ sans-serif
+
+ Liberation Sans
+
+ Liberation Sans
+
+
+
+ serif
+
+ Liberation Serif
+
+ Liberation Serif
+
+
+
+
diff --git a/config/fontconfig/with-dejavu-emojiless.sh b/config/fontconfig/with-dejavu-emojiless.sh
new file mode 100644
index 0000000..8b8b1ee
--- /dev/null
+++ b/config/fontconfig/with-dejavu-emojiless.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+rm ./conf.d/70-no-dejavu.conf
+
+echo "Removed configuration"
diff --git a/config/gallery-dl/config.json b/config/gallery-dl/config.json
new file mode 100644
index 0000000..221b95f
--- /dev/null
+++ b/config/gallery-dl/config.json
@@ -0,0 +1,51 @@
+{
+ "extractor": {
+ "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0",
+ "cookies": "~/cookies.txt",
+ "base-directory": "~/Lataukset/gallery-dl/",
+ "archive": "~/Lataukset/gallery-dl/archive.sqlite3",
+ "exhentai":
+ {
+ "filename": "{num:>04}_{name}.{extension}",
+ "directory": ["{category!c}", "{title}"],
+ "postprocessors": [
+ {
+ "name": "zip",
+ "compression": "store",
+ "extension": "cbz"
+ }
+ ],
+ "wait-min": 1.0,
+ "wait-max": 5.0
+ }
+ },
+ "downloader": {
+ "part-directory": "/tmp/.download/",
+ "rate": "1M",
+ "retries": 3,
+ "timeout": 8.5
+ },
+ "output":
+ {
+ "mode": "terminal",
+ "log": {
+ "format": "{name}: {message}",
+ "level": "info"
+ },
+ "logfile": {
+ "path": "~/Lataukset/gallery-dl/log.txt",
+ "mode": "w",
+ "level": "debug"
+ },
+ "unsupportedfile": {
+ "path": "~/Lataukset/gallery-dl/unsupported.txt",
+ "mode": "a",
+ "format": "{asctime} {message}",
+ "format-date": "%Y-%m-%d-%H-%M-%S"
+ }
+ },
+
+ "cache": {
+ "file": "~/Lataukset/gallery-dl/cache.sqlite3"
+ }
+}
diff --git a/config/i3/background.png b/config/i3/background.png
new file mode 100644
index 0000000..28d5059
Binary files /dev/null and b/config/i3/background.png differ
diff --git a/config/i3/config b/config/i3/config
new file mode 100644
index 0000000..256ad99
--- /dev/null
+++ b/config/i3/config
@@ -0,0 +1,422 @@
+# i3 config file (v4)
+#
+# Please see https://i3wm.org/docs/userguide.html for a complete reference!
+#
+# This config file uses keycodes (bindsym) and was written for the QWERTY
+# layout.
+#
+# To get a config file with the same key positions, but for your current
+# layout, use the i3-config-wizard
+#
+
+# Font for window titles. Will also be used by the bar unless a different font
+# is used in the bar {} block below.
+font pango:DejaVu Sans Mono 10
+
+# This font is widely installed, provides lots of unicode glyphs, right-to-left
+# text rendering and scalability on retina/hidpi displays (thanks to pango).
+#font pango:DejaVu Sans Mono 8
+
+# The combination of xss-lock, nm-applet and pactl is a popular choice, so
+# they are included here as an example. Modify as you see fit.
+
+# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
+# screen before suspend. Use loginctl lock-session to lock your screen.
+#exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
+
+# NetworkManager is the most popular way to manage wireless networks on Linux,
+# and nm-applet is a desktop environment-independent system tray GUI for it.
+#exec --no-startup-id nm-applet
+
+# Use pactl to adjust volume in PulseAudio.
+set $refresh_i3status killall -SIGUSR1 i3status
+bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5% && $refresh_i3status
+bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5% && $refresh_i3status
+bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
+bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
+
+# use these keys for focus, movement, and resize directions when reaching for
+# the arrows is not convenient
+set $up Up
+set $down Down
+set $left Left
+set $right Right
+
+# use Mouse+Mod4 to drag floating windows to their wanted position
+floating_modifier Mod4
+
+# start a terminal
+bindsym Mod4+Return exec i3-sensible-terminal
+
+# kill focused window
+bindsym Mod4+Shift+q kill
+
+# start dmenu (a program launcher)
+#bindsym Mod1+d exec --no-startup-id dmenu_run
+# A more modern dmenu replacement is rofi:
+bindsym Mod4+d exec --no-startup-id "rofi -modi power:'/home/lanxu/.config/rofi/scripts/powermenu.sh',combi -combi-modi 'window,power,run,ssh' -show combi"
+# There also is i3-dmenu-desktop which only displays applications shipping a
+# .desktop file. It is a wrapper around dmenu, so you need that installed.
+# bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop
+
+# change focus
+bindsym Mod4+$left focus left
+bindsym Mod4+$down focus down
+bindsym Mod4+$up focus up
+bindsym Mod4+$right focus right
+
+# alternatively, you can use the cursor keys:
+#bindsym Mod4+Left focus left
+#bindsym Mod4+Down focus down
+#bindsym Mod4+Up focus up
+#bindsym Mod4+Right focus right
+
+# move focused window
+bindsym Mod4+Shift+$left move left
+bindsym Mod4+Shift+$down move down
+bindsym Mod4+Shift+$up move up
+bindsym Mod4+Shift+$right move right
+
+# alternatively, you can use the cursor keys:
+#bindsym Mod4+Shift+Left move left
+#bindsym Mod4+Shift+Down move down
+#bindsym Mod4+Shift+Up move up
+#bindsym Mod4+Shift+Right move right
+
+# split in horizontal orientation
+bindsym Mod4+h split h
+
+# split in vertical orientation
+bindsym Mod4+v split v
+
+# enter fullscreen mode for the focused container
+bindsym Mod4+f fullscreen toggle
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym Mod4+s layout stacking
+bindsym Mod4+w layout tabbed
+bindsym Mod4+e layout toggle split
+
+# toggle tiling / floating
+bindsym Mod4+Shift+space floating toggle
+
+# change focus between tiling / floating windows
+bindsym Mod4+space focus mode_toggle
+
+# focus the parent container
+bindsym Mod4+a focus parent
+
+# focus the child container
+#bindsym Mod4+d focus child
+
+# move the currently focused window to the scratchpad
+bindsym Mod4+Shift+minus move scratchpad
+
+# Show the next scratchpad window or hide the focused scratchpad window.
+# If there are multiple scratchpad windows, this command cycles through them.
+bindsym Mod4+minus scratchpad show
+
+# Define names for default workspaces for which we configure key bindings later on.
+# We use variables to avoid repeating the names in multiple places.
+set $ws1 "1:term"
+set $ws2 "2:irc"
+set $ws3 "3:net"
+set $ws4 "4:gfx"
+set $ws5 "5:steam"
+set $ws6 "6:lutris"
+set $ws7 "7:x"
+set $ws8 "8:x"
+set $ws9 "9:pw"
+set $ws10 "10:tray"
+
+# switch to workspace
+bindsym Mod4+1 workspace $ws1
+bindsym Mod4+2 workspace $ws2
+bindsym Mod4+3 workspace $ws3
+bindsym Mod4+4 workspace $ws4
+bindsym Mod4+5 workspace $ws5
+bindsym Mod4+6 workspace $ws6
+bindsym Mod4+7 workspace $ws7
+bindsym Mod4+8 workspace $ws8
+bindsym Mod4+9 workspace $ws9
+bindsym Mod4+0 workspace $ws10
+# move focused container to workspace
+bindsym Mod4+Shift+1 move container to workspace $ws1
+bindsym Mod4+Shift+2 move container to workspace $ws2
+bindsym Mod4+Shift+3 move container to workspace $ws3
+bindsym Mod4+Shift+4 move container to workspace $ws4
+bindsym Mod4+Shift+5 move container to workspace $ws5
+bindsym Mod4+Shift+6 move container to workspace $ws6
+bindsym Mod4+Shift+7 move container to workspace $ws7
+bindsym Mod4+Shift+8 move container to workspace $ws8
+bindsym Mod4+Shift+9 move container to workspace $ws9
+bindsym Mod4+Shift+0 move container to workspace $ws10
+
+# reload the configuration file
+bindsym Mod4+Shift+c reload
+# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
+bindsym Mod4+Shift+r restart
+# exit i3 (logs you out of your X session)
+bindsym Mod4+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
+
+# resize window (you can also use the mouse for that)
+mode "resize" {
+ # These bindings trigger as soon as you enter the resize mode
+
+ # Pressing left will shrink the window’s width.
+ # Pressing right will grow the window’s width.
+ # Pressing up will shrink the window’s height.
+ # Pressing down will grow the window’s height.
+ bindsym $left resize shrink width 10 px or 10 ppt
+ bindsym $down resize grow height 10 px or 10 ppt
+ bindsym $up resize shrink height 10 px or 10 ppt
+ bindsym $right resize grow width 10 px or 10 ppt
+
+ # same bindings, but for the arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # Back to normal: Enter or Escape or Mod4+r
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+ bindsym Mod4+r mode "default"
+}
+
+bindsym Mod1+r mode "resize"
+
+# Start i3bar to display a workspace bar (plus the system information i3status
+# finds out, if available)
+#bar {
+# status_command i3status
+#}
+
+#######################################################################
+# automatically start i3-config-wizard to offer the user to create a
+# keysym-based config which used their favorite modifier (alt or windows)
+#
+# i3-config-wizard will not launch if there already is a config file
+# in ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) or
+# ~/.i3/config.
+#
+# Please remove the following exec line:
+#######################################################################
+#exec i3-config-wizard
+
+#######################################################################
+# lanxu's modifications
+#######################################################################
+
+# Assignments
+assign [class="^firefox$"] → $ws3
+assign [class="^krita$"] → $ws4
+assign [class="^Blender$"] → $ws4
+assign [class="^Gimp$"] → $ws4
+assign [class="^Lutris$"] → $ws6
+assign [class="^Nextcloud$"] → $ws10
+assign [class="^Blueman-manager$"] → $ws10
+assign [class="^Pavucontrol$"] → $ws10
+assign [class="^cantata$"] → $ws10
+assign [class="^Boincmgr$"] → $ws10
+assign [class="^KeePassXC$"] → $ws9
+
+# Modifiers
+for_window [class="^firefox$"] layout tabbed
+for_window [class="Arandr"] floating enable
+for_window [title="^Telegram$"] floating enable, move scratchpad
+for_window [class="itch"] floating enable
+# for_window [class="Wine"] floating enable
+for_window [class="mpv"] floating enable, move position center
+for_window [class="vlc"] floating enable
+for_window [class="Mumble"] floating enable, move position center
+for_window [class="Sxiv"] floating enable
+
+# services
+#for_window [class="Nextcloud"] floating enable, move position center, move scratchpad
+for_window [class="cantata"] floating disable
+for_window [class="boincmgr"] floating disable
+
+# Games
+for_window [class="kfgame.exe"] floating enable
+for_window [class="Wine"] floating enable
+for_window [class="xscreensaver-demo"] floating enable
+
+# Steam
+# https://github.com/ValveSoftware/steam-for-linux/issues/1040
+for_window [class="^Steam$" title="^Friends$"] floating enable
+for_window [class="^Steam$" title="Steam - News"] floating enable
+for_window [class="^Steam$" title=".* - Chat"] floating enable
+for_window [class="^Steam$" title="^Settings$"] floating enable
+for_window [class="^Steam$" title=".* - event started"] floating enable
+for_window [class="^Steam$" title=".* CD key"] floating enable
+for_window [class="^Steam$" title="^Steam - Self Updater$"] floating enable
+for_window [class="^Steam$" title="^Screenshot Uploader$"] floating enable
+for_window [class="^Steam$" title="^Steam Guard - Computer Authorization Required$"] floating enable
+for_window [title="^Steam Keyboard$"] floating enable
+for_window [class="^Steam$"] move container to workspace $ws5
+for_window [title="^Friends List$"] move container to workspace $ws5, floating enable, resize set width 400px
+
+mouse_warping none
+
+# Special keysyms
+bindsym Mod4+t [class="TelegramDesktop"] scratchpad show
+bindsym Mod4+n [class="^Nextcloud"] scratchpad show
+
+# i3-gaps
+#smart_borders on
+#smart_gaps on
+#gaps outer 0
+#gaps inner 5
+
+
+## Base16 Gruvbox dark, hard
+# Author: Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
+#
+# You can use these variables anywhere in the i3 configuration file.
+
+set $base00 #1d2021
+set $base01 #3c3836
+set $base02 #504945
+set $base03 #665c54
+set $base04 #bdae93
+set $base05 #d5c4a1
+set $base06 #ebdbb2
+set $base07 #fbf1c7
+set $base08 #fb4934
+set $base09 #fe8019
+set $base0A #fabd2f
+set $base0B #b8bb26
+set $base0C #8ec07c
+set $base0D #83a598
+set $base0E #d3869b
+set $base0F #d65d0e
+
+
+# https://github.com/khamer/base16-i3/tree/master/colors
+
+## Base16 Solarized Light
+# Author: Ethan Schoonover (modified by aramisgithub)
+#
+# You can use these variables anywhere in the i3 configuration file.
+
+#set $base00 #fdf6e3
+#set $base01 #eee8d5
+#set $base02 #93a1a1
+#set $base03 #839496
+#set $base04 #657b83
+#set $base05 #586e75
+#set $base06 #073642
+#set $base07 #002b36
+#set $base08 #dc322f
+#set $base09 #cb4b16
+#set $base0A #b58900
+#set $base0B #859900
+#set $base0C #2aa198
+#set $base0D #268bd2
+#set $base0E #6c71c4
+#set $base0F #d33682
+
+## Base16 Solarized Dark
+# Author: Ethan Schoonover (modified by aramisgithub)
+#
+# You can use these variables anywhere in the i3 configuration file.
+
+#set $base00 #002b36
+#set $base01 #073642
+#set $base02 #586e75
+#set $base03 #657b83
+#set $base04 #839496
+#set $base05 #93a1a1
+#set $base06 #eee8d5
+#set $base07 #fdf6e3
+#set $base08 #dc322f
+#set $base09 #cb4b16
+#set $base0A #b58900
+#set $base0B #859900
+#set $base0C #2aa198
+#set $base0D #268bd2
+#set $base0E #6c71c4
+#set $base0F #d33682
+
+# Basic bar configuration using the Base16 variables.
+bar {
+ font pango: DejaVu Sans Mono Bold 10
+ mode dock
+ status_command py3status
+ position top
+ i3bar_command i3bar -t
+ tray_output none
+ separator_symbol " "
+
+ colors {
+ background $base00
+ separator $base03
+ statusline $base04
+
+ # State Border BG Text
+ focused_workspace $base05 $base0D $base00
+ active_workspace $base05 $base03 $base05
+ inactive_workspace $base03 $base01 $base05
+ urgent_workspace $base08 $base08 $base00
+ binding_mode $base00 $base0A $base00
+ }
+}
+
+# Basic color configuration using the Base16 variables for windows and borders.
+# Property Name Border BG Text Indicator Child Border
+client.focused $base05 $base0D $base00 $base0D $base0C
+client.focused_inactive $base01 $base01 $base05 $base03 $base01
+client.unfocused $base01 $base00 $base05 $base01 $base01
+client.urgent $base08 $base08 $base00 $base08 $base08
+client.placeholder $base00 $base00 $base05 $base00 $base00
+client.background $base07
+
+default_border pixel 1
+# Removes all borders
+for_window [class=".*"] border pixel 1
+
+#exec --no-startup-id "dunst" # in case multiple daemons are installed
+#exec --no-startup-id "pasystray"
+#exec --no-startup-id "blueman-applet"
+#exec --no-startup-id "udiskie --tray --notify --automount"
+
+# Services
+exec --no-startup-id "mpd /home/lanxu/.config/mpd/mpd.conf" # Music Player Daemon
+exec --no-startup-id xss-lock -- lock.sh
+exec --no-startup-id "./Scripts/screensaver.sh" # Screensaver
+#exec --no-startup-id "xscreensaver -no-splash" # Screensaver
+#exec --no-startup-id "./Scripts/xscreensaverstopper.sh" # Screensaver inhibitor
+#exec --no-startup-id "compton -b" # Compositor
+exec --no-startup-id "nitrogen --restore" # Wallpaper
+exec --no-startup-id "udiskie --notify --automount" # Automounter
+# dunst is used for notifications
+
+# Background software
+#exec --no-startup-id "blueman-manager" # Bluetooth
+exec --no-startup-id "cantata"
+#exec --no-startup-id "boincmgr"
+#exec --no-startup-id "nextcloud"
+exec --no-startup-id "pavucontrol"
+exec --no-startup-id "keepassxc" # Password manager
+
+# Applications
+exec --no-startup-id "telegram-desktop"
+
+# Set manual layout for tray workspace
+#exec --no-startup-id "i3-msg 'workspace 10:tray; append_layout /home/lanxu/.config/i3/tray.json'"
+
+bindsym XF86AudioStop exec --no-startup-id mpc stop
+bindsym XF86AudioPlay exec --no-startup-id mpc play
+bindsym XF86AudioPause exec --no-startup-id mpc pause
+bindsym XF86AudioNext exec --no-startup-id mpc next
+bindsym XF86AudioPrev exec --no-startup-id mpc prev
+
+# Print screen
+bindsym Print exec --no-startup-id flameshot gui
+bindsym Mod4+l exec --no-startup-id "loginctl lock-session"
+
+# Moving desktops
+bindsym Mod4+o move workspace to output left
+bindsym Mod4+Ctrl+Right move workspace to output right
+bindsym Mod4+Ctrl+Left move workspace to output left
diff --git a/config/i3/i3status.conf b/config/i3/i3status.conf
new file mode 100644
index 0000000..cfdd739
--- /dev/null
+++ b/config/i3/i3status.conf
@@ -0,0 +1,52 @@
+general {
+ # These will be used if not supplied by a module
+ # Solarized
+ #color = '#073642' # base0
+ color = '#93a1a1' # base1
+ color_good = '#859900'
+ color_degraded = '#b58900'
+ color_bad = '#dc322f'
+}
+py3status {
+ align = 'center'
+ markup = 'pango'
+ min_width = 50
+ separator = True
+ separator_block_width = 20
+ border = '#4c7899'
+ #border = '#073642'
+ border_bottom = 0
+ border_left = 0
+ border_right = 0
+ border_top = 0
+}
+
+time {
+ format = "%Y-%m-%d %H:%M "
+}
+
+mpd_status {
+ format = "[[[{artist} - ]{title}]|[{file}]]"
+ max_width = 30
+}
+
+volume_status {
+ command = "pactl"
+}
+
+weather_owm {
+ api_key = "4e3b7bbd3da07052c4fed6d342e48707"
+ city = "Tampere"
+ unit_temperature = "C"
+ format_temperature = "[\?color=all {current:.0f}°{unit}]"
+ format = "{city} {icon} {temperature}"
+}
+
+order += "net_status"
+order += "dpms"
+order += "volume_status"
+order += "sysdata"
+order += "gpu_temp"
+order += "weather_owm"
+order += "mpd_status"
+order += "time"
diff --git a/config/i3/py3status/gpu_temp.py b/config/i3/py3status/gpu_temp.py
new file mode 100644
index 0000000..11bf24d
--- /dev/null
+++ b/config/i3/py3status/gpu_temp.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+"""
+This module produces GPU temperature
+
+"""
+import sys
+sys.path.insert(1, '/home/lanxu/Scripts/')
+from gputemp import get_temperature
+
+class Py3status:
+ format = 'GPU: {temp}℃'
+ thresholds = [
+ (0, "good"),
+ (50, "degraded"),
+ (70, "bad")
+ ]
+
+ def gpu_temp(self):
+ temp = float(get_temperature())
+
+ full_text = self.py3.safe_format(self.format, { 'temp': temp})
+ color = self.py3.threshold_get_color(temp)
+
+ return {
+ 'full_text': full_text,
+ 'color': color,
+ 'cached_until': self.py3.time_in(15)
+ }
diff --git a/config/i3/py3status/net_status.py b/config/i3/py3status/net_status.py
new file mode 100644
index 0000000..93e53cd
--- /dev/null
+++ b/config/i3/py3status/net_status.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+"""
+This module produces list of enabled network interfaces
+
+"""
+import sys
+import subprocess
+from subprocess import check_output
+
+class Py3status:
+ format = 'NET: {status}'
+
+ def net_status(self):
+ # Retrieve active connections, Ignore bridges
+ command = 'nmcli --mode multiline --colors no con show --active | rg DEVICE | awk -F":" \'{ gsub(/ /, ""); print $2}\' | rg \'^[^br-]\''
+ return_value = check_output(command, shell=True)
+ value = return_value.decode("utf-8")
+ value = value.replace('\n', ', ').strip(', ')
+ full_text = self.py3.safe_format(self.format, { 'status': value})
+
+ return {
+ 'full_text': full_text,
+ 'cached_until': self.py3.time_in(15)
+ }
diff --git a/config/i3/tray.json b/config/i3/tray.json
new file mode 100644
index 0000000..3ce486a
--- /dev/null
+++ b/config/i3/tray.json
@@ -0,0 +1,104 @@
+{
+ // splitv split container with 2 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splitv",
+ "percent": 0.5,
+ "type": "con",
+ "nodes": [
+ {
+ // splitv split container with 1 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splitv",
+ "percent": 0.5,
+ "type": "con",
+ "nodes": [
+ {
+ "border": "pixel",
+ "current_border_width": 0,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 514,
+ "width": 945,
+ "x": 0,
+ "y": 0
+ },
+ "name": "Äänenvoimakkuus",
+ "percent": 1,
+ "swallows": [
+ {
+ "class": "^Pavucontrol$"
+ // "instance": "^pavucontrol$",
+ // "title": "^Äänenvoimakkuus$"
+ }
+ ],
+ "type": "con"
+ }
+ ]
+ },
+ {
+ // splith split container with 1 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splith",
+ "percent": 0.5,
+ "type": "con",
+ "nodes": [
+ {
+ "border": "pixel",
+ "current_border_width": 0,
+ "floating": "auto_off",
+ "geometry": {
+ "height": 950,
+ "width": 1223,
+ "x": 0,
+ "y": 0
+ },
+ "name": "Cantata",
+ "percent": 1,
+ "swallows": [
+ {
+ "class": "^cantata$"
+ // "instance": "^cantata$",
+ // "title": "^Cantata$"
+ }
+ ],
+ "type": "con"
+ }
+ ]
+ }
+ ]
+}
+
+{
+ // splitv split container with 2 children
+ "border": "pixel",
+ "floating": "auto_off",
+ "layout": "splitv",
+ "percent": 0.5,
+ "type": "con",
+ "nodes": [
+ {
+ "border": "pixel",
+ "current_border_width": 0,
+ "floating": "user_off",
+ "geometry": {
+ "height": 1037,
+ "width": 617,
+ "x": 1455,
+ "y": 33
+ },
+ "name": "Nextcloud",
+ "percent": 0.5,
+ "swallows": [
+ {
+ "class": "^Nextcloud$"
+ // "instance": "^nextcloud$",
+ // "title": "^Nextcloud$"
+ }
+ ],
+ "type": "con"
+ }
+ ]
+}
diff --git a/config/imv/config b/config/imv/config
new file mode 100644
index 0000000..7bc48d6
--- /dev/null
+++ b/config/imv/config
@@ -0,0 +1,4 @@
+[binds]
+y = exec wl-copy < "$imv_current_file"
+d = exec dragon -a -x "$imv_current_file"
+f = fullscreen; reset
diff --git a/config/kitty/kitty.conf b/config/kitty/kitty.conf
new file mode 100644
index 0000000..43f7d99
--- /dev/null
+++ b/config/kitty/kitty.conf
@@ -0,0 +1,139 @@
+font_family Fira Code Medium
+bold_font Fira Code Bold
+italic_font Fira Code Italic
+bold_italic_font auto
+font_size 11.0
+window_padding_width 2.0
+window_padding_height 2.0
+
+# Base16 Gruvbox dark, hard - kitty color config
+# Scheme by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
+background #1d2021
+foreground #d5c4a1
+selection_background #d5c4a1
+selection_foreground #1d2021
+url_color #bdae93
+cursor #d5c4a1
+active_border_color #665c54
+inactive_border_color #3c3836
+active_tab_background #1d2021
+active_tab_foreground #d5c4a1
+inactive_tab_background #3c3836
+inactive_tab_foreground #bdae93
+tab_bar_background #3c3836
+
+# normal
+color0 #1d2021
+color1 #fb4934
+color2 #b8bb26
+color3 #fabd2f
+color4 #83a598
+color5 #d3869b
+color6 #8ec07c
+color7 #d5c4a1
+
+# bright
+color8 #665c54
+color9 #fb4934
+color10 #b8bb26
+color11 #fabd2f
+color12 #83a598
+color13 #d3869b
+color14 #8ec07c
+color15 #fbf1c7
+
+# extended base16 colors
+color16 #fe8019
+color17 #d65d0e
+color18 #3c3836
+color19 #504945
+color20 #bdae93
+color21 #ebdbb2
+
+## Base16 Solarized Dark - kitty color config
+## Scheme by Ethan Schoonover (modified by aramisgithub)
+#background #002b36
+#foreground #93a1a1
+#selection_background #93a1a1
+#selection_foreground #002b36
+#url_color #839496
+#cursor #93a1a1
+#active_border_color #657b83
+#inactive_border_color #073642
+#active_tab_background #002b36
+#active_tab_foreground #93a1a1
+#inactive_tab_background #073642
+#inactive_tab_foreground #839496
+#tab_bar_background #073642
+#
+## normal
+#color0 #002b36
+#color1 #dc322f
+#color2 #859900
+#color3 #b58900
+#color4 #268bd2
+#color5 #6c71c4
+#color6 #2aa198
+#color7 #93a1a1
+#
+## bright
+#color8 #657b83
+#color9 #dc322f
+#color10 #859900
+#color11 #b58900
+#color12 #268bd2
+#color13 #6c71c4
+#color14 #2aa198
+#color15 #fdf6e3
+#
+## extended base16 colors
+#color16 #cb4b16
+#color17 #d33682
+#color18 #073642
+#color19 #586e75
+#color20 #839496
+#color21 #eee8d5
+
+# Base16 Default Dark - kitty color config
+## Scheme by Chris Kempson (http://chriskempson.com)
+#background #181818
+#foreground #d8d8d8
+#selection_background #d8d8d8
+#selection_foreground #181818
+#url_color #b8b8b8
+#cursor #d8d8d8
+#active_border_color #585858
+#inactive_border_color #282828
+#active_tab_background #181818
+#active_tab_foreground #d8d8d8
+#inactive_tab_background #282828
+#inactive_tab_foreground #b8b8b8
+#tab_bar_background #282828
+#
+## normal
+#color0 #181818
+#color1 #ab4642
+#color2 #a1b56c
+#color3 #f7ca88
+#color4 #7cafc2
+#color5 #ba8baf
+#color6 #86c1b9
+#color7 #d8d8d8
+#
+## bright
+#color8 #585858
+#color9 #ab4642
+#color10 #a1b56c
+#color11 #f7ca88
+#color12 #7cafc2
+#color13 #ba8baf
+#color14 #86c1b9
+#color15 #f8f8f8
+#
+## extended base16 colors
+#color16 #dc9656
+#color17 #a16946
+#color18 #282828
+#color19 #383838
+#color20 #b8b8b8
+#color21 #e8e8e8
diff --git a/config/kitty/theme-base16-gruvbox-dark.conf b/config/kitty/theme-base16-gruvbox-dark.conf
new file mode 100644
index 0000000..3399014
--- /dev/null
+++ b/config/kitty/theme-base16-gruvbox-dark.conf
@@ -0,0 +1,43 @@
+# Base16 Gruvbox dark, hard - kitty color config
+# Scheme by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox)
+background #1d2021
+foreground #d5c4a1
+selection_background #d5c4a1
+selection_foreground #1d2021
+url_color #bdae93
+cursor #d5c4a1
+active_border_color #665c54
+inactive_border_color #3c3836
+active_tab_background #1d2021
+active_tab_foreground #d5c4a1
+inactive_tab_background #3c3836
+inactive_tab_foreground #bdae93
+tab_bar_background #3c3836
+
+# normal
+color0 #1d2021
+color1 #fb4934
+color2 #b8bb26
+color3 #fabd2f
+color4 #83a598
+color5 #d3869b
+color6 #8ec07c
+color7 #d5c4a1
+
+# bright
+color8 #665c54
+color9 #fb4934
+color10 #b8bb26
+color11 #fabd2f
+color12 #83a598
+color13 #d3869b
+color14 #8ec07c
+color15 #fbf1c7
+
+# extended base16 colors
+color16 #fe8019
+color17 #d65d0e
+color18 #3c3836
+color19 #504945
+color20 #bdae93
+color21 #ebdbb2
diff --git a/config/kitty/theme-base16-solarized-dark.conf b/config/kitty/theme-base16-solarized-dark.conf
new file mode 100644
index 0000000..cdcc683
--- /dev/null
+++ b/config/kitty/theme-base16-solarized-dark.conf
@@ -0,0 +1,43 @@
+# Base16 Solarized Dark - kitty color config
+# Scheme by Ethan Schoonover (modified by aramisgithub)
+background #002b36
+foreground #93a1a1
+selection_background #93a1a1
+selection_foreground #002b36
+url_color #839496
+cursor #93a1a1
+active_border_color #657b83
+inactive_border_color #073642
+active_tab_background #002b36
+active_tab_foreground #93a1a1
+inactive_tab_background #073642
+inactive_tab_foreground #839496
+tab_bar_background #073642
+
+# normal
+color0 #002b36
+color1 #dc322f
+color2 #859900
+color3 #b58900
+color4 #268bd2
+color5 #6c71c4
+color6 #2aa198
+color7 #93a1a1
+
+# bright
+color8 #657b83
+color9 #dc322f
+color10 #859900
+color11 #b58900
+color12 #268bd2
+color13 #6c71c4
+color14 #2aa198
+color15 #fdf6e3
+
+# extended base16 colors
+color16 #cb4b16
+color17 #d33682
+color18 #073642
+color19 #586e75
+color20 #839496
+color21 #eee8d5
diff --git a/config/lf/lfrc b/config/lf/lfrc
new file mode 100644
index 0000000..2e1d422
--- /dev/null
+++ b/config/lf/lfrc
@@ -0,0 +1,26 @@
+set previewer ~/.config/lf/pv.sh
+map i $~/.config/lf/pv.sh $f | less -R
+
+# Trash
+cmd trash %trash-put "$fx"
+
+# Search with fzf
+map f $vi $(fzf)
+
+# Recreate open-with with lf
+cmd open-with %"$@" "$fx"
+map ` push :open-with
+
+# Show current directory in window title
+cmd on-cd &{{
+ # '&' commands run silently in background (which is what we want here),
+ # but are not connected to stdout.
+ # To make sure our escape sequence still reaches stdout we pipe it to /dev/tty
+ printf "\033]0; $PWD\007" > /dev/tty
+}}
+
+map r reload
+
+# Drag and drop
+map %dragon --all --and-exit "$fx"
+map &wl-copy < "$fx"
diff --git a/config/lf/pv.sh b/config/lf/pv.sh
new file mode 100755
index 0000000..58483f3
--- /dev/null
+++ b/config/lf/pv.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+SAVEIFS=$IFS
+IFS=$(echo -en "\n\b")
+
+FILE="${1}"
+HEIGHT="${2}"
+
+case "$1" in
+ #*.png|*.jpg|*.jpeg|*.gif|*.webp)viu -w 100 -s "$1";;
+ *.png|*.jpg|*.jpeg|*.gif|*.webp)
+ catimg -w 100 "${FILE}";;
+ *.tar*)
+ tar tf "$1";;
+ *.zip)
+ unzip -l "$1";;
+ *.rar)
+ unrar l "$1";;
+ *.7z)
+ 7z l "$1";;
+ *.pdf)
+ pdftotext "$1" -;;
+ *.mp4|*.avi|*.mkv|*.webm|*.mpg)
+ TMPFILE=$(mktemp)
+ ffmpegthumbnailer -i "${FILE}" -o "${TMPFILE}" -s 0
+ catimg -w 100 "${TMPFILE}";;
+ #mediainfo ${FILE};;
+ *.cbz|*.cbr|*.epub)
+ TMPFILE=$(mktemp)
+ comicthumb.py "${FILE}" "${TMPFILE}" 512 > /dev/null 2>&1
+ echo $TMPFILE
+ catimg -w 100 "${TMPFILE}";;
+ *)
+ bat --color=always --theme=base16 "$1";;
+esac
+
+IFS=$SAVEIFS
diff --git a/config/mimeapps.list b/config/mimeapps.list
new file mode 100644
index 0000000..fede0a1
--- /dev/null
+++ b/config/mimeapps.list
@@ -0,0 +1,32 @@
+[Default Applications]
+application/vnd.comicbook+rar=mcomix.desktop
+application/vnd.comicbook+zip=mcomix.desktop
+application/vnd.rar=xarchiver.desktop
+application/x-cbr=mcomix.desktop
+application/x-cbz=mcomix.desktop
+application/zip=xarchiver.desktop
+application/epub+zip=mcomix.desktop;
+application/octet-stream=gvim.desktop;
+application/pdf=org.pwmt.zathura-pdf-mupdf.desktop;
+application/pgp-signature=gvim.desktop;
+application/vnd.ms-publisher=gvim.desktop;
+application/vnd.rar=mcomix.desktop;xarchiver.desktop;
+application/x-alz=xarchiver.desktop;
+image/gif=sxiv_browser.desktop
+image/jpeg=sxiv_browser.desktop
+image/png=sxiv_browser.desktop
+image/svg+xml=inkscape.desktop
+inode/directory=pcmanfm.desktop
+video/mp4=mpv.desktop
+video/quicktime=mpv.desktop
+video/x-msvideo=mpv.desktop
+video/x-flv=mpv.desktop
+video/x-matroska=mpv.desktop
+text/plain=gvim.desktop
+x-scheme-handler/itchio=io.itch.itch.desktop
+x-terminal-emulator=urxvt.desktop
+x-scheme-handler/discord-378483863044882443=discord-378483863044882443.desktop
+x-scheme-handler/http=firefox.desktop
+
+[Added Associations]
+application/x-blender=blender.desktop;
diff --git a/config/mpd/mpd.conf b/config/mpd/mpd.conf
new file mode 100644
index 0000000..8366678
--- /dev/null
+++ b/config/mpd/mpd.conf
@@ -0,0 +1,424 @@
+# An example configuration file for MPD.
+# Read the user manual for documentation: http://www.musicpd.org/doc/user/
+
+
+# Files and directories #######################################################
+#
+# This setting controls the top directory which MPD will search to discover the
+# available audio files and add them to the daemon's online database. This
+# setting defaults to the XDG directory, otherwise the music directory will be
+# be disabled and audio files will only be accepted over ipc socket (using
+# file:// protocol) or streaming files over an accepted protocol.
+#
+#music_directory "~/music"
+#
+# This setting sets the MPD internal playlist directory. The purpose of this
+# directory is storage for playlists created by MPD. The server will use
+# playlist files not created by the server but only if they are in the MPD
+# format. This setting defaults to playlist saving being disabled.
+#
+#playlist_directory "~/.mpd/playlists"
+#
+# This setting sets the location of the MPD database. This file is used to
+# load the database at server start up and store the database while the
+# server is not up. This setting defaults to disabled which will allow
+# MPD to accept files over ipc socket (using file:// protocol) or streaming
+# files over an accepted protocol.
+#
+#db_file "~/.mpd/database"
+#
+# These settings are the locations for the daemon log files for the daemon.
+# These logs are great for troubleshooting, depending on your log_level
+# settings.
+#
+# The special value "syslog" makes MPD use the local syslog daemon. This
+# setting defaults to logging to syslog, otherwise logging is disabled.
+#
+#log_file "~/.mpd/log"
+#
+# This setting sets the location of the file which stores the process ID
+# for use of mpd --kill and some init scripts. This setting is disabled by
+# default and the pid file will not be stored.
+#
+#pid_file "~/.mpd/pid"
+#
+# This setting sets the location of the file which contains information about
+# most variables to get MPD back into the same general shape it was in before
+# it was brought down. This setting is disabled by default and the server
+# state will be reset on server start up.
+#
+#state_file "~/.mpd/state"
+#
+# The location of the sticker database. This is a database which
+# manages dynamic information attached to songs.
+#
+#sticker_file "~/.mpd/sticker.sql"
+#
+###############################################################################
+
+
+# General music daemon options ################################################
+#
+# This setting specifies the user that MPD will run as. MPD should never run as
+# root and you may use this setting to make MPD change its user ID after
+# initialization. This setting is disabled by default and MPD is run as the
+# current user.
+#
+#user "nobody"
+#
+# This setting specifies the group that MPD will run as. If not specified
+# primary group of user specified with "user" setting will be used (if set).
+# This is useful if MPD needs to be a member of group such as "audio" to
+# have permission to use sound card.
+#
+#group "nogroup"
+#
+# This setting sets the address for the daemon to listen on. Careful attention
+# should be paid if this is assigned to anything other then the default, any.
+# This setting can deny access to control of the daemon.
+#
+# For network
+bind_to_address "127.0.0.1"
+#
+# And for Unix Socket
+#bind_to_address "~/.config/mpd/socket"
+#
+# This setting is the TCP port that is desired for the daemon to get assigned
+# to.
+#
+#port "6600"
+#
+# This setting controls the type of information which is logged. Available
+# setting arguments are "default", "secure" or "verbose". The "verbose" setting
+# argument is recommended for troubleshooting, though can quickly stretch
+# available resources on limited hardware storage.
+#
+#log_level "default"
+#
+# If you have a problem with your MP3s ending abruptly it is recommended that
+# you set this argument to "no" to attempt to fix the problem. If this solves
+# the problem, it is highly recommended to fix the MP3 files with vbrfix
+# (available from ), at which
+# point gapless MP3 playback can be enabled.
+#
+#gapless_mp3_playback "yes"
+#
+# Setting "restore_paused" to "yes" puts MPD into pause mode instead
+# of starting playback after startup.
+#
+#restore_paused "no"
+#
+# This setting enables MPD to create playlists in a format usable by other
+# music players.
+#
+#save_absolute_paths_in_playlists "no"
+#
+# This setting defines a list of tag types that will be extracted during the
+# audio file discovery process. The complete list of possible values can be
+# found in the mpd.conf man page.
+#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
+#
+# This setting enables automatic update of MPD's database when files in
+# music_directory are changed.
+#
+#auto_update "yes"
+#
+# Limit the depth of the directories being watched, 0 means only watch
+# the music directory itself. There is no limit by default.
+#
+#auto_update_depth "3"
+#
+###############################################################################
+
+
+# Symbolic link behavior ######################################################
+#
+# If this setting is set to "yes", MPD will discover audio files by following
+# symbolic links outside of the configured music_directory.
+#
+#follow_outside_symlinks "yes"
+#
+# If this setting is set to "yes", MPD will discover audio files by following
+# symbolic links inside of the configured music_directory.
+#
+#follow_inside_symlinks "yes"
+#
+###############################################################################
+
+
+# Zeroconf / Avahi Service Discovery ##########################################
+#
+# If this setting is set to "yes", service information will be published with
+# Zeroconf / Avahi.
+#
+#zeroconf_enabled "yes"
+#
+# The argument to this setting will be the Zeroconf / Avahi unique name for
+# this MPD server on the network.
+#
+#zeroconf_name "Music Player"
+#
+###############################################################################
+
+
+# Permissions #################################################################
+#
+# If this setting is set, MPD will require password authorization. The password
+# can setting can be specified multiple times for different password profiles.
+#
+#password "password@read,add,control,admin"
+#
+# This setting specifies the permissions a user has who has not yet logged in.
+#
+#default_permissions "read,add,control,admin"
+#
+###############################################################################
+
+
+# Database #######################################################################
+#
+
+#database {
+# plugin "proxy"
+# host "other.mpd.host"
+# port "6600"
+#}
+
+# Input #######################################################################
+#
+
+input {
+ plugin "curl"
+# proxy "proxy.isp.com:8080"
+# proxy_user "user"
+# proxy_password "password"
+}
+
+#
+###############################################################################
+
+# Audio Output ################################################################
+#
+# MPD supports various audio output types, as well as playing through multiple
+# audio outputs at the same time, through multiple audio_output settings
+# blocks. Setting this block is optional, though the server will only attempt
+# autodetection for one sound card.
+#
+# An example of an ALSA output:
+#
+#audio_output {
+# type "alsa"
+# name "My ALSA Device"
+## device "hw:0,0" # optional
+## mixer_type "hardware" # optional
+## mixer_device "default" # optional
+## mixer_control "PCM" # optional
+## mixer_index "0" # optional
+#}
+#
+# An example of an OSS output:
+#
+#audio_output {
+# type "oss"
+# name "My OSS Device"
+## device "/dev/dsp" # optional
+## mixer_type "hardware" # optional
+## mixer_device "/dev/mixer" # optional
+## mixer_control "PCM" # optional
+#}
+#
+# An example of a shout output (for streaming to Icecast):
+#
+#audio_output {
+# type "shout"
+# encoding "ogg" # optional
+# name "My Shout Stream"
+# host "localhost"
+# port "8000"
+# mount "/mpd.ogg"
+# password "hackme"
+# quality "5.0"
+# bitrate "128"
+# format "44100:16:1"
+## protocol "icecast2" # optional
+## user "source" # optional
+## description "My Stream Description" # optional
+## url "http://example.com" # optional
+## genre "jazz" # optional
+## public "no" # optional
+## timeout "2" # optional
+## mixer_type "software" # optional
+#}
+#
+# An example of a recorder output:
+#
+#audio_output {
+# type "recorder"
+# name "My recorder"
+# encoder "vorbis" # optional, vorbis or lame
+# path "/var/lib/mpd/recorder/mpd.ogg"
+## quality "5.0" # do not define if bitrate is defined
+# bitrate "128" # do not define if quality is defined
+# format "44100:16:1"
+#}
+#
+# An example of a httpd output (built-in HTTP streaming server):
+#
+#audio_output {
+# type "httpd"
+# name "My HTTP Stream"
+# encoder "vorbis" # optional, vorbis or lame
+# port "8000"
+# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6
+## quality "5.0" # do not define if bitrate is defined
+# bitrate "128" # do not define if quality is defined
+# format "44100:16:1"
+# max_clients "0" # optional 0=no limit
+#}
+#
+# An example of a pulseaudio output (streaming to a remote pulseaudio server)
+#
+audio_output {
+ type "pulse"
+ name "My Pulse Output"
+# server "remote_server" # optional
+# sink "remote_server_sink" # optional
+}
+#
+# An example of a winmm output (Windows multimedia API).
+#
+#audio_output {
+# type "winmm"
+# name "My WinMM output"
+## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
+# or
+## device "0" # optional
+## mixer_type "hardware" # optional
+#}
+#
+# An example of an openal output.
+#
+#audio_output {
+# type "openal"
+# name "My OpenAL output"
+## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
+#}
+#
+## Example "pipe" output:
+#
+#audio_output {
+# type "pipe"
+# name "my pipe"
+# command "aplay -f cd 2>/dev/null"
+## Or if you're want to use AudioCompress
+# command "AudioCompress -m | aplay -f cd 2>/dev/null"
+## Or to send raw PCM stream through PCM:
+# command "nc example.org 8765"
+# format "44100:16:2"
+#}
+#
+## An example of a null output (for no audio output):
+#
+#audio_output {
+# type "null"
+# name "My Null Output"
+# mixer_type "none" # optional
+#}
+#
+# If MPD has been compiled with libsamplerate support, this setting specifies
+# the sample rate converter to use. Possible values can be found in the
+# mpd.conf man page or the libsamplerate documentation. By default, this is
+# setting is disabled.
+#
+#samplerate_converter "Fastest Sinc Interpolator"
+#
+###############################################################################
+
+
+# Normalization automatic volume adjustments ##################################
+#
+# This setting specifies the type of ReplayGain to use. This setting can have
+# the argument "off", "album", "track" or "auto". "auto" is a special mode that
+# chooses between "track" and "album" depending on the current state of
+# random playback. If random playback is enabled then "track" mode is used.
+# See for more details about ReplayGain.
+# This setting is off by default.
+#
+#replaygain "album"
+#
+# This setting sets the pre-amp used for files that have ReplayGain tags. By
+# default this setting is disabled.
+#
+#replaygain_preamp "0"
+#
+# This setting sets the pre-amp used for files that do NOT have ReplayGain tags.
+# By default this setting is disabled.
+#
+#replaygain_missing_preamp "0"
+#
+# This setting enables or disables ReplayGain limiting.
+# MPD calculates actual amplification based on the ReplayGain tags
+# and replaygain_preamp / replaygain_missing_preamp setting.
+# If replaygain_limit is enabled MPD will never amplify audio signal
+# above its original level. If replaygain_limit is disabled such amplification
+# might occur. By default this setting is enabled.
+#
+#replaygain_limit "yes"
+#
+# This setting enables on-the-fly normalization volume adjustment. This will
+# result in the volume of all playing audio to be adjusted so the output has
+# equal "loudness". This setting is disabled by default.
+#
+#volume_normalization "no"
+#
+###############################################################################
+
+# Character Encoding ##########################################################
+#
+# If file or directory names do not display correctly for your locale then you
+# may need to modify this setting.
+#
+#filesystem_charset "UTF-8"
+#
+# This setting controls the encoding that ID3v1 tags should be converted from.
+#
+#id3v1_encoding "ISO-8859-1"
+#
+###############################################################################
+
+
+# SIDPlay decoder #############################################################
+#
+# songlength_database:
+# Location of your songlengths file, as distributed with the HVSC.
+# The sidplay plugin checks this for matching MD5 fingerprints.
+# See http://www.c64.org/HVSC/DOCUMENTS/Songlengths.faq
+#
+# default_songlength:
+# This is the default playing time in seconds for songs not in the
+# songlength database, or in case you're not using a database.
+# A value of 0 means play indefinitely.
+#
+# filter:
+# Turns the SID filter emulation on or off.
+#
+#decoder {
+# plugin "sidplay"
+# songlength_database "/media/C64Music/DOCUMENTS/Songlengths.txt"
+# default_songlength "120"
+# filter "true"
+#}
+#
+###############################################################################
+
+
+# Required files
+db_file "~/.config/mpd/database"
+log_file "~/.config/mpd/log"
+
+# # Optional
+music_directory "~/Musiikki"
+playlist_directory "~/.config/mpd/playlists"
+pid_file "~/.config/mpd/pid"
+state_file "~/.config/mpd/state"
+sticker_file "~/.config/mpd/sticker.sql"
diff --git a/config/mpv/lua/notify.lua b/config/mpv/lua/notify.lua
new file mode 100644
index 0000000..3cbcc50
--- /dev/null
+++ b/config/mpv/lua/notify.lua
@@ -0,0 +1,304 @@
+-- notify.lua -- Desktop notifications for mpv.
+-- Just put this file into your ~/.mpv/lua folder and mpv will find it.
+--
+-- Copyright (c) 2014 Roland Hieber
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy
+-- of this software and associated documentation files (the "Software"), to deal
+-- in the Software without restriction, including without limitation the rights
+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-- copies of the Software, and to permit persons to whom the Software is
+-- furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in
+-- all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-- SOFTWARE.
+
+-------------------------------------------------------------------------------
+-- helper functions
+-------------------------------------------------------------------------------
+
+function print_debug(s)
+ -- print("DEBUG: " .. s) -- comment out for no debug info
+ return true
+end
+
+-- url-escape a string, per RFC 2396, Section 2
+function string.urlescape(str)
+ local s, c = string.gsub(str, "([^A-Za-z0-9_.!~*'()/-])",
+ function(c)
+ return ("%%%02x"):format(c:byte())
+ end)
+ return s;
+end
+
+-- escape string for html
+function string.htmlescape(str)
+ local str = string.gsub(str, "<", "<")
+ str = string.gsub(str, ">", ">")
+ str = string.gsub(str, "&", "&")
+ str = string.gsub(str, "\"", """)
+ str = string.gsub(str, "'", "'")
+ return str
+end
+
+-- escape string for shell inclusion
+function string.shellescape(str)
+ return "'"..string.gsub(str, "'", "'\"'\"'").."'"
+end
+
+-- converts string to a valid filename on most (modern) filesystems
+function string.safe_filename(str)
+ local s, _ = string.gsub(str, "([^A-Za-z0-9_.-])",
+ function(c)
+ return ("%02x"):format(c:byte())
+ end)
+ return s;
+end
+
+-------------------------------------------------------------------------------
+-- here we go.
+-------------------------------------------------------------------------------
+
+local http = require("socket.http")
+http.TIMEOUT = 3
+http.USERAGENT = "mpv-notify/0.1"
+
+local posix = require("posix")
+
+local CACHE_DIR = os.getenv("XDG_CACHE_HOME")
+CACHE_DIR = CACHE_DIR or os.getenv("HOME").."/.cache"
+CACHE_DIR = CACHE_DIR.."/mpv/coverart"
+print_debug("making " .. CACHE_DIR)
+os.execute("mkdir -p -- " .. string.shellescape(CACHE_DIR))
+
+function tmpname()
+ local _, fname = posix.mkstemp(CACHE_DIR .. "/rescale.XXXXXX")
+ return fname
+end
+
+-- scale an image file
+-- @return boolean of success
+function scale_image(src, dst)
+ local convert_cmd = ("convert -scale x64 -- %s %s"):format(
+ string.shellescape(src), string.shellescape(dst))
+ print_debug("executing " .. convert_cmd)
+ if os.execute(convert_cmd) then
+ return true
+ end
+ return false
+end
+
+-- look for a list of possible cover art images in the same folder as the file
+-- @param absolute filename name of currently played file, or nil if no match
+function get_folder_cover_art(filename)
+ if not filename or string.len(filename) < 1 then
+ return nil
+ end
+
+ print_debug("get_folder_cover_art: filename is " .. filename)
+
+ local cover_extensions = { "png", "jpg", "jpeg", "gif" }
+ local cover_names = { "cover", "folder", "front", "back", "insert" }
+
+ local path = string.match(filename, "^(.*/)[^/]+$")
+
+ for _,name in pairs(cover_names) do
+ for _,ext in pairs(cover_extensions) do
+ morenames = { name, string.upper(name),
+ string.upper(string.sub(name, 1, 1)) .. string.sub(name, 2, -1) }
+ moreexts = { ext, string.upper(ext) }
+ for _,name in pairs(morenames) do
+ for _,ext in pairs(moreexts) do
+ local fn = path .. name .. "." .. ext
+ --print_debug("get_folder_cover_art: trying " .. fn)
+ local f = io.open(fn, "r")
+ if f then
+ f:close()
+ print_debug("get_folder_cover_art: match at " .. fn)
+ return fn
+ end
+ end
+ end
+ end
+ end
+ return nil
+end
+
+-- fetch cover art from MusicBrainz/Cover Art Archive
+-- @return file name of downloaded cover art, or nil in case of error
+-- @param mbid optional MusicBrainz release ID
+function fetch_musicbrainz_cover_art(artist, album, mbid)
+ print_debug("fetch_musicbrainz_cover_art parameters:")
+ print_debug("artist: " .. artist)
+ print_debug("album: " .. album)
+ print_debug("mbid: " .. mbid)
+
+ if not artist or artist == "" or not album or album == "" then
+ print("not enough metadata, not fetching cover art.")
+ return nil
+ end
+
+ local output_filename = string.safe_filename(artist .. "_" .. album)
+ output_filename = (CACHE_DIR .. "/%s.png"):format(output_filename)
+
+ -- TODO: dirty hack, may only work on Linux.
+ f, err = io.open(output_filename, "r")
+ if f then
+ print_debug("file is already in cache: " .. output_filename)
+ return output_filename -- exists and is readable
+ elseif string.find(err, "[Pp]ermission denied") then
+ print(("cannot read from cached file %s: %s"):format(output_filename, err))
+ return nil
+ end
+ print_debug("fetching album art to " .. output_filename)
+
+ local valid_mbid = function(s)
+ return s and string.len(s) > 0 and not string.find(s, "[^0-9a-fA-F-]")
+ end
+
+ -- fetch release MBID from MusicBrainz, needed for Cover Art Archive
+ if not valid_mbid(mbid) then
+ string.gsub(artist, '"', "")
+ local query = ("%s AND artist:%s"):format(album, artist)
+ local url = "http://musicbrainz.org/ws/2/release?limit=1&query="
+ .. string.urlescape(query)
+ print_debug("fetching " .. url)
+ local d, c, h = http.request(url)
+ -- poor man's XML parsing:
+ local mbid = string.match(d or "",
+ "<%s*release%s+[^>]*id%s*=%s*['\"]%s*([0-9a-fA-F-]+)%s*['\"]")
+ if not mbid or not valid_mbid(mbid) then
+ print("MusicBrainz returned no match.")
+ print_debug("content: " .. d)
+ return nil
+ end
+ end
+ print_debug("got MusicBrainz ID " .. mbid)
+
+ -- fetch image from Cover Art Archive
+ local url = ("http://coverartarchive.org/release/%s/front-250"):format(mbid)
+ print("fetching album cover from " .. url)
+ local d, c, h = http.request(url)
+ if c ~= 200 then
+ print(("Cover Art Archive returned HTTP %s for MBID %s"):format(c, mbid))
+ return nil
+ end
+ if not d or string.len(d) < 1 then
+ print(("Cover Art Archive returned no content for MBID %s"):format(mbid))
+ print_debug("HTTP response: " .. d)
+ return nil
+ end
+
+ local tmp_filename = tmpname()
+ local f = io.open(tmp_filename, "w+")
+ f:write(d)
+ f:flush()
+ f:close()
+
+ -- make it a nice size
+ if scale_image(tmp_filename, output_filename) then
+ if not os.remove(tmp_filename) then
+ print("could not remove" .. tmp_filename .. ", please remove it manually")
+ end
+ return output_filename
+ end
+
+ print(("could not scale %s to %s"):format(tmp_filename, output_filename))
+ return nil
+end
+
+function notify_current_track()
+ local data = mp.get_property_native("metadata")
+ if not data then
+ return
+ end
+
+ function get_metadata(data, keys)
+ for _,v in pairs(keys) do
+ if data[v] and string.len(data[v]) > 0 then
+ return data[v]
+ end
+ end
+ return ""
+ end
+ -- srsly MPV, why do we have to do this? :-(
+ local artist = get_metadata(data, {"artist", "ARTIST"})
+ local album = get_metadata(data, {"album", "ALBUM"})
+ local album_mbid = get_metadata(data, {"MusicBrainz Album Id",
+ "MUSICBRAINZ_ALBUMID"})
+ local title = get_metadata(data, {"title", "TITLE", "icy-title"})
+
+ print_debug("notify_current_track: relevant metadata:")
+ print_debug("artist: " .. artist)
+ print_debug("album: " .. album)
+ print_debug("album_mbid: " .. album_mbid)
+
+ local summary = ""
+ local body = ""
+ local params = ""
+ local scaled_image = ""
+ local delete_scaled_image = false
+
+ -- first try finding local cover art
+ local abs_filename = os.getenv("PWD") .. "/" .. mp.get_property_native("path")
+ local cover_image = get_folder_cover_art(abs_filename)
+ if cover_image and cover_image ~= "" then
+ scaled_image = tmpname()
+ scale_image(cover_image, scaled_image)
+ delete_scaled_image = true
+ end
+
+ -- then load cover art from the internet
+ if (not scaled_image or scaled_image == "")
+ and ((artist ~= "" and album ~= "") or album_mbid ~= "") then
+ scaled_image = fetch_musicbrainz_cover_art(artist, album, album_mbid)
+ cover_image = scaled_image
+ end
+
+ if scaled_image and string.len(scaled_image) > 1 then
+ print("found cover art in " .. cover_image)
+ params = " -i " .. string.shellescape(scaled_image)
+ end
+
+ if(artist == "") then
+ summary = string.shellescape("Now playing:")
+ else
+ summary = string.shellescape(string.htmlescape(artist))
+ end
+ if title == "" then
+ body = string.shellescape(mp.get_property_native("filename"))
+ else
+ if album == "" then
+ body = string.shellescape(string.htmlescape(title))
+ else
+ body = string.shellescape(("%s %s"):format(
+ string.htmlescape(title), string.htmlescape(album)))
+ end
+ end
+
+ local command = ("notify-send -a mpv %s -- %s %s"):format(params, summary, body)
+ print_debug("command: " .. command)
+ os.execute(command)
+
+ if delete_scaled_image and not os.remove(scaled_image) then
+ print("could not remove" .. scaled_image .. ", please remove it manually")
+ end
+end
+
+function notify_metadata_updated(name, data)
+ notify_current_track()
+end
+
+
+-- insert main() here
+
+mp.register_event("file-loaded", notify_current_track)
+mp.observe_property("metadata", nil, notify_metadata_updated)
diff --git a/config/mpv/mpv.conf b/config/mpv/mpv.conf
new file mode 100644
index 0000000..2c9a9d5
--- /dev/null
+++ b/config/mpv/mpv.conf
@@ -0,0 +1,7 @@
+hwdec=vaapi
+vo=gpu
+osd-font-size=14
+ao=pulse
+
+[extension.webm]
+loop-file=inf
diff --git a/config/nitrogen/bg-saved.cfg b/config/nitrogen/bg-saved.cfg
new file mode 100644
index 0000000..7b5a597
--- /dev/null
+++ b/config/nitrogen/bg-saved.cfg
@@ -0,0 +1,14 @@
+[xin_0]
+file=/home/lanxu/.config/i3/background.png
+mode=5
+bgcolor=#000000
+
+[xin_1]
+file=/home/lanxu/.config/i3/background.png
+mode=5
+bgcolor=#000000
+
+[xin_2]
+file=/home/lanxu/.config/i3/background.png
+mode=5
+bgcolor=#000000
diff --git a/config/nitrogen/nitrogen.cfg b/config/nitrogen/nitrogen.cfg
new file mode 100644
index 0000000..7ec69dc
--- /dev/null
+++ b/config/nitrogen/nitrogen.cfg
@@ -0,0 +1,12 @@
+[geometry]
+posx=0
+posy=374
+sizex=917
+sizey=351
+
+[nitrogen]
+view=list
+recurse=true
+sort=alpha
+icon_caps=false
+dirs=/home/lanxu/.config/i3;
diff --git a/config/nvim/init.vim b/config/nvim/init.vim
new file mode 100644
index 0000000..b42c8d9
--- /dev/null
+++ b/config/nvim/init.vim
@@ -0,0 +1,3 @@
+set runtimepath^=~/.vim runtimepath+=~/.vim/after
+let &packpath=&runtimepath
+source ~/.vimrc
diff --git a/config/ranger/commands.py b/config/ranger/commands.py
new file mode 100644
index 0000000..1675a55
--- /dev/null
+++ b/config/ranger/commands.py
@@ -0,0 +1,33 @@
+import os
+from ranger.core.loader import CommandLoader
+from ranger.api.commands import Command
+
+class compress(Command):
+ def execute(self):
+ """ Compress marked files to current directory """
+ cwd = self.fm.thisdir
+ marked_files = cwd.get_selection()
+
+ if not marked_files:
+ return
+
+ def refresh(_):
+ cwd = self.fm.get_directory(original_path)
+ cwd.load_content()
+
+ original_path = cwd.path
+ parts = self.line.split()
+ au_flags = [' '.join(parts[1:])]
+
+ descr = "compressing files in: " + os.path.basename(parts[1])
+ obj = CommandLoader(args=['apack'] + au_flags + \
+ [os.path.relpath(f.path, cwd.path) for f in marked_files], descr=descr, read=True)
+
+ obj.signal_bind('after', refresh)
+ self.fm.loader.add(obj)
+
+ def tab(self, tabnum):
+ """ Complete with current folder name """
+
+ extension = ['.zip', '.tar.gz', '.xz', '.rar', '.7z']
+ return ['compress ' + os.path.basename(self.fm.thisdir.path) + ext for ext in extension]
diff --git a/config/ranger/rc.conf b/config/ranger/rc.conf
new file mode 100644
index 0000000..0f977d9
--- /dev/null
+++ b/config/ranger/rc.conf
@@ -0,0 +1,763 @@
+# ===================================================================
+# This file contains the default startup commands for ranger.
+# To change them, it is recommended to create either /etc/ranger/rc.conf
+# (system-wide) or ~/.config/ranger/rc.conf (per user) and add your custom
+# commands there.
+#
+# If you copy this whole file there, you may want to set the environment
+# variable RANGER_LOAD_DEFAULT_RC to FALSE to avoid loading it twice.
+#
+# The purpose of this file is mainly to define keybindings and settings.
+# For running more complex python code, please create a plugin in "plugins/" or
+# a command in "commands.py".
+#
+# Each line is a command that will be run before the user interface
+# is initialized. As a result, you can not use commands which rely
+# on the UI such as :delete or :mark.
+# ===================================================================
+
+# ===================================================================
+# == Options
+# ===================================================================
+
+# Which viewmode should be used? Possible values are:
+# miller: Use miller columns which show multiple levels of the hierarchy
+# multipane: Midnight-commander like multipane view showing all tabs next
+# to each other
+set viewmode miller
+#set viewmode multipane
+
+# How many columns are there, and what are their relative widths?
+set column_ratios 1,3,4
+
+# Which files should be hidden? (regular expression)
+set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$
+
+# Show hidden files? You can toggle this by typing 'zh'
+set show_hidden false
+
+# Ask for a confirmation when running the "delete" command?
+# Valid values are "always", "never", "multiple" (default)
+# With "multiple", ranger will ask only if you delete multiple files at once.
+set confirm_on_delete multiple
+
+# Use non-default path for file preview script?
+# ranger ships with scope.sh, a script that calls external programs (see
+# README.md for dependencies) to preview images, archives, etc.
+#set preview_script ~/.config/ranger/scope.sh
+
+# Use the external preview script or display simple plain text or image previews?
+set use_preview_script true
+
+# Automatically count files in the directory, even before entering them?
+set automatically_count_files true
+
+# Open all images in this directory when running certain image viewers
+# like feh or sxiv? You can still open selected files by marking them.
+set open_all_images true
+
+# Be aware of version control systems and display information.
+set vcs_aware false
+
+# State of the four backends git, hg, bzr, svn. The possible states are
+# disabled, local (only show local info), enabled (show local and remote
+# information).
+set vcs_backend_git enabled
+set vcs_backend_hg disabled
+set vcs_backend_bzr disabled
+set vcs_backend_svn disabled
+
+# Truncate the long commit messages to this length when shown in the statusbar.
+set vcs_msg_length 50
+
+# Use one of the supported image preview protocols
+set preview_images true
+
+# Set the preview image method. Supported methods:
+#
+# * w3m (default):
+# Preview images in full color with the external command "w3mimgpreview"?
+# This requires the console web browser "w3m" and a supported terminal.
+# It has been successfully tested with "xterm" and "urxvt" without tmux.
+#
+# * iterm2:
+# Preview images in full color using iTerm2 image previews
+# (http://iterm2.com/images.html). This requires using iTerm2 compiled
+# with image preview support.
+#
+# This feature relies on the dimensions of the terminal's font. By default, a
+# width of 8 and height of 11 are used. To use other values, set the options
+# iterm2_font_width and iterm2_font_height to the desired values.
+#
+# * terminology:
+# Previews images in full color in the terminology terminal emulator.
+# Supports a wide variety of formats, even vector graphics like svg.
+#
+# * urxvt:
+# Preview images in full color using urxvt image backgrounds. This
+# requires using urxvt compiled with pixbuf support.
+#
+# * urxvt-full:
+# The same as urxvt but utilizing not only the preview pane but the
+# whole terminal window.
+#
+# * kitty:
+# Preview images in full color using kitty image protocol.
+# Requires python PIL or pillow library.
+# If ranger does not share the local filesystem with kitty
+# the transfer method is changed to encode the whole image;
+# while slower, this allows remote previews,
+# for example during an ssh session.
+# Tmux is unsupported.
+#
+# * ueberzug:
+# Preview images in full color with the external command "ueberzug".
+# Images are shown by using a child window.
+# Only for users who run X11 in GNU/Linux.
+#set preview_images_method ueberzug
+set preview_images_method w3m
+
+# Delay in seconds before displaying an image with the w3m method.
+# Increase it in case of experiencing display corruption.
+set w3m_delay 0.02
+
+# Manually adjust the w3mimg offset when using a terminal which needs this
+set w3m_offset 0
+
+# Default iTerm2 font size (see: preview_images_method: iterm2)
+set iterm2_font_width 8
+set iterm2_font_height 11
+
+# Use a unicode "..." character to mark cut-off filenames?
+set unicode_ellipsis false
+
+# BIDI support - try to properly display file names in RTL languages (Hebrew, Arabic).
+# Requires the python-bidi pip package
+set bidi_support false
+
+# Show dotfiles in the bookmark preview box?
+set show_hidden_bookmarks true
+
+# Which colorscheme to use? These colorschemes are available by default:
+# default, jungle, snow, solarized
+set colorscheme default
+
+# Preview files on the rightmost column?
+# And collapse (shrink) the last column if there is nothing to preview?
+set preview_files true
+set preview_directories true
+set collapse_preview true
+
+# Wrap long lines in plain text previews?
+set wrap_plaintext_previews false
+
+# Save the console history on exit?
+set save_console_history true
+
+# Draw the status bar on top of the browser window (default: bottom)
+set status_bar_on_top false
+
+# Draw a progress bar in the status bar which displays the average state of all
+# currently running tasks which support progress bars?
+set draw_progress_bar_in_status_bar true
+
+# Draw borders around columns? (separators, outline, both, or none)
+# Separators are vertical lines between columns.
+# Outline draws a box around all the columns.
+# Both combines the two.
+set draw_borders none
+
+# Display the directory name in tabs?
+set dirname_in_tabs false
+
+# Enable the mouse support?
+set mouse_enabled true
+
+# Display the file size in the main column or status bar?
+set display_size_in_main_column true
+set display_size_in_status_bar true
+
+# Display the free disk space in the status bar?
+set display_free_space_in_status_bar true
+
+# Display files tags in all columns or only in main column?
+set display_tags_in_all_columns true
+
+# Set a title for the window? Updates both `WM_NAME` and `WM_ICON_NAME`
+set update_title false
+
+# Set the tmux/screen window-name to "ranger"?
+set update_tmux_title true
+
+# Shorten the title if it gets long? The number defines how many
+# directories are displayed at once, 0 turns off this feature.
+set shorten_title 3
+
+# Show hostname in titlebar?
+set hostname_in_titlebar true
+
+# Abbreviate $HOME with ~ in the titlebar (first line) of ranger?
+set tilde_in_titlebar false
+
+# How many directory-changes or console-commands should be kept in history?
+set max_history_size 20
+set max_console_history_size 50
+
+# Try to keep so much space between the top/bottom border when scrolling:
+set scroll_offset 8
+
+# Flush the input after each key hit? (Noticeable when ranger lags)
+set flushinput true
+
+# Padding on the right when there's no preview?
+# This allows you to click into the space to run the file.
+set padding_right true
+
+# Save bookmarks (used with mX and `X) instantly?
+# This helps to synchronize bookmarks between multiple ranger
+# instances but leads to *slight* performance loss.
+# When false, bookmarks are saved when ranger is exited.
+set autosave_bookmarks true
+
+# Save the "`" bookmark to disk. This can be used to switch to the last
+# directory by typing "``".
+set save_backtick_bookmark true
+
+# You can display the "real" cumulative size of directories by using the
+# command :get_cumulative_size or typing "dc". The size is expensive to
+# calculate and will not be updated automatically. You can choose
+# to update it automatically though by turning on this option:
+set autoupdate_cumulative_size false
+
+# Turning this on makes sense for screen readers:
+set show_cursor false
+
+# One of: size, natural, basename, atime, ctime, mtime, type, random
+set sort natural
+
+# Additional sorting options
+set sort_reverse false
+set sort_case_insensitive true
+set sort_directories_first true
+set sort_unicode false
+
+# Enable this if key combinations with the Alt Key don't work for you.
+# (Especially on xterm)
+set xterm_alt_key false
+
+# Whether to include bookmarks in cd command
+set cd_bookmarks true
+
+# Changes case sensitivity for the cd command tab completion
+set cd_tab_case sensitive
+
+# Use fuzzy tab completion with the "cd" command. For example,
+# ":cd /u/lo/b" expands to ":cd /usr/local/bin".
+set cd_tab_fuzzy false
+
+# Avoid previewing files larger than this size, in bytes. Use a value of 0 to
+# disable this feature.
+set preview_max_size 0
+
+# The key hint lists up to this size have their sublists expanded.
+# Otherwise the submaps are replaced with "...".
+set hint_collapse_threshold 10
+
+# Add the highlighted file to the path in the titlebar
+set show_selection_in_titlebar true
+
+# The delay that ranger idly waits for user input, in milliseconds, with a
+# resolution of 100ms. Lower delay reduces lag between directory updates but
+# increases CPU load.
+set idle_delay 2000
+
+# When the metadata manager module looks for metadata, should it only look for
+# a ".metadata.json" file in the current directory, or do a deep search and
+# check all directories above the current one as well?
+set metadata_deep_search false
+
+# Clear all existing filters when leaving a directory
+set clear_filters_on_dir_change false
+
+# Disable displaying line numbers in main column.
+# Possible values: false, absolute, relative.
+set line_numbers false
+
+# When line_numbers=relative show the absolute line number in the
+# current line.
+set relative_current_zero false
+
+# Start line numbers from 1 instead of 0
+set one_indexed false
+
+# Save tabs on exit
+set save_tabs_on_exit false
+
+# Enable scroll wrapping - moving down while on the last item will wrap around to
+# the top and vice versa.
+set wrap_scroll false
+
+# Set the global_inode_type_filter to nothing. Possible options: d, f and l for
+# directories, files and symlinks respectively.
+set global_inode_type_filter
+
+# This setting allows to freeze the list of files to save I/O bandwidth. It
+# should be 'false' during start-up, but you can toggle it by pressing F.
+set freeze_files false
+
+# Print file sizes in bytes instead of the default human-readable format.
+set size_in_bytes false
+
+# Warn at startup if RANGER_LEVEL env var is greater than 0, in other words
+# give a warning when you nest ranger in a subshell started by ranger.
+# Special value "error" makes the warning more visible.
+set nested_ranger_warning true
+
+# ===================================================================
+# == Local Options
+# ===================================================================
+# You can set local options that only affect a single directory.
+
+# Examples:
+# setlocal path=~/downloads sort mtime
+
+# ===================================================================
+# == Command Aliases in the Console
+# ===================================================================
+
+alias e edit
+alias q quit
+alias q! quit!
+alias qa quitall
+alias qa! quitall!
+alias qall quitall
+alias qall! quitall!
+alias setl setlocal
+
+alias filter scout -prts
+alias find scout -aets
+alias mark scout -mr
+alias unmark scout -Mr
+alias search scout -rs
+alias search_inc scout -rts
+alias travel scout -aefklst
+
+# ===================================================================
+# == Define keys for the browser
+# ===================================================================
+
+# Basic
+map Q quitall
+map q quit
+copymap q ZZ ZQ
+
+map R reload_cwd
+map F set freeze_files!
+map reset
+map redraw_window
+map abort
+map change_mode normal
+map ~ set viewmode!
+
+map i display_file
+map scroll_preview 1
+map scroll_preview -1
+map ? help
+map W display_log
+map w taskview_open
+map S shell $SHELL
+
+map : console
+map ; console
+map ! console shell%space
+map @ console -p6 shell %%s
+map # console shell -p%space
+map s console shell%space
+map r chain draw_possible_programs; console open_with%space
+map f console find%space
+map cd console cd%space
+
+map chain console; eval fm.ui.console.history_move(-1)
+
+# Change the line mode
+map Mf linemode filename
+map Mi linemode fileinfo
+map Mm linemode mtime
+map Mh linemode humanreadablemtime
+map Mp linemode permissions
+map Ms linemode sizemtime
+map MH linemode sizehumanreadablemtime
+map Mt linemode metatitle
+
+# Tagging / Marking
+map t tag_toggle
+map ut tag_remove
+map " tag_toggle tag=%any
+map mark_files toggle=True
+map v mark_files all=True toggle=True
+map uv mark_files all=True val=False
+map V toggle_visual_mode
+map uV toggle_visual_mode reverse=True
+
+# For the nostalgics: Midnight Commander bindings
+map help
+map rename_append
+map display_file
+map edit
+map copy
+map cut
+map console mkdir%space
+map console delete
+#map console trash
+map exit
+
+# In case you work on a keyboard with dvorak layout
+map move up=1
+map move down=1
+map move left=1
+map move right=1
+map move to=0
+map move to=-1
+map move down=1 pages=True
+map move up=1 pages=True
+map move right=1
+#map console delete
+map console touch%space
+
+# VIM-like
+copymap k
+copymap j
+copymap h
+copymap l
+copymap gg
+copymap G
+copymap
+copymap
+
+map J move down=0.5 pages=True
+map K move up=0.5 pages=True
+copymap J
+copymap K
+
+# Jumping around
+map H history_go -1
+map L history_go 1
+map ] move_parent 1
+map [ move_parent -1
+map } traverse
+map { traverse_backwards
+map ) jump_non
+
+map gh cd ~
+map ge cd /etc
+map gu cd /usr
+map gd cd /dev
+map gl cd -r .
+map gL cd -r %f
+map go cd /opt
+map gv cd /var
+map gm cd /media
+map gi eval fm.cd('/run/media/' + os.getenv('USER'))
+map gM cd /mnt
+map gs cd /srv
+map gp cd /tmp
+map gr cd /
+map gR eval fm.cd(ranger.RANGERDIR)
+map g/ cd /
+map g? cd /usr/share/doc/ranger
+
+# External Programs
+map E edit
+map du shell -p du --max-depth=1 -h --apparent-size
+map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh
+map yp yank path
+map yd yank dir
+map yn yank name
+map y. yank name_without_extension
+
+# Filesystem Operations
+map = chmod
+
+map cw console rename%space
+map a rename_append
+map A eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"))
+map I eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"), position=7)
+
+map pp paste
+map po paste overwrite=True
+map pP paste append=True
+map pO paste overwrite=True append=True
+map pl paste_symlink relative=False
+map pL paste_symlink relative=True
+map phl paste_hardlink
+map pht paste_hardlinked_subtree
+map pd console paste dest=
+map p` paste dest=%any_path
+map p' paste dest=%any_path
+
+map dD console delete
+map dT console trash
+
+map dd cut
+map ud uncut
+map da cut mode=add
+map dr cut mode=remove
+map dt cut mode=toggle
+
+map yy copy
+map uy uncut
+map ya copy mode=add
+map yr copy mode=remove
+map yt copy mode=toggle
+
+# Temporary workarounds
+map dgg eval fm.cut(dirarg=dict(to=0), narg=quantifier)
+map dG eval fm.cut(dirarg=dict(to=-1), narg=quantifier)
+map dj eval fm.cut(dirarg=dict(down=1), narg=quantifier)
+map dk eval fm.cut(dirarg=dict(up=1), narg=quantifier)
+map ygg eval fm.copy(dirarg=dict(to=0), narg=quantifier)
+map yG eval fm.copy(dirarg=dict(to=-1), narg=quantifier)
+map yj eval fm.copy(dirarg=dict(down=1), narg=quantifier)
+map yk eval fm.copy(dirarg=dict(up=1), narg=quantifier)
+
+# Searching
+map / console search%space
+map n search_next
+map N search_next forward=False
+map ct search_next order=tag
+map cs search_next order=size
+map ci search_next order=mimetype
+map cc search_next order=ctime
+map cm search_next order=mtime
+map ca search_next order=atime
+
+# Tabs
+map tab_new
+map tab_close
+map tab_move 1
+map tab_move -1
+map tab_move 1
+map tab_move -1
+map gt tab_move 1
+map gT tab_move -1
+map gn tab_new
+map gc tab_close
+map uq tab_restore
+map tab_open 1
+map tab_open 2
+map tab_open 3
+map tab_open 4
+map tab_open 5
+map tab_open 6
+map tab_open 7
+map tab_open 8
+map tab_open 9
+map tab_shift 1
+map tab_shift -1
+
+# Sorting
+map or set sort_reverse!
+map oz set sort=random
+map os chain set sort=size; set sort_reverse=False
+map ob chain set sort=basename; set sort_reverse=False
+map on chain set sort=natural; set sort_reverse=False
+map om chain set sort=mtime; set sort_reverse=False
+map oc chain set sort=ctime; set sort_reverse=False
+map oa chain set sort=atime; set sort_reverse=False
+map ot chain set sort=type; set sort_reverse=False
+map oe chain set sort=extension; set sort_reverse=False
+
+map oS chain set sort=size; set sort_reverse=True
+map oB chain set sort=basename; set sort_reverse=True
+map oN chain set sort=natural; set sort_reverse=True
+map oM chain set sort=mtime; set sort_reverse=True
+map oC chain set sort=ctime; set sort_reverse=True
+map oA chain set sort=atime; set sort_reverse=True
+map oT chain set sort=type; set sort_reverse=True
+map oE chain set sort=extension; set sort_reverse=True
+
+map dc get_cumulative_size
+
+# Settings
+map zc set collapse_preview!
+map zd set sort_directories_first!
+map zh set show_hidden!
+map set show_hidden!
+copymap
+copymap
+map zI set flushinput!
+map zi set preview_images!
+map zm set mouse_enabled!
+map zp set preview_files!
+map zP set preview_directories!
+map zs set sort_case_insensitive!
+map zu set autoupdate_cumulative_size!
+map zv set use_preview_script!
+map zf console filter%space
+copymap zf zz
+
+# Filter stack
+map .d filter_stack add type d
+map .f filter_stack add type f
+map .l filter_stack add type l
+map .m console filter_stack add mime%space
+map .n console filter_stack add name%space
+map .# console filter_stack add hash%space
+map ." filter_stack add duplicate
+map .' filter_stack add unique
+map .| filter_stack add or
+map .& filter_stack add and
+map .! filter_stack add not
+map .r filter_stack rotate
+map .c filter_stack clear
+map .* filter_stack decompose
+map .p filter_stack pop
+map .. filter_stack show
+
+# Bookmarks
+map ` enter_bookmark %any
+map ' enter_bookmark %any
+map m set_bookmark %any
+map um unset_bookmark %any
+
+map m draw_bookmarks
+copymap m um ` '
+
+# Generate all the chmod bindings with some python help:
+eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map +{0} shell -f chmod u+{0} %s".format(arg))
+
+eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg))
+eval for arg in "rwxXst": cmd("map -{0} shell -f chmod u-{0} %s".format(arg))
+
+# ===================================================================
+# == Define keys for the console
+# ===================================================================
+# Note: Unmapped keys are passed directly to the console.
+
+# Basic
+cmap eval fm.ui.console.tab()
+cmap eval fm.ui.console.tab(-1)
+cmap eval fm.ui.console.close()
+cmap eval fm.ui.console.execute()
+cmap redraw_window
+
+copycmap
+copycmap
+
+# Move around
+cmap eval fm.ui.console.history_move(-1)
+cmap eval fm.ui.console.history_move(1)
+cmap eval fm.ui.console.move(left=1)
+cmap eval fm.ui.console.move(right=1)
+cmap eval fm.ui.console.move(right=0, absolute=True)
+cmap eval fm.ui.console.move(right=-1, absolute=True)
+cmap eval fm.ui.console.move_word(left=1)
+cmap eval fm.ui.console.move_word(right=1)
+
+copycmap
+copycmap
+
+# Line Editing
+cmap eval fm.ui.console.delete(-1)
+cmap eval fm.ui.console.delete(0)
+cmap eval fm.ui.console.delete_word()
+cmap eval fm.ui.console.delete_word(backward=False)
+cmap eval fm.ui.console.delete_rest(1)
+cmap eval fm.ui.console.delete_rest(-1)
+cmap eval fm.ui.console.paste()
+
+# And of course the emacs way
+copycmap
+copycmap
+copycmap
+copycmap
+copycmap
+copycmap
+copycmap
+copycmap
+copycmap
+
+# Note: There are multiple ways to express backspaces. (code 263)
+# and (code 127). To be sure, use both.
+copycmap
+
+# This special expression allows typing in numerals:
+cmap false
+
+# ===================================================================
+# == Pager Keybindings
+# ===================================================================
+
+# Movement
+pmap pager_move down=1
+pmap pager_move up=1
+pmap pager_move left=4
+pmap pager_move right=4
+pmap pager_move to=0
+pmap pager_move to=-1
+pmap pager_move down=1.0 pages=True
+pmap pager_move up=1.0 pages=True
+pmap pager_move down=0.5 pages=True
+pmap pager_move up=0.5 pages=True
+
+copypmap k
+copypmap j
+copypmap h
+copypmap l
+copypmap g
+copypmap G
+copypmap d
+copypmap u
+copypmap n f
+copypmap p b
+
+# Basic
+pmap redraw_window
+pmap pager_close
+copypmap q Q i
+pmap E edit_file
+
+# ===================================================================
+# == Taskview Keybindings
+# ===================================================================
+
+# Movement
+tmap taskview_move up=1
+tmap taskview_move down=1
+tmap taskview_move to=0
+tmap taskview_move to=-1
+tmap taskview_move down=1.0 pages=True
+tmap taskview_move up=1.0 pages=True
+tmap taskview_move down=0.5 pages=True
+tmap taskview_move up=0.5 pages=True
+
+copytmap k
+copytmap j
+copytmap g
+copytmap G
+copytmap u
+copytmap n f
+copytmap p b
+
+# Changing priority and deleting tasks
+tmap J eval -q fm.ui.taskview.task_move(-1)
+tmap K eval -q fm.ui.taskview.task_move(0)
+tmap dd eval -q fm.ui.taskview.task_remove()
+tmap eval -q fm.ui.taskview.task_move(-1)
+tmap eval -q fm.ui.taskview.task_move(0)
+tmap eval -q fm.ui.taskview.task_remove()
+
+# Basic
+tmap redraw_window
+tmap taskview_close
+copytmap q Q w
+
+# Drag'n'Drop using dragon https://github.com/mwh/dragon
+map shell dragon -a -x %p
diff --git a/config/ranger/rifle.conf b/config/ranger/rifle.conf
new file mode 100644
index 0000000..642f521
--- /dev/null
+++ b/config/ranger/rifle.conf
@@ -0,0 +1,288 @@
+# vim: ft=cfg
+#
+# This is the configuration file of "rifle", ranger's file executor/opener.
+# Each line consists of conditions and a command. For each line the conditions
+# are checked and if they are met, the respective command is run.
+#
+# Syntax:
+# , , ... = command
+#
+# The command can contain these environment variables:
+# $1-$9 | The n-th selected file
+# $@ | All selected files
+#
+# If you use the special command "ask", rifle will ask you what program to run.
+#
+# Prefixing a condition with "!" will negate its result.
+# These conditions are currently supported:
+# match | The regexp matches $1
+# ext | The regexp matches the extension of $1
+# mime | The regexp matches the mime type of $1
+# name | The regexp matches the basename of $1
+# path | The regexp matches the absolute path of $1
+# has | The program is installed (i.e. located in $PATH)
+# env | The environment variable "variable" is non-empty
+# file | $1 is a file
+# directory | $1 is a directory
+# number | change the number of this command to n
+# terminal | stdin, stderr and stdout are connected to a terminal
+# X | A graphical environment is available (darwin, Xorg, or Wayland)
+#
+# There are also pseudo-conditions which have a "side effect":
+# flag | Change how the program is run. See below.
+# label