]> git.decadent.org.uk Git - ion3.git/blob - ioncore/ioncore_wd.lua
[svn-upgrade] Integrating new upstream version, ion3 (20071130)
[ion3.git] / ioncore / ioncore_wd.lua
1 --
2 -- ion/share/ioncore_wd.lua
3 -- 
4 -- Copyright (c) Tuomo Valkonen 2004-2007.
5 --
6 -- See the included file LICENSE for details.
7 --
8
9 local savefile="saved_wd"
10 local dirs={}
11 local px
12
13 if pcall(function() return require('posix') end) then
14     px=posix
15 end
16
17 local function checkdir(d)
18     if not px then
19         return true
20     else
21         local t, err=px.stat(d, "type")
22         if not t then
23             return nil, err
24         elseif t=="link" then
25             local d2, err=px.readlink(d)
26             if not d2 then
27                 return nil, err
28             else
29                 return checkdir(d2)
30             end
31         elseif t=="directory" then
32             return true
33         else
34             return nil, TR("Not a directory.")
35         end
36     end
37 end
38
39 local function regtreepath_i(reg)
40     local function f(s, v)
41         if v then
42             return v:manager()
43         else
44             return s
45         end
46     end
47     return f, reg, nil
48 end
49
50 --DOC
51 -- Change default working directory for new programs started in \var{reg}.
52 function ioncore.chdir_for(reg, dir)
53     assert(dir==nil or type(dir)=="string")
54     if dir=="" or dir==nil then
55         dirs[reg]=nil
56         return true
57     else 
58         local ok, err=checkdir(dir)
59         if ok then
60             dirs[reg]=dir
61         end
62         return ok, err
63     end
64 end
65
66 --DOC
67 -- Get default working directory for new programs started in \var{reg}.
68 function ioncore.get_dir_for(reg)
69     for r in regtreepath_i(reg) do
70         if dirs[r] then
71             return dirs[r]
72         end
73     end
74 end
75
76
77 local function lookup_script_warn(script)
78     local script=ioncore.lookup_script(script)
79     if not script then
80         warn(TR("Could not find %s", script))
81     end
82     return script
83 end
84
85
86 local function lookup_runinxterm_warn(prog, title, wait)
87     local rx=lookup_script_warn("ion-runinxterm")
88     if rx then
89         rx="exec "..rx
90         if wait then
91             rx=rx.." -w"
92         end
93         if title then
94             rx=rx.." -T "..string.shell_safe(title)
95         end
96         if prog then
97             rx=rx.." -- "..prog
98         end
99     end
100     return rx
101 end
102
103
104 --DOC
105 -- Run \var{cmd} with the environment variable DISPLAY set to point to the
106 -- root window of the X screen \var{reg} is on. If \var{cmd} is prefixed
107 -- by a colon (\code{:}), the following command is executed in an xterm
108 -- (or other terminal emulator) with the help of the \command{ion-runinxterm} 
109 -- script. If the command is prefixed by two colons, \command{ion-runinxterm}
110 -- will ask you to press enter after the command is finished, even if it
111 -- returns succesfully.
112 function ioncore.exec_on(reg, cmd, merr_internal)
113     local _, _, col, c=string.find(cmd, "^[%s]*(:+)(.*)")
114     if col then
115         cmd=lookup_runinxterm_warn(c, nil, string.len(col)>1)
116         if not cmd then
117             return
118         end
119         if XTERM then
120             cmd='XTERMCMD='..string.shell_safe(XTERM)..' '..cmd
121         end
122     end
123     return ioncore.do_exec_on(reg, cmd, ioncore.get_dir_for(reg), 
124                               merr_internal)
125 end
126
127
128 local function load_config()
129     local d=ioncore.read_savefile(savefile)
130     if d then
131         dirs={}
132         for nm, d in pairs(d) do
133             local r=ioncore.lookup_region(nm)
134             if r then
135                 local ok, err=checkdir(d)
136                 if ok then
137                     dirs[r]=d
138                 else
139                     warn(err)
140                 end
141             end
142         end
143     end
144 end
145
146
147 local function save_config()
148     local t={}
149     for r, d in pairs(dirs) do
150         local nm=obj_exists(r) and r:name()
151         if nm then
152             t[nm]=d
153         end
154     end
155     ioncore.write_savefile(savefile, t)
156 end
157
158
159 local function init()
160     load_config()
161     ioncore.get_hook("ioncore_snapshot_hook"):add(save_config)
162     ioncore.get_hook("ioncore_post_layout_setup_hook"):add(load_config)
163 end
164
165 init()
166