]> git.decadent.org.uk Git - ion3.git/blobdiff - mod_query/mod_query.lua
[svn-upgrade] Integrating new upstream version, ion3 (20070203)
[ion3.git] / mod_query / mod_query.lua
index 0f51738edceb6c7dde1058f5354a01cdf09cb18a..243f98785fafc317097fc52506531214f55c29f3 100644 (file)
@@ -1,7 +1,7 @@
 --
 -- ion/query/mod_query.lua -- Some common queries for Ion
 -- 
--- Copyright (c) Tuomo Valkonen 2004-2006.
+-- Copyright (c) Tuomo Valkonen 2004-2007.
 -- 
 -- Ion is free software; you can redistribute it and/or modify it under
 -- the terms of the GNU Lesser General Public License as published by
@@ -31,14 +31,6 @@ local DIE_TIMEOUT_NO_ERRORCODE=2 -- 2 seconds
 -- Generic helper functions {{{
 
 
-function mod_query.make_completor(completefn)
-    local function completor(cp, str, point)
-        cp:set_completions(completefn(str, point))
-    end
-    return completor
-end
-
-
 --DOC
 -- Low-level query routine. \var{mplex} is the \type{WMPlex} to display
 -- the query in, \var{prompt} the prompt string, and \var{initvalue}
@@ -60,12 +52,13 @@ function mod_query.query(mplex, prompt, initvalue, handler, completor,
     end
 
     -- Check that no other queries are open in the mplex.
-    local l=mplex:managed_list()
-    for i, r in pairs(l) do
-        if obj_is(r, "WEdln") then
-            return
-        end
+    local ok=mplex:managed_i(function(r) 
+                                 return not obj_is(r, "WEdln") 
+                             end)
+    if not ok then
+        return
     end
+    
     local wedln=mod_query.do_query(mplex, prompt, initvalue, 
                                    handle_it, completor, cycle)
     if context then
@@ -175,6 +168,20 @@ function mod_query.file_completor(wedln, str)
 end
 
 
+function mod_query.get_initdir(mplex)
+    --if mod_query.last_dir then
+    --    return mod_query.last_dir
+    --end
+    local wd=(ioncore.get_dir_for(mplex) or os.getenv("PWD"))
+    if wd==nil then
+        wd="/"
+    elseif string.sub(wd, -1)~="/" then
+        wd=wd .. "/"
+    end
+    return wd
+end
+
+
 function mod_query.query_execfile(mplex, prompt, prog)
     assert(prog~=nil)
     local function handle_execwith(mplex, str)
@@ -200,39 +207,10 @@ function mod_query.query_execwith(mplex, prompt, dflt, prog, completor,
 end
 
 
-function mod_query.get_initdir(mplex)
-    --if mod_query.last_dir then
-    --    return mod_query.last_dir
-    --end
-    local wd=(ioncore.get_dir_for(mplex) or os.getenv("PWD"))
-    if wd==nil then
-        wd="/"
-    elseif string.sub(wd, -1)~="/" then
-        wd=wd .. "/"
-    end
-    return wd
-end
-
-
-local MAXDEPTH=10
-
+-- }}}
 
-function mod_query.complete_from_list(list, str)
-    local results={}
-    local len=string.len(str)
-    if len==0 then
-        results=list
-    else
-        for _, m in pairs(list) do
-            if string.sub(m, 1, len)==str then
-                table.insert(results, m)
-            end
-        end
-    end
-    
-    return results
-end    
 
+-- Completion helpers {{{
 
 local pipes={}
 
@@ -325,6 +303,85 @@ function mod_query.popen_completions(cp, cmd, fn, reshnd)
 end
 
 
+local function mk_completion_test(str, sub_ok, casei_ok)
+    if not str then
+        return function(s) return true end
+    end
+    
+    local function mk(str, sub_ok)
+        if sub_ok then
+            return function(s) return string.find(s, str, 1, true) end
+        else
+            local len=string.len(str)
+            return function(s) return string.sub(s, 1, len)==str end
+        end
+    end
+    
+    local casei=(casei_ok and mod_query.get().caseicompl)
+    
+    if not casei then
+        return mk(str, sub_ok)
+    else
+        local fn=mk(string.lower(str), sub_ok)
+        return function(s) return fn(string.lower(s)) end
+    end
+end
+
+
+local function mk_completion_add(entries, str, sub_ok, casei_ok)
+    local tst=mk_completion_test(str, sub_ok, casei_ok)
+    
+    return function(s) 
+               if s and tst(s) then
+                   table.insert(entries, s)
+               end
+           end
+end
+
+
+function mod_query.complete_keys(list, str, sub_ok, casei_ok)
+    local results={}
+    local test_add=mk_completion_add(results, str, sub_ok, casei_ok)
+    
+    for m, _ in pairs(list) do
+        test_add(m)
+    end
+
+    return results
+end    
+
+
+function mod_query.complete_name(str, iter)
+    local sub_ok_first=true
+    local casei_ok=true
+    local entries={}
+    local tst_add=mk_completion_add(entries, str, sub_ok_first, casei_ok)
+    
+    iter(function(reg)
+             tst_add(reg:name())
+             return true
+         end)
+    
+    if #entries==0 and not sub_ok_first then
+        local tst_add2=mk_completion_add(entries, str, true, casei_ok)
+        iter(function(reg)
+                 tst_add2(reg:name())
+                 return true
+             end)
+    end
+    
+    return entries
+end
+
+
+function mod_query.make_completor(completefn)
+    local function completor(cp, str, point)
+        cp:set_completions(completefn(str, point))
+    end
+    return completor
+end
+
+
 -- }}}
 
 
@@ -340,36 +397,24 @@ function mod_query.call_warn(mplex, fn)
 end
 
 
-function mod_query.complete_name(str, list)
-    local entries={}
-    local l=string.len(str)
-    for i, reg in pairs(list) do
-        local nm=reg:name()
-        if nm and string.sub(nm, 1, l)==str then
-            table.insert(entries, nm)
-        end
-    end
-    if #entries==0 then
-        for i, reg in pairs(list) do
-            local nm=reg:name()
-            if nm and string.find(nm, str, 1, true) then
-                table.insert(entries, nm)
-            end
-        end
-    end
-    return entries
-end
-
 function mod_query.complete_clientwin(str)
-    return mod_query.complete_name(str, ioncore.clientwin_list())
+    return mod_query.complete_name(str, ioncore.clientwin_i)
 end
 
+
 function mod_query.complete_workspace(str)
-    return mod_query.complete_name(str, ioncore.region_list("WGroupWS"))
+    local function iter(fn) 
+        return ioncore.region_i(function(obj)
+                                    return (not obj_is(obj, "WGroupWS")
+                                            or fn(obj))
+                                end)
+    end
+    return mod_query.complete_name(str, iter)
 end
 
+
 function mod_query.complete_region(str)
-    return mod_query.complete_name(str, ioncore.region_list())
+    return mod_query.complete_name(str, ioncore.region_i)
 end
 
 
@@ -383,6 +428,7 @@ function mod_query.gotoclient_handler(frame, str)
     end
 end
 
+
 function mod_query.attachclient_handler(frame, str)
     local cwin=ioncore.lookup_clientwin(str)
     
@@ -423,18 +469,37 @@ function mod_query.workspace_handler(mplex, name)
     local ws=ioncore.lookup_region(name, "WGroupWS")
     if ws then
         ws:goto()
-        return
-    end
+    else
+        local function create_handler(mplex_, layout)
+            if not layout or layout=="" then
+                layout="default"
+            end
+            
+            if not ioncore.getlayout(layout) then
+                mod_query.warn(mplex_, TR("Unknown layout"))
+            else
+                local scr=mplex:screen_of()
+                
+                local function mkws()
+                    local tmpl={name=name, switchto=true}
+                    if not ioncore.create_ws(scr, tmpl, layout) then
+                        error(TR("Unknown error"))
+                    end
+                end
 
-    local scr=mplex:screen_of()
-    
-    local function mkws()
-       if not ioncore.create_ws(scr, {name=name}) then
-            error(TR("Unknown error"))
+                mod_query.call_warn(mplex, mkws)
+            end
         end
-    end
 
-    mod_query.call_warn(mplex, mkws)
+        local function compl_layout(str)
+            local los=ioncore.getlayout(nil, true)
+            return mod_query.complete_keys(los, str, true, true)
+        end
+        
+        mod_query.query(mplex, TR("New workspace layout (default):"), nil,
+                        create_handler, mod_query.make_completor(compl_layout),
+                        "workspacelayout")
+    end
 end
 
 
@@ -504,10 +569,20 @@ end
 
 
 --DOC
--- This function asks for a name new for the workspace on which the
--- query resides.
-function mod_query.query_renameworkspace(mplex)
-    local ws=ioncore.find_manager(mplex, "WGroupWS")
+-- This function asks for a name new for the workspace \var{ws},
+-- or the one on which \var{mplex} resides, if it is not set.
+-- If \var{mplex} is not set, one is looked for.
+function mod_query.query_renameworkspace(mplex, ws)
+    if not mplex then
+        assert(ws)
+        mplex=ioncore.find_manager(ws, "WMPlex")
+    elseif not ws then
+        assert(mplex)
+        ws=ioncore.find_manager(mplex, "WGroupWS")
+    end
+    
+    assert(mplex and ws)
+    
     mod_query.query(mplex, TR("Workspace name:"), ws:name(),
                     function(mplex, str) ws:set_name(str) end,
                     nil, "framename")
@@ -766,6 +841,8 @@ end
 
 
 mod_query.known_hosts={}
+mod_query.hostnicks={}
+mod_query.ssh_completions={}
 
 
 function mod_query.get_known_hosts(mplex)
@@ -789,8 +866,6 @@ function mod_query.get_known_hosts(mplex)
 end
 
 
-mod_query.hostnicks={}
-
 function mod_query.get_hostnicks(mplex)
     mod_query.hostnicks={}
     local f
@@ -800,7 +875,7 @@ function mod_query.get_hostnicks(mplex)
     if h then
         f=io.open(h.."/.ssh/config")
     end
-    if not f then 
+    if not f then
         warn(TR("Failed to open ~/.ssh/config"))
         return
     end
@@ -837,21 +912,10 @@ function mod_query.complete_ssh(str)
     end
     
     local res = {}
-    
-    if string.len(host)==0 then
-        if string.len(user)==0 then
-            return mod_query.ssh_completions
-        end
-        
-        for _, v in ipairs(mod_query.ssh_completions) do
-            table.insert(res, user .. v)
-        end
-        return res
-    end
+    local tst = mk_completion_test(host, true, false)
     
     for _, v in ipairs(mod_query.ssh_completions) do
-        local s, e=string.find(v, host, 1, true)
-        if s==1 and e>=1 then
+        if tst(v) then
             table.insert(res, user .. v)
         end
     end
@@ -859,7 +923,6 @@ function mod_query.complete_ssh(str)
     return res
 end
 
-mod_query.ssh_completions={}
 
 --DOC
 -- This query asks for a host to connect to with SSH. 
@@ -1086,7 +1149,7 @@ function mod_query.query_menu(mplex, themenu, prompt)
     end
 
     local function xform_name(n, is_submenu)
-        return (string.lower(string.gsub(n, "[-%s]+", "-"))
+        return (string.lower(string.gsub(n, "[-/%s]+", "-"))
                 ..(is_submenu and "/" or ""))
     end
 
@@ -1116,13 +1179,8 @@ function mod_query.query_menu(mplex, themenu, prompt)
     local ntab=xform_menu({}, menu, "")
     
     local function complete(str)
-        local results={}
-        for s, e in pairs(ntab) do
-            if string.find(s, str, 1, true) then
-                table.insert(results, s)
-            end
-        end
-        return results
+        -- casei_ok false, because everything is already in lower case
+        return mod_query.complete_keys(ntab, str, true, false)
     end
     
     local function handle(mplex, str)
@@ -1188,14 +1246,16 @@ function mod_query.show_tree(mplex, reg, max_depth)
                       indent, reg:xid())
         end
         
-        if (not max_depth or max_depth > d) and reg.managed_list then
-            local mgd=reg:managed_list()
-            if #mgd > 0 then
-                s=s .. "\n" .. indent .. "---"
-                for k, v in pairs(mgd) do
-                    s=s .. "\n" .. get_info(v, indent, d+1)
-                end
-            end
+        if (not max_depth or max_depth > d) and reg.managed_i then
+            local first=true
+            reg:managed_i(function(sub)
+                              if first then
+                                  s=s .. "\n" .. indent .. "---"
+                                  first=false
+                              end
+                              s=s .. "\n" .. get_info(sub, indent, d+1)
+                              return true
+                          end)
         end
         
         return s