2 -- ion/share/ioncore-bindings.lua
4 -- Copyright (c) Tuomo Valkonen 2004-2007.
6 -- See the included file LICENSE for details.
9 local ioncore=_G.ioncore
11 local warn=ioncore.warn
13 local compiled2str=setmetatable({}, {__mode="k"})
16 -- Compile string \var{cmd} into a bindable function. Within \var{cmd}, the
17 -- variable ''\var{_}'' (underscore) can be used to refer to the object
18 -- that was selecting for the bound action and chosen to handle it.
19 -- The variable ''\var{_sub}'' refers to a ''currently active'' sub-object
20 -- of \var{_}, or a sub-object where the action loading to the binding
21 -- being called actually occured.
23 -- The string \var{guard} maybe set to pose limits on \code{_sub}. Currently
24 -- supported guards are \code{_sub:non-nil} and \code{_sub:WFoobar}, where
25 -- \type{WFoobar} is a class.
26 function ioncore.compile_cmd(cmd, guard)
31 local st, en, condition=string.find(guard, "^_sub:([%w-_]+)$")
34 st, en, condition=string.find(guard, "^_chld:([%w-_]+)$")
41 ioncore.warn_traced(TR("Invalid guard %s.", guard))
42 elseif condition=="non-nil" then
43 guardcode='if not '..sub..' then return end; '
45 guardcode='if not obj_is('..sub..', "'..condition..'") then return end; '
48 local gfncode="return function(_, _sub, _chld) "..guardcode.." return true end"
49 local gfn, gerr=loadstring(gfncode, guardcode)
51 ioncore.warn_traced(TR("Error compiling guard: %s", gerr))
56 local function guarded(gfn, fn)
60 return function(_, _sub, _chld)
61 if gfn(_, _sub, _chld) then
68 if type(cmd)=="string" then
69 local fncode=("return function(_, _sub, _chld) local d = "
71 local fn, err=loadstring(fncode, cmd)
73 ioncore.warn_traced(TR("Error in command string: ")..err)
77 return guarded(gfn, fn())
78 elseif type(cmd)=="function" then
79 return guarded(gfn, cmd)
82 ioncore.warn_traced(TR("Invalid command"))
86 local function putcmd(cmd, guard, tab)
89 func=ioncore.compile_cmd(cmd, guard)
90 if type(func)~="function" then
103 -- Used to enter documentation among bindings so that other programs
104 -- can read it. Does nothing.
105 function ioncore.bdoc(text)
106 return {action = "doc", text = text}
110 -- Returns a function that creates a submap binding description table.
111 -- When the key press action \var{keyspec} occurs, Ioncore will wait for
112 -- a further key presse and act according to the submap.
113 -- For details, see Section \ref{sec:bindings}.
114 function ioncore.submap(keyspec, list)
117 return submap(keyspec, lst)
120 return {action = "kpress", kcb = keyspec, submap = list}
124 -- Creates a binding description table for the action of pressing a key given
125 -- by \var{keyspec} (with possible modifiers) to the function \var{cmd}.
126 -- The \var{guard} controls when the binding can be called.
127 -- For more informationp see Section \ref{sec:bindings}.
128 function ioncore.kpress(keyspec, cmd, guard)
129 return putcmd(cmd, guard, {action = "kpress", kcb = keyspec})
133 -- This is similar to \fnref{ioncore.kpress} but after calling \var{cmd},
134 -- Ioncore waits for all modifiers to be released before processing
135 -- any further actions.
136 -- For more information on bindings, see Section \ref{sec:bindings}.
137 function ioncore.kpress_wait(keyspec, cmd, guard)
138 return putcmd(cmd, guard, {action = "kpress_wait", kcb = keyspec})
142 -- Submap enter event for bindings.
143 function ioncore.submap_enter(cmd, guard)
144 return putcmd(cmd, guard, {action = "submap_enter"})
148 -- Submap modifier release event for bindings.
149 function ioncore.submap_wait(cmd, guard)
150 return putcmd(cmd, guard, {action = "submap_wait"})
154 -- Submap leave event for bindings.
155 --function ioncore.submap_leave(cmd, guard)
156 -- return putcmd(cmd, guard, {action = "submap_leave"})
159 local function mact(act_, kcb_, cmd, guard)
160 local st, en, kcb2_, area_=string.find(kcb_, "([^@]*)@(.*)")
161 return putcmd(cmd, guard, {
163 kcb = (kcb2_ or kcb_),
169 -- Creates a binding description table for the action of clicking a mouse
170 -- button while possible modifier keys are pressed,
171 -- both given by \var{buttonspec}, to the function \var{cmd}.
172 -- For more information, see Section \ref{sec:bindings}.
173 function ioncore.mclick(buttonspec, cmd, guard)
174 return mact("mclick", buttonspec, cmd, guard)
178 -- Similar to \fnref{ioncore.mclick} but for double-click.
179 -- Also see Section \ref{sec:bindings}.
180 function ioncore.mdblclick(buttonspec, cmd, guard)
181 return mact("mdblclick", buttonspec, cmd, guard)
185 -- Similar to \fnref{ioncore.mclick} but for just pressing the mouse button.
186 -- Also see Section \ref{sec:bindings}.
187 function ioncore.mpress(buttonspec, cmd, guard)
188 return mact("mpress", buttonspec, cmd, guard)
192 -- Creates a binding description table for the action of moving the mouse
193 -- (or other pointing device) while the button given by \var{buttonspec}
194 -- is held pressed and the modifiers given by \var{buttonspec} were pressed
195 -- when the button was initially pressed.
196 -- Also see section \ref{sec:bindings}.
197 function ioncore.mdrag(buttonspec, cmd, guard)
198 return mact("mdrag", buttonspec, cmd, guard)
202 -- Define bindings for context \var{context}. Here \var{binding} is
203 -- a table composed of entries created with \fnref{ioncore.kpress},
204 -- etc.; see Section \ref{sec:bindings} for details.
205 function ioncore.defbindings(context, bindings)
206 local function filterdoc(b)
208 for k, v in ipairs(b) do
212 v2.submap=filterdoc(v2.submap)
214 if v2.action~="doc" then
220 return ioncore.do_defbindings(context, filterdoc(bindings))
223 local function bindings_get_cmds(map)
224 for k, v in pairs(map) do
226 v.cmd=compiled2str[v.func]
229 bindings_get_cmds(v.submap)
235 -- Get a table of all bindings.
236 function ioncore.getbindings(maybe_context)
237 local bindings=ioncore.do_getbindings()
238 if maybe_context then
239 bindings_get_cmds(bindings[maybe_context])
240 return bindings[maybe_context]
242 for k, v in pairs(bindings) do