diff --git a/.gitignore b/.gitignore index 98e0180..1270333 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ wallpaper walls *.swp localconf.lua +debugging diff --git a/.gitmodules b/.gitmodules index 0ae50e8..2a6f841 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "obvious"] - path = obvious - url = git://git.mercenariesguild.net/obvious.git [submodule "vicious"] path = vicious url = http://git.sysphere.org/vicious diff --git a/aweswt.lua b/aweswt.lua deleted file mode 100644 index f7eb326..0000000 --- a/aweswt.lua +++ /dev/null @@ -1,138 +0,0 @@ --- aweswt.lua --- Application switcher using dmenu --- - -local M = {} - --- local functions -local get_out, get_input, _switch, assemble_command - -local defaults = {} -local settings = {} - -defaults.bg_focus = theme.bg_focus -defaults.fg_focus = theme.fg_focus -defaults.bg_normal = theme.bg_normal -defaults.fg_normal = theme.fg_normal -defaults.font = string.gsub(theme.font, " ","-") -defaults.menu_cmd = "dmenu -nf %q -nb %q -sf %q -sb %q -p 'Switch to' -fn %q -i" - -local command - -for key, value in pairs(defaults) do - settings[key] = value -end - - - --- switch with window titles -M.switch = function() - _switch(true) -end - --- switch with client instance and class -M.switch_class = function() - _switch(false) -end - --- {{{ option setters - -M.set_bg_focus = function (color) - settings.bg_focus = color or defaults.bg_focus - assemble_command() -end - -M.set_fg_focus = function (color) - settings.fg_focus = color or defaults.fg_focus - assemble_command() -end - -M.set_bg_normal = function (color) - settings.bg_normal = color or defaults.bg_normal - assemble_command() -end - -M.set_fg_normal = function (color) - settings.fg_normal = color or defaults.fg_normal - assemble_command() -end - -M.set_font = function (font) - settings.font = font or defaults.font - assemble_command() -end - -M.set_menu_command = function (command) - settings.menu_cmd = command or defaults.menu_cmd - assemble_command() -end - --- }}} - --- {{{ io functions -get_out = function (a) - local f = io.popen(a) - t = {} - for line in f:lines() do - table.insert(t, line) - end - return t -end - -get_input = function (a) - s1 = 'echo "' .. a .. '" | ' .. command - return get_out(s1) -end - --- }}} - --- {{{ main worker function -_switch = function(use_name) - local clients = client.get() - - if table.getn(clients) == 0 then - return - end - - local client_list_table = {} - local apps = {} - - for key, client in pairs(clients) do - local app - - if use_name then - app = client['name'] - else - app = key .. ':' .. client['instance'] .. '.' .. client['class'] - end - - table.insert(client_list_table, app) - apps[app] = client - end - - table.sort(client_list_table, function(a, b) - return string.lower(a) < string.lower(b) - end) - local client_list = table.concat(client_list_table, "\n") - - local client_selected = apps[get_input(client_list)[1]] - if client_selected then - local ctags = client_selected:tags() - awful.tag.viewonly(ctags[1]) - client.focus = client_selected - client_selected:raise() - end -end --- }}} - -assemble_command = function() - command = string.format(settings.menu_cmd, - settings.fg_normal, - settings.bg_normal, - settings.fg_focus, - settings.bg_focus, - settings.font) -end - -assemble_command() -return M diff --git a/bindings.lua b/bindings.lua index 4a949f5..6f35dda 100644 --- a/bindings.lua +++ b/bindings.lua @@ -2,9 +2,7 @@ local awful = awful local conf = conf local mpd = require("mpd") -local obvious = {} local scratch = require("scratch") -obvious.popup_run_prompt = require("obvious.popup_run_prompt") local modkey = conf.modkey or "Mod4" local mb = require("modalbind") @@ -32,9 +30,9 @@ mpdmap = { mpdpromts = { name = "MPD PROMPTS", a = mpd.prompt.artist, - A = mpd.prompt.album, + b = mpd.prompt.album, t = mpd.prompt.title, - r = mpd.prompt.toggle_replace_on_search, + r = mpd.prompt.toggle_replace_on_search } progmap = { @@ -51,14 +49,13 @@ function rfkill(cmd) for key, adapter in pairs(adapters) do map[key] = spawnf("sudo rfkill "..cmd.." "..adapter) end - print(map["name"]) return map end --- wirelessmap = { --- name = "RFKILL", --- b = function () mb.grab(rfkill("block")) end, --- u = function () mb.grab(rfkill("unblock")) end --- } +wirelessmap = { + name = "RFKILL", + b = mb.grabf(rfkill("block")), + u = mb.grabf(rfkill("unblock")) +} function bindings.extend_and_register_key_table(globalkeys) local totalkeys = globalkeys or {} @@ -71,10 +68,10 @@ function bindings.extend_and_register_key_table(globalkeys) --{{{ Modal mappings - awful.key({ modkey }, "m", function () mb.grab(mpdmap, true) end), - awful.key({ modkey, "Shift" }, "m", function () mb.grab(mpdpromts) end), - awful.key({ modkey }, "c", function () mb.grab(progmap) end), - awful.key({ modkey }, "w", function () mb.grab(wirelessmap) end), + awful.key({ modkey }, "m", mb.grabf(mpdmap, true)), + awful.key({ modkey, "Shift" }, "m", mb.grabf(mpdpromts)), + awful.key({ modkey }, "c", mb.grabf(progmap)), + awful.key({ modkey }, "w", mb.grabf(wirelessmap)), --}}} --{{{ Audio control diff --git a/inspect.lua b/inspect.lua new file mode 100644 index 0000000..25632c9 --- /dev/null +++ b/inspect.lua @@ -0,0 +1,248 @@ +----------------------------------------------------------------------------------------------------------------------- +-- inspect.lua - v1.2.0 (2012-10) +-- Enrique GarcĂ­a Cota - enrique.garcia.cota [AT] gmail [DOT] com +-- human-readable representations of tables. +-- inspired by http://lua-users.org/wiki/TableSerialization +----------------------------------------------------------------------------------------------------------------------- + +local inspect ={} +inspect.__VERSION = '1.2.0' + +-- Apostrophizes the string if it has quotes, but not aphostrophes +-- Otherwise, it returns a regular quoted string +local function smartQuote(str) + if string.match( string.gsub(str,"[^'\"]",""), '^"+$' ) then + return "'" .. str .. "'" + end + return string.format("%q", str ) +end + +local controlCharsTranslation = { + ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", + ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\\"] = "\\\\" +} + +local function unescapeChar(c) return controlCharsTranslation[c] end + +local function unescape(str) + local result, _ = string.gsub( str, "(%c)", unescapeChar ) + return result +end + +local function isIdentifier(str) + return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" ) +end + +local function isArrayKey(k, length) + return type(k)=='number' and 1 <= k and k <= length +end + +local function isDictionaryKey(k, length) + return not isArrayKey(k, length) +end + +local sortOrdersByType = { + ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4, + ['function'] = 5, ['userdata'] = 6, ['thread'] = 7 +} + +local function sortKeys(a,b) + local ta, tb = type(a), type(b) + if ta ~= tb then return sortOrdersByType[ta] < sortOrdersByType[tb] end + if ta == 'string' or ta == 'number' then return a < b end + return false +end + +local function getDictionaryKeys(t) + local length = #t + local keys = {} + for k,_ in pairs(t) do + if isDictionaryKey(k, length) then table.insert(keys,k) end + end + table.sort(keys, sortKeys) + return keys +end + +local function getToStringResultSafely(t, mt) + local __tostring = type(mt) == 'table' and mt.__tostring + local string, status + if type(__tostring) == 'function' then + status, string = pcall(__tostring, t) + string = status and string or 'error: ' .. tostring(string) + end + return string +end + +local Inspector = {} + +function Inspector:new(t, depth) + local inspector = { + buffer = {}, + depth = depth, + level = 0, + maxIds = { + ['function'] = 0, + ['userdata'] = 0, + ['thread'] = 0, + ['table'] = 0, + ['key'] = 0, + ['tag'] = 0 + }, + ids = { + ['function'] = setmetatable({}, {__mode = "kv"}), + ['userdata'] = setmetatable({}, {__mode = "kv"}), + ['thread'] = setmetatable({}, {__mode = "kv"}), + ['table'] = setmetatable({}, {__mode = "kv"}), + ['key'] = setmetatable({}, {__mode = "kv"}), + ['tag'] = setmetatable({}, {__mode = "kv"}) + }, + tableAppearances = setmetatable({}, {__mode = "k"}) + } + + setmetatable(inspector, {__index = Inspector}) + + inspector:countTableAppearances(t) + + return inspector:putValue(t) +end + +function Inspector:countTableAppearances(t) + if type(t) == 'table' then + if not self.tableAppearances[t] then + self.tableAppearances[t] = 1 + for k,v in pairs(t) do + self:countTableAppearances(k) + self:countTableAppearances(v) + end + else + self.tableAppearances[t] = self.tableAppearances[t] + 1 + end + self:countTableAppearances(getmetatable(t)) + end +end + +function Inspector:tabify() + self:puts("\n", string.rep(" ", self.level)) + return self +end + +function Inspector:up() + self.level = self.level - 1 +end + +function Inspector:down() + self.level = self.level + 1 +end + +function Inspector:puts(...) + local args = {...} + local len = #self.buffer + for i=1, #args do + len = len + 1 + self.buffer[len] = tostring(args[i]) + end + return self +end + +function Inspector:commaControl(comma) + if comma then self:puts(',') end + return true +end + +function Inspector:putTable(t) + if self:alreadyVisited(t) then + self:puts('') + elseif self.depth and self.level >= self.depth then + self:puts('{...}') + else + if self.tableAppearances[t] > 1 then + self:puts('<',self:getId(t),'>') + end + self:puts('{') + self:down() + + local length = #t + local mt = getmetatable(t) + + local string = getToStringResultSafely(t, mt) + if type(string) == 'string' and #string > 0 then + self:puts(' -- ', unescape(string)) + if length >= 1 then self:tabify() end -- tabify the array values + end + + local comma = false + for i=1, length do + comma = self:commaControl(comma) + self:puts(' '):putValue(t[i]) + end + + local dictKeys = getDictionaryKeys(t) + + for _,k in ipairs(dictKeys) do + comma = self:commaControl(comma) + self:tabify():putKey(k):puts(' = '):putValue(t[k]) + end + + if mt then + comma = self:commaControl(comma) + self:tabify():puts(' = '):putValue(mt) + end + + self:up() + + if #dictKeys > 0 or mt then -- dictionary table. Justify closing } + self:tabify() + elseif length > 0 then -- array tables have one extra space before closing } + self:puts(' ') + end + self:puts('}') + end + return self +end + +function Inspector:alreadyVisited(v) + return self.ids[type(v)][v] ~= nil +end + +function Inspector:getId(v) + local tv = type(v) + local idtable = self.ids[tv] + local id = idtable and idtable[v] or nil + if not id then + id = self.maxIds[tv] + 1 + self.maxIds[tv] = id + self.ids[tv][v] = id + end + return id +end + +function Inspector:putValue(v) + local tv = type(v) + + if tv == 'string' then + self:puts(smartQuote(unescape(v))) + elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then + self:puts(tostring(v)) + elseif tv == 'table' then + self:putTable(v) + else + self:puts('<',tv,' ',self:getId(v),'>') + end + return self +end + +function Inspector:putKey(k) + if isIdentifier(k) then return self:puts(k) end + return self:puts( "[" ):putValue(k):puts("]") +end + +function Inspector:tostring() + return table.concat(self.buffer) +end + +setmetatable(inspect, { __call = function(_,t,depth) + return Inspector:new(t, depth):tostring() +end }) + +return inspect + diff --git a/modalbind.lua b/modalbind.lua index f3f027c..aef2c71 100644 --- a/modalbind.lua +++ b/modalbind.lua @@ -1,7 +1,9 @@ -local M = {} +local modalbind = {} +local wibox = require("wibox") local inited = false local modewidget = {} local modewibox = { screen = -1 } +local nesting = 0 --local functions @@ -31,49 +33,54 @@ end --- Change the opacity of the modebox. -- @param amount opacity between 0.0 and 1.0, or nil to use default -M.set_opacity = function (amount) +function set_opacity(amount) settings.opacity = amount or defaults.opacity update_settings() end +modalbind.set_opacity = set_opacity --- Change height of the modebox. -- @param amount height in pixels, or nil to use default -M.set_height = function (amount) +function set_height(amount) settings.height = amount or defaults.height update_settings() end +modalbind.set_height = set_height --- Change border width of the modebox. -- @param amount width in pixels, or nil to use default -M.set_border_width = function (amount) +function set_border_width(amount) settings.border_width = amount or defaults.border_width update_settings() end +modalbind.set_border_width = set_border_width --- Change horizontal offset of the modebox. -- set location for the box with set_corner(). The box is shifted to the right -- if it is in one of the left corners or to the left otherwise -- @param amount horizontal shift in pixels, or nil to use default -M.set_x_offset = function (amount) +function set_x_offset (amount) settings.x_offset = amount or defaults.x_offset update_settings() end +modalbind.set_x_offset = set_x_offset --- Change vertical offset of the modebox. -- set location for the box with set_corner(). The box is shifted downwards if it -- is in one of the upper corners or upwards otherwise. -- @param amount vertical shift in pixels, or nil to use default -M.set_y_offset = function (amount) +function set_y_offset(amount) settings.y_offset = amount or defaults.y_offset update_settings() end +modalbind.set_y_offset = set_y_offset --- Set the corner, where the modebox will be displayed -- If a parameter is not a valid orientation (see below), the function returns -- without doing anything -- @param vertical either top or bottom -- @param horizontal either left or right -M.set_corner = function (vertical, horizontal) +function set_corner(vertical, horizontal) if (vertical ~= "top" and vertical ~= "bottom") then return end @@ -83,10 +90,12 @@ M.set_corner = function (vertical, horizontal) settings.corner_v = vertical or defaults.corner_v settings.corner_h = horizontal or defaults.corner_h end +modalbind.set_corner = set_corner -M.set_show_options = function (bool) +function set_show_options(bool) settings.show_options = bool end +modalbind.set_show_options = set_show_options local function set_default(s) minwidth, minheight = modewidget[s]:fit(screen[s].geometry.width, @@ -151,12 +160,16 @@ local function hide_box() if s ~= -1 then modewibox[s].visible = false end end -M.grab = function(keymap, stay_in_mode) - if keymap.name then show_box(mouse.screen, keymap) end +function grab(keymap, stay_in_mode) + if keymap.name then + show_box(mouse.screen, keymap) + nesting = nesting + 1 + end keygrabber.run(function(mod, key, event) if key == "Escape" then keygrabber.stop() + nesting = 0 hide_box(); return true end @@ -167,9 +180,10 @@ M.grab = function(keymap, stay_in_mode) keygrabber.stop() keymap[key]() if stay_in_mode then - M.grab(keymap, true) + grab(keymap, true) else - hide_box() + nesting = nesting - 1 + if nesting < 1 then hide_box() end return true end end @@ -177,10 +191,14 @@ M.grab = function(keymap, stay_in_mode) return true end) end -M.grabf = function(keymap, stay_in_mode) - return function() M.grab(keymap, stay_in_mode) end +modalbind.grab = grab + +function grabf(keymap, stay_in_mode) + return function() grab(keymap, stay_in_mode) end end +modalbind.grabf = grabf -M.wibox = function() return modewibox[1] end +function modebox() return modewibox[1] end +modalbind.modebox = modebox -return M +return modalbind diff --git a/mpd.lua b/mpd.lua index 1d8239c..99b3c9b 100644 --- a/mpd.lua +++ b/mpd.lua @@ -1,74 +1,46 @@ ---assert(package.loadlib(MY_PATH .. "./mpdc.so", "luaopen_mpdc")) -require "mpdc" local M = {} -local type = "" local conf = conf +local awful = awful +local log = log -- local functions -local show, mpc_play_search, notify - -local conn = nil +local dmenu, mpc_play_search, notify, mpc local defaults = {} local settings = {} -defaults.host = "127.0.0.1" -defaults.port = 6600 defaults.replace_on_search = true for key, value in pairs(defaults) do settings[key] = value end --- {{{ basic functions - -M.connect = function () - print("Connecting to mpd") - conn = mpdc.open(settings.host, settings.port) +mpc = function(command) + awful.util.spawn("mpc " .. command) end -M.disconnect = function() - if conn ~= nil then conn:close() end - conn = nil -end - -M.ensure_connection = function() - -- connect on first call - if conn == nil then M.connect() end -end - --- }}} - -- {{{ mpd.ctrl submodule M.ctrl = {} M.ctrl.toggle = function () - M.ensure_connection() - conn:toggle() + mpc("toggle") end M.ctrl.play = function () - M.ensure_connection() - conn:play() - -- TODO widget updating + mpc("play") end M.ctrl.pause = function () - M.ensure_connection() - conn:pause() + mpc("pause") end M.ctrl.next = function () - M.ensure_connection() - conn:next() - -- TODO widget updating + mpc("next") end M.ctrl.prev = function () - M.ensure_connection() - conn:prev() - -- TODO widget updating + mpc("prev") end -- }}} @@ -82,22 +54,23 @@ local clear_before = conf.mpd_prompt_clear_before == nil and M.prompt = {} M.prompt.artist = function() - type = "artist" - show() + dmenu("-a") end M.prompt.album = function() - type = "album" - show() + dmenu("-a -b") end M.prompt.title = function() - type = "title" - show() + dmenu("-a -b -t") end M.prompt.title = title +function dmenu(opts) + awful.util.spawn("dmpc " .. (clear_before and "-r" or "-R") .. " " .. opts) +end + M.prompt.replace_on_search = function(bool) clear_before = bool end @@ -109,19 +82,8 @@ M.prompt.toggle_replace_on_search = function() ).. " the playlist") end -function show() - obvious.popup_run_prompt.set_prompt_string("Play ".. type .. ":") - obvious.popup_run_prompt.set_cache("/mpd_ ".. type); - obvious.popup_run_prompt.set_run_function(mpc_play_search) - obvious.popup_run_prompt.run_prompt() -end - function mpc_play_search(s) - if clear_before then conn:clear() end - local result, num = conn:isearch(type, s) - notify("Found " .. (num) .. " matches"); - conn:iadd(result) - conn:play() + notify("Found " .. (s) .. " matches"); end -- }}} diff --git a/obvious b/obvious deleted file mode 160000 index c5b8844..0000000 --- a/obvious +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c5b884459194a15a38b88c99d5558a64efaf4e89 diff --git a/rc.lua b/rc.lua index 64f938f..0e1fe34 100644 --- a/rc.lua +++ b/rc.lua @@ -7,6 +7,7 @@ beautiful = require("autobeautiful") naughty = require("naughty") conf = require("localconf") require("errors") +inspect = require("inspect") -- }}} layouts = require('layouts') @@ -22,6 +23,7 @@ log.add_logger(log.loggers.naughty, 2) tags = require('tags') tags.setup() + -- }}} -- {{{ widgets diff --git a/rules.lua b/rules.lua index b512885..4f50dac 100644 --- a/rules.lua +++ b/rules.lua @@ -129,6 +129,18 @@ local function setup(self) opacity = 0.9 } }, + { + rule = { class = "feh", name = "timetable" }, + properties = { + tag = tags[rule_screen][13], + skip_taskbar = true, + type = desktop, + below = true, + focusable = false, + border_width = 0, + floating = true + } + }, { rule = { instance = "Awesomelog" }, properties = { diff --git a/simplelog.lua b/simplelog.lua index 6526689..b4e4c30 100644 --- a/simplelog.lua +++ b/simplelog.lua @@ -26,10 +26,10 @@ function loglv(msg, level) end end -function debug(msg) +function dbg(msg) loglv(msg, 0) end -simplelog.debug = debug +simplelog.debug = dbg function log(msg) loglv(msg, 1) @@ -50,13 +50,11 @@ function add_logger(logger, level) if level == nil then level = settings.defaultlevel end - print(inspect(logger)) table.insert(settings.loggers, function(msg, severity) if severity >= level then logger(msg, severity) end end) - print(inspect(settings.loggers)) end simplelog.add_logger = add_logger diff --git a/uzbl.lua b/uzbl.lua deleted file mode 100644 index bbd6b22..0000000 --- a/uzbl.lua +++ /dev/null @@ -1,47 +0,0 @@ - - -uzbltag = tags[rule_screen][2] -mytasklist = {} -mytasklist.buttons = awful.util.table.join( -awful.button({ }, 1, function (c) - if c == client.focus then - c.minimized = true - else - if not c:isvisible() then - awful.tag.viewonly(c:tags()[1]) - end - -- This will also un-minimize - -- the client, if needed - client.focus = c - c:raise() - end -end), -awful.button({ }, 3, function () - if instance then - instance:hide() - instance = nil - else - instance = awful.menu.clients({ width=250 }) - end -end), -awful.button({ }, 4, function () - awful.client.focus.byidx(1) - if client.focus then client.focus:raise() end -end), -awful.button({ }, 5, function () - awful.client.focus.byidx(-1) - if client.focus then client.focus:raise() end -end)) - -mytasklist[rule_screen] = awful.widget.tasklist(function(c) - return awful.widget.tasklist.label.currenttags(c, rule_screen) -end, mytasklist.buttons) -uzblbox = {} -uzblbox = awful.wibox({ position = "top", screen = rule_screen }) -uzblbox.visible = false -uzblbox.widgets = { mytasklist[rule_screen], -layout = awful.widget.layout.horizontal.rightleft } - -uzbltag:add_signal("property::selected", function (tag) - uzblbox.visible = tag.selected -end) diff --git a/widgets.lua b/widgets.lua index c1ccffc..9c7b21f 100644 --- a/widgets.lua +++ b/widgets.lua @@ -202,9 +202,9 @@ widgets.add.cpu = cpuwidget -- battery local function batterywidget(name, screen, parent_layout, batname) --{{{ + print("creating batwidget '" .. name .. "' for battery '"..batname.."'") local widget = wibox.widget.textbox() local bg = wibox.widget.background() - print("creating batwidget '" .. name .. "' for battery '"..batname.."'") bg:set_widget(widget) vicious.register(widget, vicious.widgets.bat, function (widget, args) if args[2] == 0 then return ""