modal bindings and extended mpd capabilities
This commit is contained in:
parent
3f3552f4e2
commit
23c922db3d
34
aweswt.lua
34
aweswt.lua
|
@ -1,17 +1,24 @@
|
||||||
-- aweswt.lua
|
-- aweswt.lua
|
||||||
-- Application switcher using dmenu
|
-- Application switcher using dmenu
|
||||||
--
|
--
|
||||||
local io = io
|
|
||||||
local table = table
|
|
||||||
local pairs = pairs
|
|
||||||
local awful = awful
|
|
||||||
local client = client
|
|
||||||
local string = string
|
|
||||||
local USE_NAME = true
|
|
||||||
|
|
||||||
module("aweswt")
|
local M = {}
|
||||||
|
|
||||||
function get_out (a)
|
local dmenu = "dmenu -nf '#888888' -nb '#222222' -sf '#ffffff' -sb '#285577' -p 'switch to application:' -fn 'Terminus 8' -i"
|
||||||
|
|
||||||
|
local get_out, get_input, _switch
|
||||||
|
|
||||||
|
-- switch with window titles
|
||||||
|
M.switch = function()
|
||||||
|
_switch(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- switch with client instance and class
|
||||||
|
M.switch_class = function()
|
||||||
|
_switch(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
get_out = function (a)
|
||||||
local f = io.popen(a)
|
local f = io.popen(a)
|
||||||
t = {}
|
t = {}
|
||||||
for line in f:lines() do
|
for line in f:lines() do
|
||||||
|
@ -20,13 +27,12 @@ function get_out (a)
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_input (a)
|
get_input = function (a)
|
||||||
local dmenu = "dmenu -nf '#888888' -nb '#222222' -sf '#ffffff' -sb '#285577' -p 'switch to application:' -fn 'Terminus 8' -i"
|
|
||||||
s1 = 'echo "' .. a .. '" | ' .. dmenu
|
s1 = 'echo "' .. a .. '" | ' .. dmenu
|
||||||
return get_out(s1)
|
return get_out(s1)
|
||||||
end
|
end
|
||||||
|
|
||||||
function switch ()
|
_switch = function(use_name)
|
||||||
local clients = client.get()
|
local clients = client.get()
|
||||||
|
|
||||||
if table.getn(clients) == 0 then
|
if table.getn(clients) == 0 then
|
||||||
|
@ -39,8 +45,7 @@ function switch ()
|
||||||
for key, client in pairs(clients) do
|
for key, client in pairs(clients) do
|
||||||
local app
|
local app
|
||||||
|
|
||||||
if USE_NAME then
|
if use_name then
|
||||||
--app = key .. ':' .. string.sub(client['name'], 1, 20)
|
|
||||||
app = client['name']
|
app = client['name']
|
||||||
else
|
else
|
||||||
app = key .. ':' .. client['instance'] .. '.' .. client['class']
|
app = key .. ':' .. client['instance'] .. '.' .. client['class']
|
||||||
|
@ -64,3 +69,4 @@ function switch ()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
230
bindings.lua
230
bindings.lua
|
@ -1,3 +1,6 @@
|
||||||
|
local aweswt = require("aweswt")
|
||||||
|
local mb = require("modalbind")
|
||||||
|
local mpd = require("mpd")
|
||||||
|
|
||||||
-- {{{ Mouse bindings
|
-- {{{ Mouse bindings
|
||||||
root.buttons(awful.util.table.join(
|
root.buttons(awful.util.table.join(
|
||||||
|
@ -7,128 +10,149 @@ awful.button({ }, 5, awful.tag.viewprev)
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
|
|
||||||
|
mpdmap = {
|
||||||
|
name = "MPD",
|
||||||
|
m = mpd.ctrl.toggle,
|
||||||
|
n = mpd.ctrl.next,
|
||||||
|
N = mpd.ctrl.prev,
|
||||||
|
s = function() awful.util.spawn("mpd") end,
|
||||||
|
g = function () awful.util.spawn(cmd.mpd_client) end,
|
||||||
|
d = mpd.disconnect,
|
||||||
|
c = mpd.connect
|
||||||
|
}
|
||||||
|
mpdpromts = {
|
||||||
|
name = "MPD PROMPTS",
|
||||||
|
a = mpd.prompt.artist,
|
||||||
|
A = mpd.prompt.album,
|
||||||
|
t = mpd.prompt.title,
|
||||||
|
r = mpd.prompt.toggle_replace_on_search,
|
||||||
|
}
|
||||||
|
|
||||||
|
progmap = {
|
||||||
|
name = "PROGRAMS",
|
||||||
|
f = function () awful.util.spawn(cmd.browser) end,
|
||||||
|
i = function () awful.util.spawn(cmd.im_client) end,
|
||||||
|
m = function () awful.util.spawn(cmd.mail_client) end
|
||||||
|
}
|
||||||
|
|
||||||
-- {{{ Key bindings
|
-- {{{ Key bindings
|
||||||
globalkeys = awful.util.table.join(
|
globalkeys = awful.util.table.join(
|
||||||
--{{{ Focus and Tags
|
--{{{ Focus and Tags
|
||||||
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
|
awful.key({ modkey, }, "Left", awful.tag.viewprev ),
|
||||||
awful.key({ modkey, }, "Right", awful.tag.viewnext ),
|
awful.key({ modkey, }, "Right", awful.tag.viewnext ),
|
||||||
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
|
awful.key({ modkey, }, "Escape", awful.tag.history.restore),
|
||||||
|
|
||||||
awful.key({ modkey, }, "j",
|
awful.key({ modkey, }, "j",
|
||||||
function ()
|
function ()
|
||||||
awful.client.focus.byidx( 1)
|
awful.client.focus.byidx( 1)
|
||||||
if client.focus then client.focus:raise() end
|
if client.focus then client.focus:raise() end
|
||||||
end),
|
end),
|
||||||
awful.key({ modkey, }, "k",
|
awful.key({ modkey, }, "k",
|
||||||
function ()
|
function ()
|
||||||
awful.client.focus.byidx(-1)
|
awful.client.focus.byidx(-1)
|
||||||
if client.focus then client.focus:raise() end
|
if client.focus then client.focus:raise() end
|
||||||
end),
|
end),
|
||||||
|
|
||||||
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
|
awful.key({ modkey, "Control" }, "j", function ()
|
||||||
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
|
awful.screen.focus_relative( 1)
|
||||||
--}}}
|
end),
|
||||||
|
|
||||||
--{{{ Layout manipulation
|
awful.key({ modkey, "Control" }, "k", function ()
|
||||||
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
|
awful.screen.focus_relative(-1)
|
||||||
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
|
end),
|
||||||
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
|
|
||||||
awful.key({ modkey, }, "Tab",
|
|
||||||
function ()
|
|
||||||
awful.client.focus.history.previous()
|
|
||||||
if client.focus then
|
|
||||||
client.focus:raise()
|
|
||||||
end
|
|
||||||
end),
|
|
||||||
awful.key({ "Mod1", }, "Tab",
|
|
||||||
function ()
|
|
||||||
awful.client.focus.history.previous()
|
|
||||||
if client.focus then
|
|
||||||
client.focus:raise()
|
|
||||||
end
|
|
||||||
end),
|
|
||||||
--}}}
|
|
||||||
--
|
|
||||||
--{{{ Spawns
|
|
||||||
awful.key({ modkey, }, "Return", function () awful.util.spawn(terminal) end),
|
|
||||||
awful.key({ modkey, }, "f", function () awful.util.spawn("webbrowser") end),
|
|
||||||
awful.key({ modkey, }, "t", function () awful.util.spawn("mail-client") end),
|
|
||||||
awful.key({ modkey, }, "p", function () awful.util.spawn("im-client") end),
|
|
||||||
awful.key({ modkey, }, "g", function () awful.util.spawn("gmpc") end),
|
|
||||||
awful.key({ modkey, }, "w", function () awful.util.spawn("awsetbg -a -r /home/crater2150/.config/awesome/walls/ &") end),
|
|
||||||
awful.key({ modkey, "Control" }, "r", awesome.restart),
|
|
||||||
awful.key({ modkey, "Shift" }, "q", awesome.quit),
|
|
||||||
awful.key({ }, "Menu", aweswt.switch),
|
|
||||||
awful.key({ modkey }, "BackSpace", rodentbane.start),
|
|
||||||
--}}}
|
|
||||||
|
|
||||||
--{{{ tabletpc keys
|
awful.key({ }, "Menu", aweswt.switch),
|
||||||
|
--}}}
|
||||||
|
|
||||||
awful.key({ hyper }, "6", function () awful.util.spawn("/usr/local/bin/rotate") end),
|
--{{{ Layout manipulation
|
||||||
awful.key({ modkey }, "x", function () teardrop("cellwriter","top","center", 0.99, 0.4)end ),
|
awful.key({ modkey, "Shift" }, "j", function ()
|
||||||
awful.key({ modkey, "Control" }, "Delete", function () awful.util.spawn("xlock") end),
|
awful.client.swap.byidx( 1)
|
||||||
|
end),
|
||||||
|
|
||||||
awful.key({ hyper }, "1", function () awful.util.spawn("/usr/local/bin/tabletstick 1") end),
|
awful.key({ modkey, "Shift" }, "k", function ()
|
||||||
awful.key({ hyper }, "2", function () awful.util.spawn("/usr/local/bin/tabletstick 2") end),
|
awful.client.swap.byidx( -1)
|
||||||
awful.key({ hyper }, "3", function () awful.util.spawn("/usr/local/bin/tabletstick 3") end),
|
end),
|
||||||
awful.key({ hyper }, "4", function () awful.util.spawn("/usr/local/bin/tabletstick 4") end),
|
|
||||||
awful.key({ hyper }, "5", function () awful.util.spawn("/usr/local/bin/tabletstick 4") end),
|
awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
|
||||||
|
awful.key({ modkey, }, "Tab", function ()
|
||||||
|
awful.client.focus.history.previous()
|
||||||
|
if client.focus then
|
||||||
|
client.focus:raise()
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
awful.key({ "Mod1", }, "Tab", function ()
|
||||||
|
awful.client.focus.history.previous()
|
||||||
|
if client.focus then
|
||||||
|
client.focus:raise()
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
|
||||||
|
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
|
||||||
|
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
|
||||||
|
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
|
||||||
|
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
|
||||||
|
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
|
||||||
|
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
|
||||||
|
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
|
||||||
|
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, 0) end),
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ thinkpad
|
awful.key({ modkey, "Control" }, "r", awesome.restart),
|
||||||
|
awful.key({ modkey, "Shift" }, "q", awesome.quit),
|
||||||
|
awful.key({ modkey, }, "Return", function () awful.util.spawn(cmd.terminal) end),
|
||||||
|
|
||||||
awful.key({ }, "XF86Sleep", function () awful.util.spawn("/usr/local/bin/s2ram")end ),
|
--{{{ Modal mappings
|
||||||
awful.key({ }, "XF86Away", function () awful.util.spawn("xlock")end ),
|
|
||||||
awful.key({ }, "XF86TouchpadToggle", function () awful.util.spawn("touchpad")end ),
|
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),
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
--{{{ Audio control
|
--{{{ Audio control
|
||||||
awful.key({ }, "Print", function () teardrop("urxvtc -e alsamixer","top","center", 0.99, 0.4)end ),
|
|
||||||
awful.key({ }, "XF86AudioLowerVolume", function () awful.util.spawn("amixer set Master 2%-")end ),
|
|
||||||
awful.key({ }, "XF86AudioRaiseVolume", function () awful.util.spawn("amixer set Master 2%+")end ),
|
|
||||||
awful.key({ }, "XF86AudioMute", function () awful.util.spawn("amixer set Master toggle") end),
|
|
||||||
awful.key({ modkey }, "m", function () awful.util.spawn("mpc toggle") end),
|
|
||||||
awful.key({ modkey }, ">", function () awful.util.spawn("mpc next") end),
|
|
||||||
awful.key({ modkey }, "<", function () awful.util.spawn("mpc prev") end),
|
|
||||||
awful.key({ modkey , "Shift" }, "m", mpd_prompt.grabber),
|
|
||||||
awful.key({ }, "XF86AudioPlay", function () awful.util.spawn("mpc toggle") end),
|
|
||||||
awful.key({ }, "XF86AudioNext", function () awful.util.spawn("mpc next") end),
|
|
||||||
awful.key({ }, "XF86AudioPrev", function () awful.util.spawn("mpc prev") end),
|
|
||||||
awful.key({ modkey }, "`", function () teardrop("urxvtc -e ncmpcpp","bottom","center", 0.99, 0.4)end ),
|
|
||||||
|
|
||||||
--}}}
|
awful.key({ }, "XF86AudioLowerVolume", function () awful.util.spawn("amixer set Master 2%-")end ),
|
||||||
|
awful.key({ }, "XF86AudioRaiseVolume", function () awful.util.spawn("amixer set Master 2%+")end ),
|
||||||
|
awful.key({ }, "XF86AudioMute", function () awful.util.spawn("amixer set Master toggle") end),
|
||||||
|
awful.key({ }, "XF86AudioPlay", mpd.ctrl.toggle),
|
||||||
|
awful.key({ }, "XF86AudioNext", mpd.ctrl.next),
|
||||||
|
awful.key({ }, "XF86AudioPrev", mpd.ctrl.prev),
|
||||||
|
|
||||||
--{{{ Prompt
|
--}}}
|
||||||
|
|
||||||
awful.key({ modkey }, "r", function ()
|
-- {{{ teardrops
|
||||||
obvious.popup_run_prompt.set_prompt_string(" Run~ ")
|
awful.key({ }, "F12", function () teardrop(cmd.terminal,"center","center", 0.99, 0.7)end ),
|
||||||
obvious.popup_run_prompt.set_cache("history")
|
awful.key({ modkey }, "`", function () teardrop("urxvtc -e ncmpcpp","bottom","center", 0.99, 0.4)end ),
|
||||||
obvious.popup_run_prompt.set_run_function(awful.util.spawn)
|
awful.key({ }, "Print", function () teardrop("urxvtc -e alsamixer","top","center", 0.99, 0.4)end ),
|
||||||
obvious.popup_run_prompt.run_prompt()
|
-- }}}
|
||||||
end),
|
|
||||||
awful.key({ modkey }, "e", function ()
|
|
||||||
obvious.popup_run_prompt.set_prompt_string(" exec Lua~ ")
|
|
||||||
obvious.popup_run_prompt.set_cache("history_eval")
|
|
||||||
obvious.popup_run_prompt.set_run_function(awful.util.eval)
|
|
||||||
obvious.popup_run_prompt.run_prompt()
|
|
||||||
end),
|
|
||||||
awful.key({ }, "F12", function () teardrop(terminal,"center","center", 0.99, 0.7)end ),
|
|
||||||
|
|
||||||
--}}}
|
--{{{ Prompt
|
||||||
|
|
||||||
--{{{ Default
|
awful.key({ modkey }, "r", function ()
|
||||||
awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end),
|
obvious.popup_run_prompt.set_prompt_string(" Run~ ")
|
||||||
awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end),
|
obvious.popup_run_prompt.set_cache("history")
|
||||||
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1) end),
|
obvious.popup_run_prompt.set_run_function(awful.util.spawn)
|
||||||
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1) end),
|
obvious.popup_run_prompt.run_prompt()
|
||||||
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1) end),
|
end),
|
||||||
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1) end),
|
awful.key({ modkey }, "e", function ()
|
||||||
awful.key({ modkey, }, "space", function () awful.layout.inc(layouts, 1) end),
|
obvious.popup_run_prompt.set_prompt_string(" exec Lua~ ")
|
||||||
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(layouts, 0) end)
|
obvious.popup_run_prompt.set_cache("history_eval")
|
||||||
|
obvious.popup_run_prompt.set_run_function(awful.util.eval)
|
||||||
|
obvious.popup_run_prompt.run_prompt()
|
||||||
|
end),
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
|
--{{{ misc. XF86 Keys
|
||||||
|
|
||||||
|
awful.key({ }, "XF86Sleep", function () awful.util.spawn("/usr/local/bin/s2ram")end ),
|
||||||
|
awful.key({ }, "XF86Away", function () awful.util.spawn("xlock")end ),
|
||||||
|
awful.key({ }, "XF86TouchpadToggle", function () awful.util.spawn("touchpad")end ),
|
||||||
|
|
||||||
|
--}}}
|
||||||
|
|
||||||
|
awful.key({ modkey }, "BackSpace", rodentbane.start)
|
||||||
)
|
)
|
||||||
|
|
||||||
function client_opacity_set(c, default, max, step)
|
function client_opacity_set(c, default, max, step)
|
||||||
|
@ -159,7 +183,7 @@ clientkeys = awful.util.table.join(
|
||||||
awful.key({ }, "XF86Calculater", awful.client.movetoscreen )
|
awful.key({ }, "XF86Calculater", awful.client.movetoscreen )
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Compute the maximum number of digit we need, limited to 9
|
-- Compute the maximum number of digit we need, limited to 22
|
||||||
keynumber = 0
|
keynumber = 0
|
||||||
for s = 1, screen.count() do
|
for s = 1, screen.count() do
|
||||||
keynumber = math.min(22, math.max(#tags[s], keynumber));
|
keynumber = math.min(22, math.max(#tags[s], keynumber));
|
||||||
|
@ -214,3 +238,5 @@ clientbuttons = awful.util.table.join(
|
||||||
-- Set keys
|
-- Set keys
|
||||||
root.keys(globalkeys)
|
root.keys(globalkeys)
|
||||||
-- }}}
|
-- }}}
|
||||||
|
-- vim: set fenc=utf-8 tw=80 foldmethod=marker :
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
terminal = "urxvtc -e tmux"
|
terminal = "urxvtc -e tmux"
|
||||||
editor_cmd = "urxvtc -e vim"
|
|
||||||
modkey = "Mod4"
|
modkey = "Mod4"
|
||||||
hyper = "Mod3"
|
|
||||||
rule_screen=1
|
rule_screen=1
|
||||||
|
|
601
luampd.lua
Normal file
601
luampd.lua
Normal file
|
@ -0,0 +1,601 @@
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
-- Copyright (c) 2006 Stephen M. Jothen
|
||||||
|
-- All rights reserved.
|
||||||
|
--
|
||||||
|
-- Redistribution and use in source and binary forms, with or without
|
||||||
|
-- modification, are permitted provided that the following conditions
|
||||||
|
-- are met:
|
||||||
|
-- 1. Redistributions of source code must retain the above copyright
|
||||||
|
-- notice, this list of conditions and the following disclaimer.
|
||||||
|
-- 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
-- notice, this list of conditions and the following disclaimer in the
|
||||||
|
-- documentation and/or other materials provided with the distribution.
|
||||||
|
-- 3. The name of the author may not be used to endorse or promote products
|
||||||
|
-- derived from this software without specific prior written permission.
|
||||||
|
--
|
||||||
|
-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
-- LuaMPD - Lua interface to the MusicPD protocol
|
||||||
|
--
|
||||||
|
-- Author: Steve Jothen <sjothen at gmail dot com>
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Classes and requires
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
local socket = require("socket")
|
||||||
|
local luampd = {}
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Private functions and tables
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
-- errors taken from ack.h in the mpd sources
|
||||||
|
local err_table = {
|
||||||
|
["1"] = "ACK_ERROR_NOT_LIST",
|
||||||
|
["2"] = "ACK_ERROR_ARG",
|
||||||
|
["3"] = "ACK_ERROR_PASSWORD",
|
||||||
|
["4"] = "ACK_ERROR_PERMISSION",
|
||||||
|
["5"] = "ACK_ERROR_UNKNOWN",
|
||||||
|
|
||||||
|
["50"] = "ACK_ERROR_NO_EXIST",
|
||||||
|
["51"] = "ACK_ERROR_PLAYLIST_MAX",
|
||||||
|
["52"] = "ACK_ERROR_SYSTEM",
|
||||||
|
["53"] = "ACK_ERROR_PLAYLIST_LOAD",
|
||||||
|
["54"] = "ACK_ERROR_UPDATE_ALREADY",
|
||||||
|
["55"] = "ACK_ERROR_PLAYER_SYNC",
|
||||||
|
["56"] = "ACK_ERROR_EXIST",
|
||||||
|
}
|
||||||
|
|
||||||
|
-- turns a table of strings into groups seperated by a
|
||||||
|
-- delimiting string, and then turns each group of lines
|
||||||
|
-- into key, value pair tables
|
||||||
|
local function multi_hash(delimiter, lines)
|
||||||
|
local size = table.maxn(lines)
|
||||||
|
local patches = {}
|
||||||
|
local patch = {}
|
||||||
|
|
||||||
|
while size >= 1 do
|
||||||
|
|
||||||
|
if string.find(lines[size], delimiter) then
|
||||||
|
-- add to the patches repository
|
||||||
|
local k, v = socket.skip(2, string.find(lines[size], "(.+):%s(.+)"))
|
||||||
|
|
||||||
|
if k and v then
|
||||||
|
-- we have our key value pair!
|
||||||
|
patch[string.lower(k)] = v
|
||||||
|
-- we want the key to be lowercase
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(patches, patch)
|
||||||
|
patch = {}
|
||||||
|
|
||||||
|
else
|
||||||
|
-- were still modifying the current patch
|
||||||
|
local k, v = socket.skip(2, string.find(lines[size], "(.+):%s(.+)"))
|
||||||
|
|
||||||
|
if k and v then
|
||||||
|
patch[string.lower(k)] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
size = size - 1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return patches
|
||||||
|
end
|
||||||
|
|
||||||
|
-- will turn a table of strings that match
|
||||||
|
-- key: value
|
||||||
|
-- into a table such as { key = value, key2 = value2 }
|
||||||
|
local function hash(lines)
|
||||||
|
local hash = {}
|
||||||
|
for key, value in pairs(lines) do
|
||||||
|
local k, v = socket.skip(2, string.find(value, "(.+):%s(.+)"))
|
||||||
|
if k and v then
|
||||||
|
-- lowercase the key for easier access (tabl.artist rather than tabl.Artist)
|
||||||
|
hash[string.lower(k)] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function handle_error(line)
|
||||||
|
-- line is the actual error line received from mpd
|
||||||
|
local err_num, com_num = socket.skip(2, string.find(line, "ACK %[(%d+)@(%d+)%]"))
|
||||||
|
if err_table[err_num] then
|
||||||
|
error(err_table[err_num])
|
||||||
|
else
|
||||||
|
-- unknown error
|
||||||
|
error(err_table["5"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_response(obj, command)
|
||||||
|
|
||||||
|
-- collect the lines into this table
|
||||||
|
local response_lines = {}
|
||||||
|
|
||||||
|
if obj.socket then
|
||||||
|
obj.socket:send(command .. '\n')
|
||||||
|
-- send the command with newline and collect response
|
||||||
|
-- a response is everything up until an ACK or OK
|
||||||
|
local line = obj.socket:receive("*l")
|
||||||
|
while (line ~= "OK") do
|
||||||
|
if line == nil then
|
||||||
|
-- bug?? on ubuntu mpd will close socket randomly
|
||||||
|
-- with large playlists while listing them
|
||||||
|
-- try playlistinfo (with playlist size > 13000)
|
||||||
|
error("SOCKET_ERROR")
|
||||||
|
elseif string.sub(line, 1, 3) == "ACK" then
|
||||||
|
break
|
||||||
|
-- let us handle this erro
|
||||||
|
end
|
||||||
|
table.insert(response_lines, line)
|
||||||
|
line = obj.socket:receive("*l")
|
||||||
|
end
|
||||||
|
-- if we stopped on an ACK then we better return information about it..
|
||||||
|
-- last line in the table will be the ack message
|
||||||
|
if string.sub(line, 1, 3) == "ACK" then
|
||||||
|
handle_error(line)
|
||||||
|
--elseif line == "OK" then
|
||||||
|
-- return true
|
||||||
|
else
|
||||||
|
return response_lines
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- not connected??
|
||||||
|
error("SOCKET_ERROR")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Public instance methods
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
function luampd:new(info)
|
||||||
|
|
||||||
|
-- local instance of object
|
||||||
|
|
||||||
|
local instance = {
|
||||||
|
hostname = info.hostname or "localhost",
|
||||||
|
password = info.password or nil,
|
||||||
|
port = info.port or 6600,
|
||||||
|
debug = info.debug or false,
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.socket = socket.connect(instance.hostname, instance.port)
|
||||||
|
|
||||||
|
if instance.socket then
|
||||||
|
-- try and get ok from the server
|
||||||
|
local line = instance.socket:receive("*l")
|
||||||
|
if line:find("OK MPD (.+)") then
|
||||||
|
-- connected, send password
|
||||||
|
if instance.password then
|
||||||
|
instance.socket:send(string.format("password %s\n", self.password))
|
||||||
|
-- correct password?
|
||||||
|
local ok_pass = instance.socket:receive("*l")
|
||||||
|
if ok_pass ~= "OK" then
|
||||||
|
error(string.format("Wrong password to %s:d", instance.hostname, instance.port))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- not mpd or wrong hostname
|
||||||
|
error(string.format("Cant get response from %s:%d", instance.hostname, instance.port))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- socket.connect returns nil, somethings wrong
|
||||||
|
error(string.format("Socket cant connect to %s:%d", instance.hostname, instance.port))
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(instance, { __index = luampd })
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Admin functions
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
-- Some of these functions are in the documentation but dont work?
|
||||||
|
-- disableoutput, enableoutput
|
||||||
|
function luampd:disableoutput(outputid)
|
||||||
|
get_response(self, string.format("disableoutput %d", outputid))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:enableoutput(outputid)
|
||||||
|
get_response(self, string.format("enableoutput %d", outputid))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:kill()
|
||||||
|
get_response(self, "kill")
|
||||||
|
self.socket = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:outputs()
|
||||||
|
local response = get_response(self, "outputs")
|
||||||
|
return hash(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:update()
|
||||||
|
get_response(self, "update")
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Database functions
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
function luampd:find(stype, swhat)
|
||||||
|
local send_string = string.format("find %s \"%s\"", stype, swhat)
|
||||||
|
local data = get_response(self, send_string)
|
||||||
|
return multi_hash("^file:", data)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- how should we handle these functions?
|
||||||
|
-- list/listall/lsinfo
|
||||||
|
function luampd:list(meta, meta2, search)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:listall(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:listallinfo(path)
|
||||||
|
local send_string
|
||||||
|
if path then
|
||||||
|
send_string = string.format("listallinfo \"%s\"", path)
|
||||||
|
else
|
||||||
|
send_string = "listallinfo"
|
||||||
|
end
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
local songs = multi_hash("file:(.+)", response)
|
||||||
|
return songs
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:lsinfo(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:search(stype, swhat)
|
||||||
|
local send_string = string.format("search %s \"%s\"", stype, swhat)
|
||||||
|
local data = get_response(self, send_string)
|
||||||
|
return multi_hash("^file:", data)
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Playlist functions
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
function luampd:add(file)
|
||||||
|
local add = string.format("add \"%s\"", file)
|
||||||
|
get_response(self, add)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:clear()
|
||||||
|
get_response(self, "clear")
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:currentsong()
|
||||||
|
local song = get_response(self, "currentsong")
|
||||||
|
local hash = hash(song)
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:delete(song)
|
||||||
|
get_response(self, string.format("delete %d", song))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:deleteid(songid)
|
||||||
|
get_response(self, string.format("deleteid %s", songid))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:load_playlist(path)
|
||||||
|
get_response(self, string.format("load %s", path))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:move(from, to)
|
||||||
|
get_response(self, string.format("move %d %d", from, to))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:moveid(fromid, toid)
|
||||||
|
get_response(self, string.format("moveid %d %d", fromid, toid))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:playlistinfo(song)
|
||||||
|
local send_string
|
||||||
|
if song then
|
||||||
|
send_string = string.format("playlistinfo %d", song)
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
return hash(response)
|
||||||
|
else
|
||||||
|
send_string = "playlistinfo"
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
return multi_hash("^file:", response)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:playlistid(songid)
|
||||||
|
local send_string
|
||||||
|
if songid then
|
||||||
|
send_string = string.format("playlistid %d", songid)
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
return hash(response)
|
||||||
|
else
|
||||||
|
send_string = "playlistid"
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
return multi_hash("^file:", response)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:plchanges(version)
|
||||||
|
local send_string = string.format("plchanges %d", version)
|
||||||
|
local response = get_response(self, send_string)
|
||||||
|
return multi_hash(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:plchangesposid(version)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:rm(name)
|
||||||
|
get_response(self,
|
||||||
|
string.format("rm \"%s\"", name))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:save(name)
|
||||||
|
get_response(self,
|
||||||
|
string.format("save \"%s\"", name))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:shuffle()
|
||||||
|
get_response(self, "shuffle")
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:swap(song1, song2)
|
||||||
|
get_response(self,
|
||||||
|
string.format("swap %d %d", song1, song2))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:swapid(songid1, songid2)
|
||||||
|
get_response(self,
|
||||||
|
string.format("swapid %d %d", songid1, songid2))
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Playback functions
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
-- Some of the common tables:
|
||||||
|
--
|
||||||
|
-- Status:
|
||||||
|
-- Fields: volume, repeat, random, playlist, playlistlength, xfade,
|
||||||
|
-- state, song, songid, time, bitrate, audio
|
||||||
|
--
|
||||||
|
-- CurrentSong:
|
||||||
|
-- Fields: file, artist, album, track, title, time, pos, id
|
||||||
|
|
||||||
|
-- sets the crossfading to seconds and returns the xfade status
|
||||||
|
--
|
||||||
|
function luampd:crossfade(seconds)
|
||||||
|
get_response(self,
|
||||||
|
string.format("crossfade %d", seconds))
|
||||||
|
return self:status()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- go to next song, returns song table
|
||||||
|
--
|
||||||
|
function luampd:next_()
|
||||||
|
get_response(self, "next")
|
||||||
|
return self:currentsong()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- pause the current song, returns true/false
|
||||||
|
-- (play, pause, stop, etc)
|
||||||
|
--
|
||||||
|
function luampd:pause()
|
||||||
|
get_response(self, "pause")
|
||||||
|
if self:status()["state"] == "pause" then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- starts playing, returns the current song as a table
|
||||||
|
--
|
||||||
|
function luampd:play()
|
||||||
|
get_response(self, "play")
|
||||||
|
return self:currentsong()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- start playing a song by its song id
|
||||||
|
--
|
||||||
|
function luampd:playid(songid)
|
||||||
|
get_response(self,
|
||||||
|
string.format("playid %d", songid))
|
||||||
|
return self:currentsong()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- go to the previous song and return the current song
|
||||||
|
--
|
||||||
|
function luampd:previous()
|
||||||
|
get_response(self, "previous")
|
||||||
|
return self:currentsong()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sets random on or off (state should be either
|
||||||
|
-- 1 (for on) or 0 (for off))
|
||||||
|
--
|
||||||
|
function luampd:random(state)
|
||||||
|
get_response(self,
|
||||||
|
string.format("random %d", state))
|
||||||
|
if self:state()["random"] == tostring(state) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sets repeat (see above about state)
|
||||||
|
--
|
||||||
|
function luampd:repeat_(state)
|
||||||
|
get_response(self,
|
||||||
|
string.format("repeat %d", state))
|
||||||
|
if self:state()["repeat"] == tostring(state) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- seeks to the specified time (in seconds) in the song
|
||||||
|
-- returns status
|
||||||
|
function luampd:seek(song, time)
|
||||||
|
get_response(self,
|
||||||
|
string.format("seek %d %d", song, time))
|
||||||
|
return self:status()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- same as above, except uses songid instead of song
|
||||||
|
-- returns status
|
||||||
|
function luampd:seekid(songid, time)
|
||||||
|
get_response(self,
|
||||||
|
string.format("seekid %d %d", songid, time))
|
||||||
|
return self:status()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set the volume (0-100), anything lower or higher should be handled
|
||||||
|
-- by the server (-10 will become 0, 110 will become 100)
|
||||||
|
-- returns status object
|
||||||
|
--
|
||||||
|
function luampd:setvol(vol)
|
||||||
|
get_response(self,
|
||||||
|
string.format("setvol %d", vol))
|
||||||
|
if self:status()["volume"] == tostring(vol) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- stops playing and returns the current status object
|
||||||
|
function luampd:stop()
|
||||||
|
get_response(self, "stop")
|
||||||
|
if self:status()["state"] == "stop" then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- Miscellaneous functions
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
function luampd:clearerror()
|
||||||
|
get_response(self, "clearerror")
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
function luampd:close()
|
||||||
|
get_response(self, "close")
|
||||||
|
self.socket = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:commands()
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:notcommands()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- wrong password handled in get_response
|
||||||
|
function luampd:password(pass)
|
||||||
|
get_response(self,
|
||||||
|
string.format("password %s", pass))
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:ping()
|
||||||
|
get_response(self, "ping")
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:stats()
|
||||||
|
local stats = get_response(self, "stats")
|
||||||
|
return hash(stats)
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:status()
|
||||||
|
local status = get_response(self, "status")
|
||||||
|
return hash(status)
|
||||||
|
end
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
-- More lua-esque functions, iterators
|
||||||
|
------------------------------------------------
|
||||||
|
-- 2011-03-15 crater2150: let iterators return size, which is already calculated
|
||||||
|
-- anyway
|
||||||
|
|
||||||
|
function luampd:database()
|
||||||
|
local dbase = self:listallinfo(nil)
|
||||||
|
local count = 0
|
||||||
|
local size = table.maxn(dbase)
|
||||||
|
return function()
|
||||||
|
count = count + 1
|
||||||
|
if count <= size then
|
||||||
|
return dbase[count]
|
||||||
|
end
|
||||||
|
end, size
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:playlist()
|
||||||
|
local plist = self:playlistinfo(nil)
|
||||||
|
local count = 0
|
||||||
|
local size = table.maxn(plist)
|
||||||
|
return function()
|
||||||
|
count = count + 1
|
||||||
|
if count <= size then
|
||||||
|
return plist[count]
|
||||||
|
end
|
||||||
|
end, size
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:ifind(stype, swhat)
|
||||||
|
local found = self:find(stype, swhat)
|
||||||
|
local count = 0
|
||||||
|
local size = table.maxn(found)
|
||||||
|
return function()
|
||||||
|
count = count + 1
|
||||||
|
if count <= size then
|
||||||
|
return found[count]
|
||||||
|
end
|
||||||
|
end, size
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:isearch(stype, swhat)
|
||||||
|
local found = self:search(stype, swhat)
|
||||||
|
local count = 0
|
||||||
|
local size = table.maxn(found)
|
||||||
|
return function()
|
||||||
|
count = count + 1
|
||||||
|
if count <= size then
|
||||||
|
return found[count]
|
||||||
|
end
|
||||||
|
end, size
|
||||||
|
end
|
||||||
|
|
||||||
|
function luampd:iadd(file_iterator)
|
||||||
|
for song in file_iterator do
|
||||||
|
self:add(song.file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return luampd
|
148
modalbind.lua
Normal file
148
modalbind.lua
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
local M = {}
|
||||||
|
local inited = false
|
||||||
|
local modewidget = {}
|
||||||
|
local modewibox = { screen = -1 }
|
||||||
|
|
||||||
|
--local functions
|
||||||
|
local ensure_init, set_default, update_settings, show_box, hide_box
|
||||||
|
M.grab = function(keymap, stay_in_mode)
|
||||||
|
if keymap.name then show_box(mouse.screen, keymap) end
|
||||||
|
|
||||||
|
keygrabber.run(function(mod, key, event)
|
||||||
|
if key == "Escape" then
|
||||||
|
keygrabber.stop()
|
||||||
|
hide_box();
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if event == "release" then return true end
|
||||||
|
|
||||||
|
if keymap[key] then
|
||||||
|
keygrabber.stop()
|
||||||
|
keymap[key]()
|
||||||
|
if stay_in_mode then
|
||||||
|
M.grab(keymap, true)
|
||||||
|
else
|
||||||
|
hide_box()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Partially adapted from Obvious Widget Library module "popup_run_prompt" --
|
||||||
|
-- Original Author: Andrei "Garoth" Thorp --
|
||||||
|
-- Copyright 2009 Andrei "Garoth" Thorp --
|
||||||
|
|
||||||
|
local defaults = {}
|
||||||
|
-- Default is 1 for people without compositing
|
||||||
|
defaults.opacity = 1.0
|
||||||
|
defaults.height = 22
|
||||||
|
defaults.border_width = 1
|
||||||
|
defaults.x_offset = 18
|
||||||
|
defaults.show_options = true
|
||||||
|
|
||||||
|
-- Clone the defaults for the used settings
|
||||||
|
local settings = {}
|
||||||
|
for key, value in pairs(defaults) do
|
||||||
|
settings[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
M.set_opacity = function (amount)
|
||||||
|
settings.opacity = amount or defaults.opacity
|
||||||
|
update_settings()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.set_height = function (amount)
|
||||||
|
settings.height = amount or defaults.height
|
||||||
|
update_settings()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.set_border_width = function (amount)
|
||||||
|
settings.border_width = amount or defaults.border_width
|
||||||
|
update_settings()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.set_x_offset = function (amount)
|
||||||
|
settings.x_offset = amount or defaults.x_offset
|
||||||
|
update_settings()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.set_show_options = function (bool)
|
||||||
|
settings.show_options = bool
|
||||||
|
end
|
||||||
|
|
||||||
|
ensure_init = function ()
|
||||||
|
if inited then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
inited = true
|
||||||
|
for s = 1, screen.count() do
|
||||||
|
modewidget[s] = widget({
|
||||||
|
type = "textbox",
|
||||||
|
name = "modewidget" .. s,
|
||||||
|
align = "center"
|
||||||
|
})
|
||||||
|
|
||||||
|
modewibox[s] = wibox({
|
||||||
|
fg = beautiful.fg_normal,
|
||||||
|
bg = beautiful.bg_normal,
|
||||||
|
border_width = settings.border_width,
|
||||||
|
border_color = beautiful.bg_focus,
|
||||||
|
})
|
||||||
|
set_default(s)
|
||||||
|
modewibox[s].visible = false
|
||||||
|
modewibox[s].screen = s
|
||||||
|
modewibox[s].ontop = true
|
||||||
|
|
||||||
|
-- Widgets for prompt wibox
|
||||||
|
modewibox[s].widgets = {
|
||||||
|
modewidget[s],
|
||||||
|
layout = awful.widget.layout.vertical.center
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set_default = function (s)
|
||||||
|
modewibox[s]:geometry({
|
||||||
|
width = modewidget[s].extents(modewidget[s]).width,
|
||||||
|
height = settings.height,
|
||||||
|
x = settings.x_offset < 0 and
|
||||||
|
screen[s].geometry.x - width + settings.x_offset or
|
||||||
|
settings.x_offset,
|
||||||
|
y = screen[s].geometry.y + screen[s].geometry.height - settings.height
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
update_settings = function ()
|
||||||
|
for s, value in ipairs(modewibox) do
|
||||||
|
value.border_width = settings.border_width
|
||||||
|
set_default(s)
|
||||||
|
value.opacity = settings.opacity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
show_box = function (s, map)
|
||||||
|
ensure_init()
|
||||||
|
modewibox.screen = s
|
||||||
|
local label = " -- " .. map.name .. " -- "
|
||||||
|
if settings.show_options then
|
||||||
|
for key in pairs(map) do
|
||||||
|
if key ~= "name" then label = label .. " " .. key end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
modewidget[s].text = label
|
||||||
|
set_default(s)
|
||||||
|
modewibox[s].visible = true
|
||||||
|
end
|
||||||
|
|
||||||
|
hide_box = function ()
|
||||||
|
local s = modewibox.screen
|
||||||
|
if s ~= -1 then modewibox[s].visible = false end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
150
mpd.lua
Normal file
150
mpd.lua
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
local luampd = require("luampd")
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local type = ""
|
||||||
|
|
||||||
|
-- local functions
|
||||||
|
local show, mpc_play_search, notify
|
||||||
|
|
||||||
|
local conn = nil
|
||||||
|
|
||||||
|
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 = luampd:new({
|
||||||
|
hostname = settings.hostname,
|
||||||
|
port = settings.port,
|
||||||
|
debug = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
M.disconnect = function()
|
||||||
|
if conn ~= nil then conn:close() end
|
||||||
|
conn = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
M.ensure_connection = function()
|
||||||
|
if conn == nil then M.connect() end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ mpd.ctrl submodule
|
||||||
|
|
||||||
|
M.ctrl = {}
|
||||||
|
|
||||||
|
M.ctrl.toggle = function ()
|
||||||
|
M.ensure_connection()
|
||||||
|
local status = conn:status()
|
||||||
|
if status["state"] == "pause" or status["state"] == "stop" then
|
||||||
|
conn:play()
|
||||||
|
else
|
||||||
|
conn:pause()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.ctrl.play = function ()
|
||||||
|
M.ensure_connection()
|
||||||
|
conn:play()
|
||||||
|
-- TODO widget updating
|
||||||
|
end
|
||||||
|
|
||||||
|
M.ctrl.pause = function ()
|
||||||
|
M.ensure_connection()
|
||||||
|
conn:pause()
|
||||||
|
-- TODO widget updating
|
||||||
|
end
|
||||||
|
|
||||||
|
M.ctrl.next = function ()
|
||||||
|
M.ensure_connection()
|
||||||
|
conn:next_()
|
||||||
|
-- TODO widget updating
|
||||||
|
end
|
||||||
|
|
||||||
|
M.ctrl.prev = function ()
|
||||||
|
M.ensure_connection()
|
||||||
|
conn:previous()
|
||||||
|
-- TODO widget updating
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ mpd.prompt submodule
|
||||||
|
|
||||||
|
local clear_before = cfg.mpd_prompt_clear_before == nil and
|
||||||
|
true or
|
||||||
|
cfg.mpd_prompt_clear_before
|
||||||
|
|
||||||
|
M.prompt = {}
|
||||||
|
|
||||||
|
M.prompt.artist = function()
|
||||||
|
type = "artist"
|
||||||
|
show()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.prompt.album = function()
|
||||||
|
type = "album"
|
||||||
|
show()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
M.prompt.title = function()
|
||||||
|
type = "title"
|
||||||
|
show()
|
||||||
|
end
|
||||||
|
M.prompt.title = title
|
||||||
|
|
||||||
|
M.prompt.replace_on_search = function(bool)
|
||||||
|
clear_before = bool
|
||||||
|
end
|
||||||
|
|
||||||
|
M.prompt.toggle_replace_on_search = function()
|
||||||
|
clear_before = not clear_before
|
||||||
|
notify("MPD prompts now " ..(
|
||||||
|
clear_before and "replace" or "add to"
|
||||||
|
).. " 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)
|
||||||
|
M.ensure_connection()
|
||||||
|
if clear_before then conn:clear() end
|
||||||
|
local result, num = conn:isearch(type, s)
|
||||||
|
notify("Found " .. (num) .. " matches");
|
||||||
|
conn:iadd(result)
|
||||||
|
conn:play()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ notify wrapper
|
||||||
|
notify = function(stext)
|
||||||
|
if not (naughty == nil) then
|
||||||
|
naughty.notify({
|
||||||
|
text= stext
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--}}}
|
||||||
|
|
||||||
|
return M
|
||||||
|
|
||||||
|
-- vim: set fenc=utf-8 tw=80 foldmethod=marker :
|
|
@ -1,78 +0,0 @@
|
||||||
local awful = awful
|
|
||||||
local obvious = obvious
|
|
||||||
local naughty = naughty
|
|
||||||
local keygrabber = keygrabber
|
|
||||||
local io = io
|
|
||||||
local pairs = pairs
|
|
||||||
|
|
||||||
local M = {}
|
|
||||||
|
|
||||||
local type = ""
|
|
||||||
local clear_before = true
|
|
||||||
|
|
||||||
local keymap = {}
|
|
||||||
|
|
||||||
local show,
|
|
||||||
mpc_play_search
|
|
||||||
|
|
||||||
M.grabber = function()
|
|
||||||
keygrabber.run(function(mod, key, event)
|
|
||||||
if event == "release" then return true end
|
|
||||||
keygrabber.stop()
|
|
||||||
if keymap[key] then keymap[key]() end
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
M.artist = function()
|
|
||||||
type = "artist"
|
|
||||||
show()
|
|
||||||
end
|
|
||||||
|
|
||||||
M.album = function()
|
|
||||||
type = "album"
|
|
||||||
show()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
M.title = function()
|
|
||||||
type = "title"
|
|
||||||
show()
|
|
||||||
end
|
|
||||||
M.title = title
|
|
||||||
|
|
||||||
M.replace_on_search = function(bool)
|
|
||||||
clear_before = bool
|
|
||||||
end
|
|
||||||
|
|
||||||
M.toggle_replace_on_search = function()
|
|
||||||
clear_before = not clear_before
|
|
||||||
if not (naughty == nil) then
|
|
||||||
naughty.notify({
|
|
||||||
text="MPD prompts now " ..(
|
|
||||||
clear_before and "replace" or "add to"
|
|
||||||
).. " the playlist"
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function show()
|
|
||||||
obvious.popup_run_prompt.set_prompt_string("Play ".. 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 awful.util.spawn("mpc clear") end
|
|
||||||
awful.util.spawn_with_shell("mpc search ".. type .." '" .. s .. "' | mpc add")
|
|
||||||
awful.util.spawn("mpc play");
|
|
||||||
end
|
|
||||||
|
|
||||||
keymap = {
|
|
||||||
a = M.artist,
|
|
||||||
A = M.album,
|
|
||||||
t = M.title,
|
|
||||||
r = M.toggle_replace_on_search
|
|
||||||
}
|
|
||||||
|
|
||||||
return M
|
|
3
rc.lua
3
rc.lua
|
@ -9,11 +9,8 @@ require("teardrop")
|
||||||
require("obvious.popup_run_prompt")
|
require("obvious.popup_run_prompt")
|
||||||
require("vicious")
|
require("vicious")
|
||||||
require("rodentbane.rodentbane")
|
require("rodentbane.rodentbane")
|
||||||
require("aweswt")
|
|
||||||
mpd_prompt = require("mpd_prompt")
|
|
||||||
|
|
||||||
MY_PATH = os.getenv("HOME") .. "/.config/awesome/"
|
MY_PATH = os.getenv("HOME") .. "/.config/awesome/"
|
||||||
WALLPATH = MY_PATH .. "walls/"
|
|
||||||
|
|
||||||
dofile (MY_PATH .. "localconf.lua")
|
dofile (MY_PATH .. "localconf.lua")
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ awful.rules.rules = {
|
||||||
{ rule = { role = "buddy_list" },
|
{ rule = { role = "buddy_list" },
|
||||||
properties = { master = true } },
|
properties = { master = true } },
|
||||||
{ rule = { role = "conversation" },
|
{ rule = { role = "conversation" },
|
||||||
callback = awful.client.setslave},
|
callback = awful.client.setslave },
|
||||||
{ rule = { instance = "Weechat"},
|
{ rule = { instance = "Weechat"},
|
||||||
properties = { tag = tags[rule_screen][3]} ,
|
properties = { tag = tags[rule_screen][3]} ,
|
||||||
callback = awful.client.setslave},
|
callback = awful.client.setslave},
|
||||||
|
|
18
tags.lua
18
tags.lua
|
@ -15,15 +15,15 @@ tags.setup = {
|
||||||
{ name = "F1:☭", layout = layouts[1] },
|
{ name = "F1:☭", layout = layouts[1] },
|
||||||
{ name = "F2:♚", layout = layouts[1] },
|
{ name = "F2:♚", layout = layouts[1] },
|
||||||
{ name = "F3:♛", layout = layouts[1] },
|
{ name = "F3:♛", layout = layouts[1] },
|
||||||
{ name = "F4:♜", layout = layouts[1] },
|
{ name = "F4:♜", layout = layouts[1] }--,
|
||||||
{ name = "F5:♝", layout = layouts[1] },
|
-- { name = "F5:♝", layout = layouts[1] },
|
||||||
{ name = "F6:♞", layout = layouts[1] },
|
-- { name = "F6:♞", layout = layouts[1] },
|
||||||
{ name = "F7:♟", layout = layouts[1] },
|
-- { name = "F7:♟", layout = layouts[1] },
|
||||||
{ name = "F8:⚖", layout = layouts[1] },
|
-- { name = "F8:⚖", layout = layouts[1] },
|
||||||
{ name = "F9:⚛", layout = layouts[1] },
|
-- { name = "F9:⚛", layout = layouts[1] },
|
||||||
{ name = "F10:⚡", layout = layouts[1] },
|
-- { name = "F10:⚡", layout = layouts[1] },
|
||||||
{ name = "F11:⚰", layout = layouts[1] },
|
-- { name = "F11:⚰", layout = layouts[1] },
|
||||||
{ name = "F12:⚙", layout = layouts[1] }
|
-- { name = "F12:⚙", layout = layouts[1] }
|
||||||
}
|
}
|
||||||
|
|
||||||
for s = 1, screen.count() do
|
for s = 1, screen.count() do
|
||||||
|
|
|
@ -170,8 +170,8 @@ for s = 1, screen.count() do
|
||||||
|
|
||||||
|
|
||||||
-- Create the wibox
|
-- Create the wibox
|
||||||
leftwibox[s] = awful.wibox({ position = "left", screen = s })
|
leftwibox[s] = awful.wibox({ position = "left", screen = s, width = 18 })
|
||||||
rightwibox[s] = awful.wibox({ position = "right", screen = s })
|
rightwibox[s] = awful.wibox({ position = "right", screen = s , width = 18})
|
||||||
-- Add widgets to the wibox - order matters
|
-- Add widgets to the wibox - order matters
|
||||||
leftwibox[s].widgets = {
|
leftwibox[s].widgets = {
|
||||||
mytaglist[s],
|
mytaglist[s],
|
||||||
|
|
|
@ -12,7 +12,7 @@ theme.wallpaper_cmd = { "awsetbg -l" }
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
-- {{{ Styles
|
-- {{{ Styles
|
||||||
theme.font = "sans 8"
|
theme.font = "dejavu 7"
|
||||||
|
|
||||||
-- {{{ Colors
|
-- {{{ Colors
|
||||||
theme.fg_normal = "#DCDCDC"
|
theme.fg_normal = "#DCDCDC"
|
||||||
|
|
Loading…
Reference in a new issue