-- -- By Jeremy Hankins -- Multi-head support added by Johannes Segitz -- Cycling contributed by -- Antti Kaihola -- -- Time-stamp: <2005-11-16 12:02:46 Jeremy Hankins> -- <2005-08-26 11:35:00 kaihola> -- -- With these functions you can bind a key to start an application if -- it's not already running, or cycle its windows if it is. You can -- use it by doing something like this in your bindings file: -- -- kpress(META.."C", "app.byname('xterm -title shell', 'shell')"), -- kpress(META.."T", "app.byclass('emacs', 'Emacs')"), -- kpress(META.."M", "app.byinstance('xterm -name muttTerm -e mutt', 'XTerm', 'muttTerm')"), -- -- The byname function expects an executable and a window title, the -- byclass expects a class, the byinstance expects a class and an -- instance. -- -- NOTE: cycling windows requires ioncore.current(), so it will only -- work with snapshot XXX or later. -- -- If you use a multihead setup you can use something like this to start -- applictions on your current screen -- -- kpress(MOD1.."C", "app.byname('xterm -title shell', 'shell', _)"), -- kpress(MOD1.."T", "app.byclass('emacs', 'Emacs', _)"), -- -- For emacs users there's also app.emacs_eval, and app.query_editfile, -- which interacts with any currently running emacs process (using -- gnuclient), or starts emacs to run the given command. -- app.query_editfile is a replacement for query_lib.query_editfile to -- use the currently running emacs rather than ion-edit. -- app={} function app.match_class(class, instance) -- Return matching client windows as a table. -- If the current window is among them, it's placed last on the list -- and its successor at the beginning of the list. This facilitates -- cycling multiple windows of an application. local result = {} local offset = 0 local currwin = ioncore.current() ioncore.clientwin_i(function (win) if class == win:get_ident().class then if instance then if instance == win:get_ident().instance then table.insert(result, table.getn(result)-offset+1, win) end else table.insert(result, table.getn(result)-offset+1, win) end end if win == currwin then -- Current client window found, continue filling the table from -- the beginning. offset = table.getn(result) end return true end) return result end function app.byname(prog, name, where) local win = ioncore.lookup_clientwin(name) if win then ioncore.defer(function () win:goto() end) else if where then ioncore.exec_on(where, prog) else ioncore.exec(prog) end end end function app.byclass(prog, class, where) local win = app.match_class(class)[1] if win then ioncore.defer(function () win:goto() end) else if where then ioncore.exec_on(where, prog) else ioncore.exec(prog) end end end function app.byinstance(prog, class, instance, where) local win = app.match_class(class, instance)[1] if win then ioncore.defer(function () win:goto() end) else if where then ioncore.exec_on(where, prog) else ioncore.exec(prog) end end end function app.emacs_eval(expr) local emacswin = app.match_class("Emacs")[1] if emacswin then ioncore.exec("gnuclient -batch -eval '"..expr.."'") ioncore.defer(function () emacswin:goto() end) else ioncore.exec("emacs -eval '"..expr.."'") end end function app.query_editfile(mplex, dir) local function handler(file) app.emacs_eval("(find-file \""..file.."\")") end mod_query.do_query(mplex, 'Edit file:', dir or mod_query.get_initdir(), handler, mod_query.file_completor) end