Re: yay, my lay-out load and safe script
"Jurjen Middendorp" <[email protected]>
| Newsgroups | gmane.comp.window-managers.ion.general |
|---|---|
| Message-ID | <[email protected]> |
I'm almost done with my lay-out load and safe script, i think it's getting
pretty nice so i'll post it here :) If you have any comments on what i can
improve in it i'd like to hear them, i'm pretty new to ion (scripting) and
very new to lua, so all advice is welcome!
also printing a table (with ioncore.write_savefile) i get with functions
like region_list and such all give an error message "failed
to initialize userdata" so i'm not sure on how to use these functions. How
do i examine the data these functions give back?
anyway, here it is! hope someone finds it easier to use then the other
session-save scripts out there (i do :)
-- script that produces a menu to manage workspace lay-outs. it uses
-- an unexported C-function Export it by typing "EXTL_EXPORT_AS(WRegion,
-- get_configuration)" above the function region_get_configuration in
-- ioncore/saveload.c end then rebuild ion. everything should work now :)
-- TODO:
-- - make the winprop-maker better in recognizing programs
workspacer={}
defmenu("Workspacer", {
menuentry("Save current workspace", "workspacer.save_ws(ioncore.find_manager(_, 'WGroupWS'))"),
menuentry("Load saved workspace", "workspacer.query_saved_ws(_, 'WS to load', workspacer.get_ws)"),
menuentry("Remove saved workspace", "workspacer.query_saved_ws(_, 'WS to remove', workspacer.remove_saved)"),
menuentry("Rename saved workspace", "workspacer.query_saved_ws(_, 'WS to rename', workspacer.rename_saved)"),
menuentry("Rename workspace", "mod_query.query(_, 'Rename ws and frames to', nil, workspacer.rename_stuff)"),
})
defbindings("WFrame", {
kpress(META.."W", "mod_menu.menu(_, _sub, 'Workspacer')"),
})
-- Save/restore workspaces functions
------------------------------------
local workspaces = ioncore.read_savefile('saved_workspaces') or {}
function workspacer.write_ws_table()
ioncore.write_savefile('saved_workspaces', workspaces)
end
function workspacer.save_ws(r)
if obj_is(r, "WGroupWS") then
workspacer.make_cwin_config(r)
ws_def = r:get_configuration(r)
ws_def.switchto = true
ws_def.bottom_last_close = true
workspaces[ ws_def.name ] = ws_def
workspacer.write_ws_table()
workspacer.save_apps()
end
end
function workspacer.query_saved_ws(mplex, q_string, handler)
mod_query.query(mplex, q_string, nil, handler,
mod_query.make_completor(workspacer.complete_saved_ws))
end
function workspacer.rename_saved(_, old_name)
local function rename_to(_, new_name)
workspaces.new_name = workspaces.old_name
applist.new_name = applist.old_name
workspacer.remove_saved(_, old_name)
end
mod_query.query(_, "Rename "..old_name.." to", nil, rename_to)
end
function workspacer.remove_saved(_, name)
workspaces[name] = nil
workspacer.write_ws_table()
applist[name] = nil
workspacer.save_apps()
end
function workspacer.complete_saved_ws(s)
ws_list = {}
for i, _ in pairs(workspaces) do
if string.find(i, s, 1, true) then
table.insert(ws_list, i)
end
end
return ws_list
end
function workspacer.get_ws(mplex, ws_name)
WMPlex.attach_new(mplex:screen_of(), workspaces[ws_name]):goto()
workspacer.fill_space(ioncore.lookup_region(ws_name, "WGroupWS"))
end
-- Auto-winprop functions ideas+code from collapse and autoprop scripts
-----------------------------------------------------------------------
-- make an applist with the same names as the workspaces
-- an applist = commandline for programs and winprops for the
-- saved workspace
local applist = ioncore.read_savefile('saved_workspace_apps') or {}
function workspacer.save_apps()
ioncore.write_savefile('saved_workspace_apps', applist)
end
function workspacer.fill_space(ws)
ws_name = ws:name()
table.foreach(applist[ws_name], function(_, tab)
defwinprop{
class=tab.class,
instance=tab.instance,
role=tab.role,
target=tab.target,
oneshot=true
}
ioncore.exec(tab.exe)
end)
end
function workspacer.rename_stuff(mp, str)
local ws = ioncore.find_manager(mp, "WGroupWS")
if ws then
local old = ws:name()
WRegion.set_name(ws, str)
workspacer.rename_frames(ws, old)
end
end
function workspacer.rename_frames(wantws, str)
-- rename WFrames on the wantws
l = ioncore.region_list("WFrame")
want_ws = wantws:name()
for _,x in ipairs(l) do
local ws = ioncore.find_manager(x, "WGroupWS")
if ws then
if ws:name() == want_ws then
-- put the name of the current ws somewhere in the name of frame
rname = x:name()
if str then
rname = string.gsub(rname, str, want_ws)
end
if not string.find(rname, want_ws, 1, true) then
rname = want_ws.."--"..rname
end
WRegion.set_name(x, rname)
end
end
end
end
function workspacer.make_cwin_config(ws)
local function is_useful(cwin)
-- return the command line option to starting this program
-- TODO: copy more stuff from oops.lua
name = cwin:name()
first, last, file, dir = string.find(name, "^(.-) %+?=? ?%((.+)%) %- G?VIM$")
if file and dir then return "xterm -e vim "..dir.."/"..file end
_,__,file=string.find(name, "^Xpdf: (.+)$")
if file then return "xpdf "..file end
if string.find(name, ".*Firefox$") then return "firefox" end
_, _, file = string.find(name, "^gv: (.+)$")
--maybe rebuild the location database and use locate to find filenames for gv?
if file then return "gv "..file end
end
local function autoprop(cwin, dest, cmd, ws_name)
if not (cmd and ws_name) then return end
local p={}
name=dest:name()
p.exe = cmd
p.class="*"
p.role="*"
p.instance="*"
p.target=name
p=table.join(cwin:get_ident(), p)
if p.target then
applist[ws_name][p.class..p.role..p.instance..p.target..p.exe]=p
end
end
-- make a good applist for this workspace
workspacer.rename_frames(ws)
local ws_name = ws:name()
applist[ws_name] = {}
-- make a winprop for the clientwindow if it's on this workspace and
for _, cw in pairs(ioncore.clientwin_list()) do
local in_ws = ioncore.find_manager(cw, "WGroupWS"):name()
if in_ws == ws_name then
local exe = is_useful(cw)
autoprop(cw, cw:parent(), exe, ws_name)
end
end
end
function workspacer.print_all_names()
l = ioncore.region_list('WFrame')
for _, f in pairs(l) do
mod_query.message(f, f:name())
end
end