WMII-like tag management/ru

Введение
Примечание: Вы можете выполнить все нижеописанное намного проще, если будете использовать библиотеку Shifty для Awesome.

WMII реализует более динамичную работу с тегами, чем в  awesome. При запуске сессии создается только один тег (с именем '1'). Если мы переключаемся на тег, который еще не существует, он создается. После закрытия всех приложений на каком либо теге, он уничтожается.

Эту возможность, которое я, как пришедший с WMII не обнаружил. Ее было не сложно реализовать испльзуя код Lua, очень пригодилась помощь Garoth и psychon в IRC-канале.

Примечание: все части и куски конфигурационного файла разработанны для awesome 3.3. Для других версий могут потребовать корректировки.

Во первых, нам потребуются несколько вспомогательных функций, которые мы будем использовать в дальнейшем:

function dictlen(tbl) local result = 0 for _, __ in pairs(tbl) do           result = result + 1 end return result end

function get_keys(tbl) local result = {} for key, _ in pairs(tbl) do           if key then table.insert(result, key) end end return result end

function make_completer(choices) return function(cmd, cur_pos, ncomp) local matches = {} -- завершаем выполнение при определнных обстоятельствах if #cmd == 0 or (cur_pos ~= #cmd + 1 and cmd:sub(cur_pos, cur_pos) ~= " ") then return cmd, cur_pos end -- сопоставление for _, match in pairs(choices) do               if match:find("^" .. cmd:sub(1,cur_pos)) then table.insert(matches, match) end end -- если соотвествий не найдено if #matches == 0 then return cmd, cur_pos end -- цикл while ncomp > #matches do               ncomp = ncomp - #matches end -- возвращаем соотвествие и позицию return matches[ncomp], cur_pos end end

Замените цикл в котором обрабатываются нажатие клавиша MOD+number (как показано ниже):

-- Вычисление максимального числа цифр, мы должны ограничить девятью keynumber = 0 for s = 1, screen.count do      keynumber = math.min(9, math.max(#tags[s], keynumber)); end

for i = 1, keynumber do       table.foreach(awful.key({ modkey }, i,                      function  -- [cut] end), function(_, k) table.insert(globalkeys, k) end) -- [cut] end

что то вроде этого:

for i = 0, 9 do       table.foreach(awful.key({ modkey }, i,                      function local screen = mouse.screen awful.tag.viewonly(get_tag(screen, i)) end), function(_, k) table.insert(globalkeys, k) end) table.foreach(awful.key({ modkey, "Control" }, i,                     function local screen = mouse.screen local tag = get_tag(screen, i)                         if tag then tag.selected = not tag.selected end end), function(_, k) table.insert(globalkeys, k) end) table.foreach(awful.key({ modkey, "Shift" }, i,                     function if client.focus then awful.client.movetotag(get_tag(client.focus.screen, i)) end end), function(_, k) table.insert(globalkeys, k) end) table.foreach(awful.key({ modkey, "Control", "Shift" }, i,                     function if client.focus then awful.client.toggletag(get_tag(client.focus.screen, i)) end end), function(_, k) table.insert(globalkeys, k) end) if i > 0 then table.foreach(awful.key({ modkey, "Shift" }, "F" .. i,                         function local screen = mouse.screen if tags[screen][i] then for k, c in pairs(awful.client.getmarked) do                                     awful.client.movetotag(get_tag(screen, i), c)                                  end end end), function(_, k) table.insert(globalkeys, k) end) end end

Имея это, мы уже можем удалять и создавать некоторые управляющие тегами функции. Замените весь "-- {{{ Tags" на следующий код в rc.lua:

-- {{{ Tags -- Define tags table. tags = {} -- поместить все приложения без тегов как "0" тег на screen 1 function handle_orphans for _, c in pairs(client.get) do           if #c:tags == 0 then c:tags({get_tag(1, "0")}) end end end function sort_tags(screen_no) local all_tags = screen[screen_no]:tags table.sort(all_tags, function (a, b) return a.name < b.name end) screen[screen_no]:tags(all_tags) end function delete_tag(screen_no, name) local strname = '' .. name if protected_tag == screen_no .. strname then return end local result = tags[screen_no][strname] if result ~= nil then result.screen = nil tags[screen_no][strname] = nil end end -- получаем или создаем тег function get_tag(screen_no, name) local strname = '' .. name local result = tags[screen_no][strname] if not tags[screen_no][strname] then protected_tag = screen_no .. strname result = tag(strname) result.screen = screen_no tags[screen_no][strname] = result awful.layout.set(layouts[1], result) end protected_tag = nil return result end for s = 1, screen.count do       -- Каждый экран имеет собтвенную таблицу тегов. tags[s] = {} get_tag(s, 1).selected = true end -- }}}

Для того чтобы неиспользуемые теги красиво исчезали и сортировались, добавьте следующий код в конец hook'а awful.hooks.arrange.register

if screen == mouse.screen then for n, t in pairs(tags[screen]) do           if #t:clients == 0 and t ~= awful.tag.selected and dictlen(tags[screen]) > 1 then delete_tag(screen, n)           end end end sort_tags(screen) handle_orphans

Теперь создадим код для управления нашими тегами:

function tag_prompt(txt, callback) return function local screen = client.focus and client.focus.screen or mouse.screen awful.prompt.run({ prompt = txt },            mypromptbox[screen].widget,            function(t) callback(screen, t) end,            make_completer(get_keys(tags[screen])),            awful.util.getdir("cache") .. "/history_tags") end end

Теперь привяжем его к клавишам (проверьте с существующими клавишами, чтобы не было конфликтов!)

awful.key({ modkey,          },       "t", tag_prompt("go to tag: ",   function (screen, tag) awful.tag.viewonly(get_tag(screen, tag)) end)), awful.key({ modkey, "Shift"  },       "t", tag_prompt("move to tag: ", function (screen, tag) awful.client.movetotag(get_tag(screen, tag)) end)), awful.key({ modkey, "Ctrl", "Shift" }, "t", tag_prompt("toggle tag: ", function (screen, tag) awful.tag.toggletag(get_tag(screen, tag)) end))

Это всё, наслаждайтесь!

Запланированная работа
Есть некоторы очевидные места, котрые вы можете изменить/улучшить, такие как: * Поддержка +tag и -tag * dmenu может использоваться для выбора тега, вместо строки awesome, как это сделано в WMII - как опыт