diff --git a/lib/keydoc.lua b/lib/keydoc.lua
new file mode 100644
index 0000000..494c082
--- /dev/null
+++ b/lib/keydoc.lua
@@ -0,0 +1,123 @@
+-- Document key bindings
+
+local awful = require("awful")
+local table = table
+local ipairs = ipairs
+local pairs = pairs
+local math = math
+local string = string
+local type = type
+local modkey = modkey
+local beautiful = require("beautiful")
+local naughty = require("naughty")
+local capi = {
+ root = root,
+ client = client
+}
+
+module("vbe/keydoc")
+
+local doc = { }
+local currentgroup = "Misc"
+local orig = awful.key.new
+
+-- Replacement for awful.key.new
+local function new(mod, key, press, release, docstring)
+ -- Usually, there is no use of release, let's just use it for doc
+ -- if it's a string.
+ if press and release and not docstring and type(release) == "string" then
+ docstring = release
+ release = nil
+ end
+ local k = orig(mod, key, press, release)
+ -- Remember documentation for this key (we take the first one)
+ if k and #k > 0 and docstring then
+ doc[k[1]] = { help = docstring,
+ group = currentgroup }
+ end
+
+ return k
+end
+awful.key.new = new -- monkey patch
+
+-- Turn a key to a string
+local function key2str(key)
+ local sym = key.keysym or key.key
+ if sym == "#14" then sym = "#" end
+ if not key.modifiers or #key.modifiers == 0 then return sym end
+ local result = ""
+ local translate = {
+ [modkey] = "⊞",
+ Shift = "⇧",
+ Control = "Ctrl",
+ }
+ for _, mod in pairs(key.modifiers) do
+ if translate[mod] then
+ mod = translate[mod]
+ end
+ result = result .. mod .. " + "
+ end
+ return result .. sym
+end
+
+-- Unicode "aware" length function (well, UTF8 aware)
+-- See: http://lua-users.org/wiki/LuaUnicode
+local function unilen(str)
+ local _, count = string.gsub(str, "[^\128-\193]", "")
+ return count
+end
+
+-- Start a new group
+function group(name)
+ currentgroup = name
+ return {}
+end
+
+local function markup(keys)
+ local result = ""
+
+ -- Compute longest key combination
+ local longest = 0
+ for _, key in ipairs(keys) do
+ if doc[key] then
+ longest = math.max(longest, unilen(key2str(key)))
+ end
+ end
+
+ local curgroup = nil
+ for _, key in ipairs(keys) do
+ if doc[key] then
+ local help, group = doc[key].help, doc[key].group
+ if group ~= curgroup then
+ if #result > 0 then result = result .. "\n" end
+ result = result ..
+ '' ..
+ group .. "\n"
+ curgroup = group
+ end
+ local skey = key2str(key)
+ result = result ..
+ ' ' ..
+ string.format("%" .. (longest - unilen(skey)) .. "s ", "") .. skey ..
+ ' ' ..
+ help .. '\n'
+ end
+ end
+
+ return result
+end
+
+-- Display help in a naughty notification
+local nid = nil
+function display()
+ local result = markup(capi.root.keys())
+ if capi.client.focus then
+ result = result .. "\n" .. markup(capi.client.focus:keys())
+ end
+ if result then
+ nid = naughty.notify({ text = result,
+ replaces_id = nid,
+ hover_timeout = 0.1,
+ timeout = 30 }).id
+ end
+end
diff --git a/rc/bindings.lua b/rc/bindings.lua
index dd5a109..7e8c9fb 100644
--- a/rc/bindings.lua
+++ b/rc/bindings.lua
@@ -2,6 +2,7 @@ config.keys = {}
config.mouse = {}
local volume = loadrc("volume", "vbe/volume")
local brightness = loadrc("brightness", "vbe/brightness")
+local keydoc = loadrc("keydoc", "vbe/keydoc")
local function client_info()
local v = ""
@@ -35,72 +36,94 @@ local function client_info()
end
config.keys.global = awful.util.table.join(
- -- Tag navigation
- awful.key({ modkey, }, "Left", awful.tag.viewprev ),
- awful.key({ modkey, }, "Right", awful.tag.viewnext ),
- awful.key({ modkey, }, "Escape", awful.tag.history.restore),
-
- -- Focus
+ keydoc.group("Focus"),
awful.key({ modkey, }, "j",
function ()
awful.client.focus.byidx( 1)
if client.focus then client.focus:raise() end
- end),
+ end,
+ "Focus next window"),
awful.key({ modkey, }, "k",
function ()
awful.client.focus.byidx(-1)
if client.focus then client.focus:raise() end
- end),
- awful.key({ modkey, }, "u", awful.client.urgent.jumpto),
-
- -- Layout manipulation
- 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(config.layouts, 1) end),
- awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(config.layouts, -1) end),
- awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end),
- awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end),
- awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
- awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
+ end,
+ "Focus previous window"),
awful.key({ modkey, }, "Tab",
function ()
awful.client.focus.history.previous()
if client.focus then
client.focus:raise()
end
- end),
+ end,
+ "Focus previously focused window"),
+ awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
+ "Jump to urgent-flagged window"),
+ awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
+ "Jump to next screen"),
+ awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
+
+ keydoc.group("Layout manipulation"),
+ awful.key({ modkey, }, "l", function () awful.tag.incmwfact( 0.05) end,
+ "Increase master-width factor"),
+ awful.key({ modkey, }, "h", function () awful.tag.incmwfact(-0.05) end,
+ "Decrease master-width factor"),
+ awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster( 1) end,
+ "Increase number of masters"),
+ awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster(-1) end,
+ "Decrease number of masters"),
+ awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol( 1) end,
+ "Increase number of columns"),
+ awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol(-1) end,
+ "Decrease number of columns"),
+ awful.key({ modkey, }, "space", function () awful.layout.inc(config.layouts, 1) end,
+ "Next layout"),
+ awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(config.layouts, -1) end,
+ "Previous layout"),
+ awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
+ "Swap with next window"),
+ awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
+ "Swap with previous window"),
-- Spawn a terminal
- awful.key({ modkey, }, "Return", function () awful.util.spawn(config.terminal) end),
+ keydoc.group("Misc"),
+ awful.key({ modkey, }, "Return", function () awful.util.spawn(config.terminal) end,
+ "Spawn a terminal"),
-- Restart awesome
- awful.key({ modkey, "Control" }, "r", awesome.restart),
+ awful.key({ modkey, "Control" }, "r", awesome.restart, "Restart awesome"),
-- Multimedia keys
awful.key({ }, "XF86MonBrightnessUp", brightness.increase),
awful.key({ }, "XF86MonBrightnessDown", brightness.decrease),
awful.key({ }, "XF86AudioRaiseVolume", volume.increase),
awful.key({ }, "XF86AudioLowerVolume", volume.decrease),
- awful.key({ }, "XF86AudioMute", volume.toggle)
+ awful.key({ }, "XF86AudioMute", volume.toggle),
+
+ -- Help
+ awful.key({ modkey, }, "F1", keydoc.display)
)
config.keys.client = awful.util.table.join(
- awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end),
- awful.key({ modkey, }, "x", function (c) c:kill() end),
- awful.key({ modkey, }, "o", awful.client.movetoscreen ),
- awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ),
- awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
- awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end),
- awful.key({ modkey, }, "i", client_info),
+ keydoc.group("Window-specific bindings"),
+ awful.key({ modkey, }, "f", function (c) c.fullscreen = not c.fullscreen end,
+ "Fullscreen"),
+ awful.key({ modkey, }, "x", function (c) c:kill() end,
+ "Close"),
+ awful.key({ modkey, }, "o", awful.client.movetoscreen, "Move to the other screen"),
+ awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle, "Toggle floating"),
+ awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
+ "Switch with master window"),
+ awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
+ "Stay on top"),
+ awful.key({ modkey, }, "i", client_info,
+ "Get client-related information"),
awful.key({ modkey, }, "m",
function (c)
c.maximized_horizontal = not c.maximized_horizontal
c.maximized_vertical = not c.maximized_vertical
- end)
+ end,
+ "Maximize")
)
config.mouse.client = awful.util.table.join(
diff --git a/rc/quake.lua b/rc/quake.lua
index b3036e8..69c7a5d 100644
--- a/rc/quake.lua
+++ b/rc/quake.lua
@@ -64,4 +64,4 @@ end
config.keys.global = awful.util.table.join(
config.keys.global,
- awful.key({ modkey }, "`", toggle))
+ awful.key({ modkey }, "`", toggle, "Toggle Quake console"))
diff --git a/rc/tags.lua b/rc/tags.lua
index 400e316..904ed38 100644
--- a/rc/tags.lua
+++ b/rc/tags.lua
@@ -1,6 +1,7 @@
-- Tags
sharetags = loadrc("sharetags", "vbe/sharetags")
+keydoc = loadrc("keydoc", "vbe/keydoc")
local otags = config.tags
config.tags = {}
@@ -38,6 +39,7 @@ for i = 1, #tags do
if i <= keynumber then
config.keys.global = awful.util.table.join(
config.keys.global,
+ keydoc.group("Tag management"),
awful.key({ modkey }, "#" .. i + 9,
function ()
local t = tags[i]
@@ -53,7 +55,7 @@ for i = 1, #tags do
sharetags.tag_move(t, mouse.screen)
end
awful.tag.viewonly(tags[i])
- end),
+ end, i == 5 and "Display only this tag" or nil),
awful.key({ modkey, "Control" }, "#" .. i + 9,
function ()
local t = tags[i]
@@ -67,18 +69,19 @@ for i = 1, #tags do
awful.tag.viewtoggle(t)
end
end
- end),
+ end, i == 5 and "Toggle display of this tag" or nil),
awful.key({ modkey, "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[i] then
awful.client.movetotag(tags[i])
end
- end),
+ end, i == 5 and "Move window to this tag" or nil),
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
function ()
if client.focus and tags[i] then
awful.client.toggletag(tags[i])
end
- end))
+ end, i == 5 and "Toggle this tag on this window" or nil),
+ keydoc.group("Misc"))
end
end
diff --git a/rc/theme.lua b/rc/theme.lua
index adf9282..f0dcce9 100644
--- a/rc/theme.lua
+++ b/rc/theme.lua
@@ -12,7 +12,7 @@ if theme then
theme.border_marked = theme.border_marked .. "66"
theme.bg_normal = theme.bg_normal .. "99"
- theme.bg_focus = theme.bg_focus .. "99"
+ theme.bg_focus = theme.bg_focus .. "BB"
theme.bg_urgent = theme.bg_urgent .. "99"
theme.bg_minimize = theme.bg_minimize .. "99"
@@ -20,7 +20,7 @@ if theme then
theme.bg_widget = "#00000099"
theme.fg_widget_label = "#737d8c"
theme.fg_widget_value = na(theme.fg_normal)
- theme.fg_widget_value_important = na(theme.border_marked)
+ theme.fg_widget_value_important = "#E80F28"
theme.fg_widget_sep = na(theme.fg_normal)
theme.fg_widget_border = theme.fg_widget_label
theme.fg_widget_clock = na(theme.border_focus)
diff --git a/rc/widgets.lua b/rc/widgets.lua
index 09f3b4c..0e15f7c 100644
--- a/rc/widgets.lua
+++ b/rc/widgets.lua
@@ -234,4 +234,5 @@ end
config.keys.global = awful.util.table.join(
config.keys.global,
- awful.key({ modkey }, "r", function () promptbox[mouse.screen]:run() end))
+ awful.key({ modkey }, "r", function () promptbox[mouse.screen]:run() end,
+ "Prompt for a command"))