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