feat(lib: awful: hotkeys_popup): widget to show awesome and third-party keybindings
Closes https://github.com/awesomeWM/awesome/pull/421.
This commit is contained in:
parent
ecf6b55b55
commit
0516203610
|
@ -10,6 +10,7 @@ local beautiful = require("beautiful")
|
|||
-- Notification library
|
||||
local naughty = require("naughty")
|
||||
local menubar = require("menubar")
|
||||
local hotkeys_popup = require("awful.hotkeys_popup.widget")
|
||||
|
||||
-- {{{ Error handling
|
||||
-- Check if awesome encountered an error during startup and fell back to
|
||||
|
@ -108,6 +109,7 @@ end
|
|||
-- {{{ Menu
|
||||
-- Create a laucher 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 },
|
||||
|
@ -227,6 +229,8 @@ root.buttons(awful.util.table.join(
|
|||
|
||||
-- {{{ 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,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
---------------------------------------------------------------------------
|
||||
--- Popup widget which shows current hotkeys and their descriptions.
|
||||
--
|
||||
-- @author Yauheni Kirylau <yawghen@gmail.com>
|
||||
-- @copyright 2014-2015 Yauheni Kirylau
|
||||
-- @release @AWESOME_VERSION@
|
||||
-- @module awful.hotkeys_popup
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
local hotkeys_popup = {
|
||||
widget = require("awful.hotkeys_popup.widget"),
|
||||
keys = require("awful.hotkeys_popup.keys")
|
||||
}
|
||||
hotkeys_popup.show_help = hotkeys_popup.widget.show_help
|
||||
return hotkeys_popup
|
|
@ -0,0 +1,14 @@
|
|||
---------------------------------------------------------------------------
|
||||
--- Additional hotkeys for awful.hotkeys_widget
|
||||
--
|
||||
-- @author Yauheni Kirylau <yawghen@gmail.com>
|
||||
-- @copyright 2014-2015 Yauheni Kirylau
|
||||
-- @release @AWESOME_VERSION@
|
||||
-- @module awful.hotkeys_popup.keys
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
local keys = {
|
||||
vim = require("awful.hotkeys_popup.keys.vim")
|
||||
}
|
||||
return keys
|
|
@ -0,0 +1,132 @@
|
|||
---------------------------------------------------------------------------
|
||||
--- VIM hotkeys for awful.hotkeys_widget
|
||||
--
|
||||
-- @author Yauheni Kirylau <yawghen@gmail.com>
|
||||
-- @copyright 2014-2015 Yauheni Kirylau
|
||||
-- @release @AWESOME_VERSION@
|
||||
-- @module awful.hotkeys_popup.keys.vim
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local hotkeys_popup = require("awful.hotkeys_popup.widget")
|
||||
|
||||
local vim_rule = {name="vim"}
|
||||
for group_name, group_data in pairs({
|
||||
vim_motion= { color="#009F00", rule=vim_rule },
|
||||
vim_command= { color="#aFaF00", rule=vim_rule },
|
||||
vim_command_insert= { color="#cF4F40", rule=vim_rule },
|
||||
vim_operator= { color="#aF6F00", rule=vim_rule },
|
||||
}) do
|
||||
hotkeys_popup.group_rules[group_name] = group_data
|
||||
end
|
||||
|
||||
|
||||
local vim_keys = {
|
||||
|
||||
vim_motion={{
|
||||
modifiers = {},
|
||||
keys = {
|
||||
['`']="goto mark",
|
||||
['0']='"hard" BOL',
|
||||
['-']="prev line",
|
||||
w="next word",
|
||||
e="end word",
|
||||
t=". 'till",
|
||||
['[']=". misc",
|
||||
[']']=". misc",
|
||||
f=". find char",
|
||||
[';']="repeat t/T/f/F",
|
||||
["'"]=". goto mk. BOL",
|
||||
b="prev word",
|
||||
n="next word",
|
||||
[',']="reverse t/T/f/F",
|
||||
['/']=". find",
|
||||
['~']="toggle case",
|
||||
["#"]='prev indent',
|
||||
["$"]='EOL',
|
||||
["%"]='goto match bracket',
|
||||
["^"]='"soft" BOL',
|
||||
["*"]='next indent',
|
||||
["("]='begin sentence',
|
||||
[")"]='end sentence',
|
||||
["_"]='"soft" BOL down',
|
||||
["+"]='next line',
|
||||
W='next WORD',
|
||||
E='end WORD',
|
||||
T=". back 'till",
|
||||
['{']="begin parag.",
|
||||
['}']="end parag.",
|
||||
F='. "back" find char',
|
||||
G='EOF/goto line',
|
||||
H='screen top',
|
||||
L='screen bottom',
|
||||
B='prev WORD',
|
||||
N='prev (find)',
|
||||
M='screen middle',
|
||||
['?']='. find(rev.)',
|
||||
}
|
||||
}},
|
||||
|
||||
vim_operator={{
|
||||
modifiers = {},
|
||||
keys = {
|
||||
['=']="auto format",
|
||||
y="yank",
|
||||
d="delete",
|
||||
c="change",
|
||||
["!"]='external filter',
|
||||
['<']='unindent',
|
||||
['>']='indent',
|
||||
}
|
||||
}},
|
||||
|
||||
vim_command={{
|
||||
modifiers = {},
|
||||
keys = {
|
||||
q=". record macro",
|
||||
r=". replace char",
|
||||
u="undo",
|
||||
p="paste after",
|
||||
g="gg: top of file, gf: open file here",
|
||||
z="zt: cursor to top, zb: bottom, zz: center",
|
||||
x="delete char",
|
||||
v="visual mode",
|
||||
m=". set mark",
|
||||
['.']="repeat command",
|
||||
["@"]='. play macro',
|
||||
["&"]='repeat :s',
|
||||
Q='ex mode',
|
||||
Y='yank line',
|
||||
U='undo line',
|
||||
P='paste before',
|
||||
D='delete to EOL',
|
||||
J='join lines',
|
||||
K='help',
|
||||
[':']='ex cmd line',
|
||||
['"']='. register spec',
|
||||
["|"]='BOL/goto col',
|
||||
Z='quit and ZZ:save or ZQ:not',
|
||||
X='back-delete',
|
||||
V='visual lines',
|
||||
}
|
||||
}},
|
||||
|
||||
vim_command_insert={{
|
||||
modifiers = {},
|
||||
keys = {
|
||||
i="insert mode",
|
||||
o="open below",
|
||||
a="append",
|
||||
s="subst char",
|
||||
R='replace mode',
|
||||
I='insert at BOL',
|
||||
O='open above',
|
||||
A='append at EOL',
|
||||
S='subst line',
|
||||
C='change to EOL',
|
||||
}
|
||||
}},
|
||||
}
|
||||
|
||||
hotkeys_popup.add_hotkeys(vim_keys)
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -0,0 +1,409 @@
|
|||
---------------------------------------------------------------------------
|
||||
--- Popup widget which shows current hotkeys and their descriptions.
|
||||
--
|
||||
-- @author Yauheni Kirylau <yawghen@gmail.com>
|
||||
-- @copyright 2014-2015 Yauheni Kirylau
|
||||
-- @release @AWESOME_VERSION@
|
||||
-- @module awful.hotkeys_popup.widget
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
local capi = {
|
||||
screen = screen,
|
||||
client = client,
|
||||
keygrabber = keygrabber,
|
||||
}
|
||||
local awful = require("awful")
|
||||
local wibox = require("wibox")
|
||||
local beautiful = require("beautiful")
|
||||
local dpi = beautiful.xresources.apply_dpi
|
||||
local compute_textbox_width = require("menubar").utils.compute_textbox_width
|
||||
|
||||
|
||||
-- Stripped copy of this module https://github.com/copycat-killer/lain/blob/master/util/markup.lua:
|
||||
local markup = {}
|
||||
-- Set the font.
|
||||
function markup.font(font, text)
|
||||
return '<span font="' .. tostring(font) .. '">' .. tostring(text) ..'</span>'
|
||||
end
|
||||
-- Set the foreground.
|
||||
function markup.fg(color, text)
|
||||
return '<span foreground="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
|
||||
end
|
||||
-- Set the background.
|
||||
function markup.bg(color, text)
|
||||
return '<span background="' .. tostring(color) .. '">' .. tostring(text) .. '</span>'
|
||||
end
|
||||
|
||||
|
||||
local widget = {
|
||||
hide_without_description = true,
|
||||
title_font = "Monospace Bold 9",
|
||||
description_font = "Monospace 8",
|
||||
width = dpi(1200),
|
||||
height = dpi(800),
|
||||
border_width = beautiful.border_width or dpi(2),
|
||||
modifiers_color = beautiful.bg_minimize or "#555555",
|
||||
group_margin = dpi(6),
|
||||
group_rules = {},
|
||||
additional_hotkeys = {},
|
||||
labels = {
|
||||
Mod4="Super",
|
||||
Mod1="Alt",
|
||||
Escape="Esc",
|
||||
Insert="Ins",
|
||||
Delete="Del",
|
||||
Backspace="BackSpc",
|
||||
Return="Enter",
|
||||
Next="PgDn",
|
||||
Prior="PgUp",
|
||||
['#108']="Alt Gr",
|
||||
Left='←',
|
||||
Up='↑',
|
||||
Right='→',
|
||||
Down='↓',
|
||||
['#67']="F1",
|
||||
['#68']="F2",
|
||||
['#69']="F3",
|
||||
['#70']="F4",
|
||||
['#71']="F5",
|
||||
['#72']="F6",
|
||||
['#73']="F7",
|
||||
['#74']="F8",
|
||||
['#75']="F9",
|
||||
['#76']="F10",
|
||||
['#95']="F11",
|
||||
['#96']="F12",
|
||||
['#10']="1",
|
||||
['#11']="2",
|
||||
['#12']="3",
|
||||
['#13']="4",
|
||||
['#14']="5",
|
||||
['#15']="6",
|
||||
['#16']="7",
|
||||
['#17']="8",
|
||||
['#18']="9",
|
||||
['#19']="0",
|
||||
['#20']="-",
|
||||
['#21']="=",
|
||||
Control="Ctrl"
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local cached_wiboxes = {{}}
|
||||
local cached_awful_keys = nil
|
||||
local colors_counter = {}
|
||||
local colors = beautiful.xresources.get_current_theme()
|
||||
local group_list = {}
|
||||
|
||||
|
||||
local function get_next_color(id)
|
||||
id = id or "default"
|
||||
if colors_counter[id] then
|
||||
colors_counter[id] = math.fmod(colors_counter[id] + 1, 15) + 1
|
||||
else
|
||||
colors_counter[id] = 1
|
||||
end
|
||||
return colors["color"..tostring(colors_counter[id], 15)]
|
||||
end
|
||||
|
||||
|
||||
local function join_plus_sort(modifiers)
|
||||
if #modifiers<1 then return "none" end
|
||||
table.sort(modifiers)
|
||||
return table.concat(modifiers, '+')
|
||||
end
|
||||
|
||||
|
||||
local function add_hotkey(key, data, target)
|
||||
if widget.hide_without_description and not data.description then return end
|
||||
|
||||
local readable_mods = {}
|
||||
for _, mod in ipairs(data.mod) do
|
||||
table.insert(readable_mods, widget.labels[mod] or mod)
|
||||
end
|
||||
local joined_mods = join_plus_sort(readable_mods)
|
||||
if joined_mods == "none" then
|
||||
joined_mods = ""
|
||||
else
|
||||
joined_mods = markup.fg(widget.modifiers_color, joined_mods.."+")
|
||||
end
|
||||
|
||||
local group = data.group or "none"
|
||||
group_list[group] = true
|
||||
if not target[group] then target[group] = {} end
|
||||
table.insert(
|
||||
target[group],
|
||||
{hotkey= joined_mods .. (widget.labels[key] or key),
|
||||
description=data.description}
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
local function sort_hotkeys(target)
|
||||
-- @TODO: add sort by 12345qwertyasdf etc
|
||||
for group, _ in pairs(group_list) do
|
||||
if target[group] then
|
||||
table.sort(
|
||||
target[group],
|
||||
function(a,b) return a.hotkey<b.hotkey end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function import_awful_keys()
|
||||
if cached_awful_keys then
|
||||
return
|
||||
end
|
||||
cached_awful_keys = {}
|
||||
for _, data in pairs(awful.key.hotkeys) do
|
||||
add_hotkey(data.key, data, cached_awful_keys)
|
||||
end
|
||||
sort_hotkeys(cached_awful_keys)
|
||||
end
|
||||
|
||||
|
||||
local function group_label(group, color)
|
||||
local textbox = wibox.widget.textbox(
|
||||
markup.font(widget.title_font,
|
||||
markup.bg(
|
||||
color or (widget.group_rules[group] and
|
||||
widget.group_rules[group].color or get_next_color("group_title")
|
||||
),
|
||||
markup.fg(beautiful.bg_normal or "#000000", " "..group.." ")
|
||||
)
|
||||
)
|
||||
)
|
||||
local margin = wibox.layout.margin()
|
||||
margin:set_widget(textbox)
|
||||
margin:set_top(widget.group_margin)
|
||||
return margin
|
||||
end
|
||||
|
||||
local function create_wibox(s, available_groups)
|
||||
local wa = capi.screen[s].workarea
|
||||
local height = (widget.height < wa.height) and widget.height or
|
||||
(wa.height - widget.border_width * 2)
|
||||
local width = (widget.width < wa.width) and widget.width or
|
||||
(wa.width - widget.border_width * 2)
|
||||
|
||||
-- arrange hotkey groups into columns
|
||||
local line_height = beautiful.get_font_height(widget.title_font)
|
||||
local group_label_height = line_height + widget.group_margin
|
||||
-- -1 for possible pagination:
|
||||
local max_height_px = height - group_label_height
|
||||
local column_layouts = {}
|
||||
for _, group in ipairs(available_groups) do
|
||||
local keys = cached_awful_keys[group] or widget.additional_hotkeys[group]
|
||||
local joined_descriptions = ""
|
||||
for i, key in ipairs(keys) do
|
||||
joined_descriptions = joined_descriptions .. key.description .. (i~=#keys and "\n" or "")
|
||||
end
|
||||
-- +1 for group label:
|
||||
local items_height = awful.util.linecount(joined_descriptions) * line_height + group_label_height
|
||||
local current_column
|
||||
local available_height_px = max_height_px
|
||||
local add_new_column = true
|
||||
for i, column in ipairs(column_layouts) do
|
||||
if ((column.height_px + items_height) < max_height_px) or
|
||||
(i == #column_layouts and column.height_px < max_height_px / 2)
|
||||
then
|
||||
current_column = column
|
||||
add_new_column = false
|
||||
available_height_px = max_height_px - current_column.height_px
|
||||
break
|
||||
end
|
||||
end
|
||||
local overlap_leftovers
|
||||
if items_height > available_height_px then
|
||||
local new_keys = {}
|
||||
overlap_leftovers = {}
|
||||
-- +1 for group title and +1 for possible hyphen (v):
|
||||
local available_height_items = (available_height_px - group_label_height*2) / line_height
|
||||
for i=1,#keys do
|
||||
table.insert(((i<available_height_items) and new_keys or overlap_leftovers), keys[i])
|
||||
end
|
||||
keys = new_keys
|
||||
table.insert(keys, {hotkey=markup.fg(widget.modifiers_color, "▽"), description=""})
|
||||
end
|
||||
if not current_column then
|
||||
current_column = {layout=wibox.layout.fixed.vertical()}
|
||||
end
|
||||
current_column.layout:add(group_label(group))
|
||||
|
||||
local function insert_keys(_keys, _add_new_column)
|
||||
local max_label_width = 0
|
||||
local max_label_content = ""
|
||||
local joined_labels = ""
|
||||
for i, key in ipairs(_keys) do
|
||||
local length = string.len(key.hotkey) + string.len(key.description)
|
||||
local rendered_hotkey = markup.font(widget.title_font, key.hotkey.." ") ..
|
||||
(markup.font(widget.description_font, key.description) or "")
|
||||
if length > max_label_width then
|
||||
max_label_width = length
|
||||
max_label_content = rendered_hotkey
|
||||
end
|
||||
joined_labels = joined_labels .. rendered_hotkey .. (i~=#_keys and "\n" or "")
|
||||
end
|
||||
current_column.layout:add(wibox.widget.textbox(joined_labels))
|
||||
local max_width = compute_textbox_width(wibox.widget.textbox(max_label_content), s) +
|
||||
widget.group_margin
|
||||
if not current_column.max_width or max_width > current_column.max_width then
|
||||
current_column.max_width = max_width
|
||||
end
|
||||
-- +1 for group label:
|
||||
current_column.height_px = (current_column.height_px or 0) +
|
||||
awful.util.linecount(joined_labels)*line_height + group_label_height
|
||||
if _add_new_column then
|
||||
table.insert(column_layouts, current_column)
|
||||
end
|
||||
end
|
||||
|
||||
insert_keys(keys, add_new_column)
|
||||
if overlap_leftovers then
|
||||
current_column = {layout=wibox.layout.fixed.vertical()}
|
||||
insert_keys(overlap_leftovers, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- arrange columns into pages
|
||||
local available_width_px = width
|
||||
local pages = {}
|
||||
local columns = wibox.layout.fixed.horizontal()
|
||||
for _, item in ipairs(column_layouts) do
|
||||
if item.max_width > available_width_px then
|
||||
columns.widgets[#columns.widgets]['widget']:add(
|
||||
group_label("PgDn - Next Page", beautiful.fg_normal)
|
||||
)
|
||||
table.insert(pages, columns)
|
||||
columns = wibox.layout.fixed.horizontal()
|
||||
available_width_px = width - item.max_width
|
||||
local old_widgets = item.layout.widgets
|
||||
item.layout.widgets = {group_label("PgUp - Prev Page", beautiful.fg_normal)}
|
||||
awful.util.table.merge(item.layout.widgets, old_widgets)
|
||||
else
|
||||
available_width_px = available_width_px - item.max_width
|
||||
end
|
||||
local column_margin = wibox.layout.margin()
|
||||
column_margin:set_widget(item.layout)
|
||||
column_margin:set_left(widget.group_margin)
|
||||
columns:add(column_margin)
|
||||
end
|
||||
table.insert(pages, columns)
|
||||
|
||||
local mywibox = wibox({
|
||||
ontop = true,
|
||||
opacity = beautiful.notification_opacity or 1,
|
||||
border_width = widget.border_width,
|
||||
border_color = beautiful.fg_normal,
|
||||
})
|
||||
mywibox:geometry({
|
||||
x = wa.x + math.floor((wa.width - width - widget.border_width*2) / 2),
|
||||
y = wa.y + math.floor((wa.height - height - widget.border_width*2) / 2),
|
||||
width = width,
|
||||
height = height,
|
||||
})
|
||||
mywibox:set_widget(pages[1])
|
||||
mywibox:buttons(awful.util.table.join(
|
||||
awful.button({ }, 1, function () mywibox.visible=false end),
|
||||
awful.button({ }, 3, function () mywibox.visible=false end)
|
||||
))
|
||||
|
||||
local widget_obj = {}
|
||||
widget_obj.current_page = 1
|
||||
widget_obj.wibox = mywibox
|
||||
function widget_obj:page_next()
|
||||
if self.current_page == #pages then return end
|
||||
self.current_page = self.current_page + 1
|
||||
self.wibox:set_widget(pages[self.current_page])
|
||||
end
|
||||
function widget_obj:page_prev()
|
||||
if self.current_page == 1 then return end
|
||||
self.current_page = self.current_page - 1
|
||||
self.wibox:set_widget(pages[self.current_page])
|
||||
end
|
||||
function widget_obj:show()
|
||||
self.wibox.visible = true
|
||||
end
|
||||
function widget_obj:hide()
|
||||
self.wibox.visible = false
|
||||
end
|
||||
|
||||
return widget_obj
|
||||
end
|
||||
|
||||
|
||||
--- Show popup with hotkeys help.
|
||||
-- @tparam[opt] client c Client.
|
||||
-- @tparam[opt] screen s Screen.
|
||||
function widget.show_help(c, s)
|
||||
import_awful_keys()
|
||||
c = c or capi.client.focus
|
||||
s = s or (c and c.screen or awful.screen.focused())
|
||||
|
||||
local available_groups = {}
|
||||
for group, _ in pairs(group_list) do
|
||||
local need_match
|
||||
for group_name, data in pairs(widget.group_rules) do
|
||||
if group_name==group and data.rule then
|
||||
if not c or not awful.rules.match(c, data.rule) then
|
||||
need_match = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not need_match then table.insert(available_groups, group) end
|
||||
end
|
||||
|
||||
local joined_groups = join_plus_sort(available_groups)
|
||||
if not cached_wiboxes[s][joined_groups] then
|
||||
cached_wiboxes[s][joined_groups] = create_wibox(s, available_groups)
|
||||
end
|
||||
local help_wibox = cached_wiboxes[s][joined_groups]
|
||||
help_wibox:show()
|
||||
|
||||
return capi.keygrabber.run(function(_, key, event)
|
||||
if event == "release" then return end
|
||||
if key then
|
||||
if key == "Next" then
|
||||
help_wibox:page_next()
|
||||
elseif key == "Prior" then
|
||||
help_wibox:page_prev()
|
||||
else
|
||||
capi.keygrabber.stop()
|
||||
help_wibox:hide()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
--- Add hotkey descriptions for third-party applications.
|
||||
-- @tparam table hotkeys Table with bindings,
|
||||
-- see `awful.hotkeys_popup.key.vim` as an example.
|
||||
-- @tparam[opt] bool nosort Do not sort hotkeys alphabetically.
|
||||
function widget.add_hotkeys(hotkeys, nosort)
|
||||
for group, bindings in pairs(hotkeys) do
|
||||
for _, binding in ipairs(bindings) do
|
||||
local modifiers = binding.modifiers
|
||||
local keys = binding.keys
|
||||
for key, description in pairs(keys) do
|
||||
add_hotkey(key, {
|
||||
mod=modifiers,
|
||||
description=description,
|
||||
group=group},
|
||||
widget.additional_hotkeys
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
if not nosort then
|
||||
sort_hotkeys(widget.additional_hotkeys)
|
||||
end
|
||||
end
|
||||
|
||||
return widget
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
|
@ -47,12 +47,6 @@ local table_update = function (t, set)
|
|||
return t
|
||||
end
|
||||
|
||||
local table_merge = function (t, set)
|
||||
for _, v in ipairs(set) do
|
||||
table.insert(t, v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Key bindings for menu navigation.
|
||||
-- Keys are: up, down, exec, enter, back, close. Value are table with a list of valid
|
||||
|
@ -484,15 +478,15 @@ function menu.clients(args, item_args)
|
|||
c.icon }
|
||||
if item_args then
|
||||
if type(item_args) == "function" then
|
||||
table_merge(cls_t[#cls_t], item_args(c))
|
||||
util.table.merge(cls_t[#cls_t], item_args(c))
|
||||
else
|
||||
table_merge(cls_t[#cls_t], item_args)
|
||||
util.table.merge(cls_t[#cls_t], item_args)
|
||||
end
|
||||
end
|
||||
end
|
||||
args = args or {}
|
||||
args.items = args.items or {}
|
||||
table_merge(args.items, cls_t)
|
||||
util.table.merge(args.items, cls_t)
|
||||
|
||||
local m = menu.new(args)
|
||||
m:show(args)
|
||||
|
|
|
@ -385,9 +385,9 @@ end
|
|||
-- @param indent Number of spaces added before each wrapped line. Default: 0.
|
||||
-- @return The string with lines wrapped to width.
|
||||
function util.linewrap(text, width, indent)
|
||||
local text = text or ""
|
||||
local width = width or 72
|
||||
local indent = indent or 0
|
||||
text = text or ""
|
||||
width = width or 72
|
||||
indent = indent or 0
|
||||
|
||||
local pos = 1
|
||||
return text:gsub("(%s+)()(%S+)()",
|
||||
|
@ -399,6 +399,13 @@ function util.linewrap(text, width, indent)
|
|||
end)
|
||||
end
|
||||
|
||||
--- Count number of lines in a string
|
||||
-- @tparam string text Input string.
|
||||
-- @treturn int Number of lines.
|
||||
function util.linecount(text)
|
||||
return select(2, text:gsub('\n', '\n')) + 1
|
||||
end
|
||||
|
||||
--- Get a sorted table with all integer keys from a table
|
||||
-- @param t the table for which the keys to get
|
||||
-- @return A table with keys
|
||||
|
@ -489,6 +496,17 @@ function util.table.iterate(t, filter, start)
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
--- Merge items from the one table to another one
|
||||
-- @tparam table t the container table
|
||||
-- @tparam table set the mixin table
|
||||
function util.table.merge(t, set)
|
||||
for _, v in ipairs(set) do
|
||||
table.insert(t, v)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Escape all special pattern-matching characters so that lua interprets them
|
||||
-- literally instead of as a character class.
|
||||
-- Source: http://stackoverflow.com/a/20778724/15690
|
||||
|
|
|
@ -254,12 +254,20 @@ function utils.parse_dir(dir)
|
|||
return programs
|
||||
end
|
||||
|
||||
--- Compute textbox width.
|
||||
-- @tparam wibox.widget.textbox textbox Textbox instance.
|
||||
-- @treturn int Text width.
|
||||
function utils.compute_textbox_width(textbox, s)
|
||||
s = s or mouse.screen
|
||||
local w, h = textbox:get_preferred_size(s)
|
||||
return w
|
||||
end
|
||||
|
||||
--- Compute text width.
|
||||
-- @tparam str text Text.
|
||||
-- @treturn int Text width.
|
||||
function utils.compute_text_width(text)
|
||||
local _, logical = wibox.widget.textbox(awful_util.escape(text))._layout:get_pixel_extents()
|
||||
return logical.width
|
||||
function utils.compute_text_width(text, s)
|
||||
return utils.compute_textbox_width(wibox.widget.textbox(awful_util.escape(text)), s)
|
||||
end
|
||||
|
||||
return utils
|
||||
|
|
Loading…
Reference in New Issue