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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.