awful.tag: fix and improve tag history
This fixes a long standing tag history breakage. To store history of tag switching we rely on a special signal "tag::history::update" which needs to be emitted by any function which deals with tag selection. History is multi-level with a configurable limit: awful.tag.history.limit = 20 (by default). awful.tag.history.restore function gets a new argument 'idx' which can be either 'previous' (default) which will revert to the previously selected set of tags, or a numerical index in the tag history table. Signed-off-by: koniu <gkusnierz@gmail.com> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
3145e3145e
commit
529502ffbf
|
@ -24,37 +24,11 @@ module("awful.tag")
|
||||||
-- Private data
|
-- Private data
|
||||||
local data = {}
|
local data = {}
|
||||||
data.history = {}
|
data.history = {}
|
||||||
data.history.past = {}
|
|
||||||
data.history.current = {}
|
|
||||||
data.tags = setmetatable({}, { __mode = 'k' })
|
data.tags = setmetatable({}, { __mode = 'k' })
|
||||||
|
|
||||||
-- History functions
|
-- History functions
|
||||||
history = {}
|
history = {}
|
||||||
|
history.limit = 20
|
||||||
-- Compare 2 tables of tags.
|
|
||||||
-- @param a The first table.
|
|
||||||
-- @param b The second table of tags.
|
|
||||||
-- @return True if the tables are identical, false otherwise.
|
|
||||||
local function compare_select(a, b)
|
|
||||||
if not a or not b then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
-- Quick size comparison
|
|
||||||
if #a ~= #b then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
for ka, va in pairs(a) do
|
|
||||||
if b[ka] ~= va.selected then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for kb, vb in pairs(b) do
|
|
||||||
if a[kb].selected ~= vb then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Create a set of tags and attach it to a screen.
|
--- Create a set of tags and attach it to a screen.
|
||||||
-- @param names The tag name, in a table
|
-- @param names The tag name, in a table
|
||||||
|
@ -77,26 +51,55 @@ function new(names, screen, layout)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Update the tag history.
|
--- Update the tag history.
|
||||||
-- @param screen The screen number.
|
-- @param obj Screen object.
|
||||||
function history.update(screen)
|
function history.update(obj)
|
||||||
local curtags = capi.screen[screen]:tags()
|
local s = obj.index
|
||||||
if not compare_select(curtags, data.history.current[screen]) then
|
local curtags = capi.screen[s]:tags()
|
||||||
data.history.past[screen] = data.history.current[screen]
|
-- create history table
|
||||||
data.history.current[screen] = {}
|
if not data.history[s] then
|
||||||
for k, v in ipairs(curtags) do
|
data.history[s] = {}
|
||||||
data.history.current[screen][k] = v.selected
|
-- limit history
|
||||||
|
elseif #data.history[s] >= history.limit then
|
||||||
|
for i = history.limit, #data.history[s] do
|
||||||
|
data.history[s][i] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- store previously selected tags in the history table
|
||||||
|
table.insert(data.history[s], 1, data.history[s].current)
|
||||||
|
data.history[s].previous = data.history[s][1]
|
||||||
|
-- store currently selected tags
|
||||||
|
data.history[s].current = setmetatable(selectedlist(s), { __mode = 'v' })
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Revert tag history.
|
--- Revert tag history.
|
||||||
-- @param screen The screen number.
|
-- @param screen The screen number.
|
||||||
function history.restore(screen)
|
-- @param idx Index in history. Defaults to "previous" which is a special index
|
||||||
|
-- toggling between last two selected sets of tags. Number (eg 1) will go back
|
||||||
|
-- to the given index in history.
|
||||||
|
function history.restore(screen, idx)
|
||||||
local s = screen or capi.mouse.screen
|
local s = screen or capi.mouse.screen
|
||||||
local tags = capi.screen[s]:tags()
|
local i = idx or "previous"
|
||||||
for k, t in pairs(tags) do
|
local sel = selectedlist(s)
|
||||||
t.selected = data.history.past[s][k]
|
-- do nothing if history empty
|
||||||
|
if not data.history[s] or not data.history[s][i] then return end
|
||||||
|
-- if all tags been deleted, try next entry
|
||||||
|
if #data.history[s][i] == 0 then
|
||||||
|
if i == "previous" then i = 0 end
|
||||||
|
history.restore(s, i + 1)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
-- deselect all tags
|
||||||
|
viewnone(s)
|
||||||
|
-- select tags from the history entry
|
||||||
|
for _, t in ipairs(data.history[s][i]) do
|
||||||
|
t.selected = true
|
||||||
|
end
|
||||||
|
-- update currently selected tags table
|
||||||
|
data.history[s].current = data.history[s][i]
|
||||||
|
-- store previously selected tags
|
||||||
|
data.history[s].previous = setmetatable(sel, { __mode = 'v' })
|
||||||
|
-- remove the reverted history entry
|
||||||
|
if i ~= "previous" then table.remove(data.history[s], i) end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Return a table with all visible tags
|
--- Return a table with all visible tags
|
||||||
|
@ -231,6 +234,7 @@ function viewidx(i, screen)
|
||||||
showntags[util.cycle(#showntags, k + i)].selected = true
|
showntags[util.cycle(#showntags, k + i)].selected = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
capi.screen[screen]:emit_signal("tag::history::update")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- View next tag. This is the same as tag.viewidx(1).
|
--- View next tag. This is the same as tag.viewidx(1).
|
||||||
|
@ -250,6 +254,7 @@ end
|
||||||
function viewonly(t)
|
function viewonly(t)
|
||||||
viewnone(t.screen)
|
viewnone(t.screen)
|
||||||
t.selected = true
|
t.selected = true
|
||||||
|
capi.screen[t.screen]:emit_signal("tag::history::update")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- View only a set of tags.
|
--- View only a set of tags.
|
||||||
|
@ -260,6 +265,7 @@ function viewmore(tags, screen)
|
||||||
for i, t in pairs(tags) do
|
for i, t in pairs(tags) do
|
||||||
t.selected = true
|
t.selected = true
|
||||||
end
|
end
|
||||||
|
capi.screen[screen]:emit_signal("tag::history::update")
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get tag data table.
|
--- Get tag data table.
|
||||||
|
@ -339,6 +345,10 @@ capi.client.add_signal("manage", function(c)
|
||||||
c:add_signal("property::screen", withcurrent)
|
c:add_signal("property::screen", withcurrent)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
for s = 1, capi.screen.count() do
|
||||||
|
capi.screen[s]:add_signal("tag::history::update", history.update)
|
||||||
|
end
|
||||||
|
|
||||||
setmetatable(_M, { __call = function (_, ...) return new(...) end })
|
setmetatable(_M, { __call = function (_, ...) return new(...) end })
|
||||||
|
|
||||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue