4 -- Translates bindings from Ion configuration into a listing for
13 local function gettext(x)
14 local t=translations[x]
15 if not t or t=="" then
22 local function TR(x, ...)
23 return string.format(gettext(x), unpack(arg))
26 local function read_translations(pofile)
27 local f, err=io.open(pofile)
32 local msgid, msgstr, st, en
35 if string.find(l, "^msgid") then
38 translations[msgid]=msgstr
41 st, en, msgid=string.find(l, '^msgid%s*"(.*)"%s*$')
42 elseif string.find(l, "^msgstr") then
43 assert(msgid and not msgstr)
44 st, en, msgstr=string.find(l, '^msgstr%s*"(.*)"%s*$')
45 elseif not (string.find(l, "^%s*#") or string.find(l, "^%s*$")) then
46 local st, en, str=string.find(l, '^%s*"(.*)"%s*$')
47 assert(msgid or msgstr)
58 translations[msgid]=msgstr
69 local function dobindings(fn, bindings)
71 local dummy = function() end
90 return {action = "doc", text = text}
93 function p.submap(kcb_, list)
96 return submap(kcb_, lst)
99 return {action = "kpress", kcb = kcb_, submap = list}
102 local function putcmd(cmd, guard, t)
108 function p.kpress(keyspec, cmd, guard)
109 return putcmd(cmd, guard, {action = "kpress", kcb = keyspec})
112 function p.kpress_wait(keyspec, cmd, guard)
113 return putcmd(cmd, guard, {action = "kpress_wait", kcb = keyspec})
116 local function mact(act_, kcb_, cmd, guard)
117 local st, en, kcb2_, area_=string.find(kcb_, "([^@]*)@(.*)")
118 return putcmd(cmd, guard, {
120 kcb = (kcb2_ or kcb_),
125 function p.mclick(buttonspec, cmd, guard)
126 return mact("mclick", buttonspec, cmd, guard)
129 function p.mdblclick(buttonspec, cmd, guard)
130 return mact("mdblclick", buttonspec, cmd, guard)
133 function p.mpress(buttonspec, cmd, guard)
134 return mact("mpress", buttonspec, cmd, guard)
137 function p.mdrag(buttonspec, cmd, guard)
138 return mact("mdrag", buttonspec, cmd, guard)
146 if (not v.kcb) or v.submap then
147 -- Submap rebinds are not presently handled
150 local id=v.action..":"..v.kcb..":"..(v.area or "")
165 function p.defbindings(context, bnd)
166 if not bindings[context] then
169 -- Reset documentation
170 table.insert(bindings[context], { action = "doc", text = nil })
173 for _, v in ipairs(bnd) do
174 ins(bindings[context], v)
178 local env=setmetatable({}, {
180 __newindex=function(x)
181 error("Setting global "..tostring(x))
189 local function parsefile(f, bindings)
190 local fn, err=loadfile(f)
195 return dobindings(fn, bindings)
201 -- Binding output {{{
203 local function docgroup_bindings(bindings)
207 local function parsetable(t, prefix)
208 for _, v in ipairs(t) do
209 if not v.invalid then
211 v.kcb=string.gsub(v.kcb, "AnyModifier%+", "")
213 if v.action=="doc" then
214 if outi==0 or #out[outi].bindings>0 then
217 out[outi]={doc=v.text, bindings={}}
219 parsetable(v.submap, prefix..v.kcb.." ")
223 table.insert(out[outi].bindings, v)
229 if outi~=0 and #out[outi].bindings==0 then
233 parsetable(bindings, "")
239 local function combine_bindings(v)
241 ["mpress"]=TR("press"),
242 ["mclick"]=TR("click"),
243 ["mdrag"]=TR("drag"),
244 ["mdblclick"]=TR("double click"),
248 for _, b in ipairs(v.bindings) do
253 if b.action=="kpress" or b.action=="kpress_wait" then
257 s=s..TR("%s %s", b.kcb, nact[b.action])
259 s=s..TR("%s %s at %s", b.kcb, nact[b.action], b.area)
267 local function write_bindings_man(db)
268 local function write_binding_man(v)
269 return '.TP\n.B '..combine_bindings(v)..'\n'..gettext(v.doc or "?")..'\n'
274 for _, v in ipairs(db) do
275 if #(v.bindings)>0 then
276 s=s..write_binding_man(v)
292 local function doargs(a)
298 elseif a[i]=='-i' then
301 elseif a[i]=='-D' then
302 replaces[a[i+1]]=a[i+2]
304 elseif a[i]=='-po' then
305 read_translations(a[i+1])
308 parsefile(a[i], bindings)
316 local f, err=io.open(infile)
321 local of, oerr=io.open(outfile, 'w+')
326 for l in f:lines() do
327 l=string.gsub(l, '%s*BINDINGS:([%w%.%-]+)%s*',
329 if not bindings[s] then
330 --error('No bindings for '..s)
333 local db=docgroup_bindings(bindings[s])
334 return write_bindings_man(db)
337 for pat, rep in pairs(replaces) do
338 l=string.gsub(l, pat, rep)