2 -- ion/share/ioncore-bindings.lua
4 -- Copyright (c) Tuomo Valkonen 2004-2009.
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"
50 gfn
, gerr
=loadstring(gfncode
, guardcode
)
52 ioncore
.warn_traced(TR("Error compiling guard: %s", gerr
))
57 local function guarded(gfn
, fn
)
61 return function(_
, _sub
, _chld
)
62 if gfn(_
, _sub
, _chld
) then
69 if type(cmd
)=="string" then
70 local fncode
=("return function(_, _sub, _chld) local d = "
72 local fn
, err
=loadstring(fncode
, cmd
)
74 ioncore
.warn_traced(TR("Error in command string: ")..err
)
78 return guarded(gfn
, fn())
79 elseif type(cmd
)=="function" then
80 return guarded(gfn
, cmd
)
83 ioncore
.warn_traced(TR("Invalid command"))
87 local function putcmd(cmd
, guard
, tab
)
90 func
=ioncore
.compile_cmd(cmd
, guard
)
91 if type(func
)~="function" then
104 -- Used to enter documentation among bindings so that other programs
105 -- can read it. Does nothing.
106 function ioncore
.bdoc(text
)
107 return {action
= "doc", text
= text
}
111 -- Returns a function that creates a submap binding description table.
112 -- When the key press action \var{keyspec} occurs, Ioncore will wait for
113 -- a further key presse and act according to the submap.
114 -- For details, see Section \ref{sec:bindings}.
115 function ioncore
.submap(keyspec
, list
)
118 return submap(keyspec
, lst
)
121 return {action
= "kpress", kcb
= keyspec
, submap
= list
}
125 -- Creates a binding description table for the action of pressing a key given
126 -- by \var{keyspec} (with possible modifiers) to the function \var{cmd}.
127 -- The \var{guard} controls when the binding can be called.
128 -- For more informationp see Section \ref{sec:bindings}.
129 function ioncore
.kpress(keyspec
, cmd
, guard
)
130 return putcmd(cmd
, guard
, {action
= "kpress", kcb
= keyspec
})
134 -- This is similar to \fnref{ioncore.kpress} but after calling \var{cmd},
135 -- Ioncore waits for all modifiers to be released before processing
136 -- any further actions.
137 -- For more information on bindings, see Section \ref{sec:bindings}.
138 function ioncore
.kpress_wait(keyspec
, cmd
, guard
)
139 return putcmd(cmd
, guard
, {action
= "kpress_wait", kcb
= keyspec
})
143 -- Submap enter event for bindings.
144 function ioncore
.submap_enter(cmd
, guard
)
145 return putcmd(cmd
, guard
, {action
= "submap_enter"})
149 -- Submap modifier release event for bindings.
150 function ioncore
.submap_wait(cmd
, guard
)
151 return putcmd(cmd
, guard
, {action
= "submap_wait"})
155 -- Submap leave event for bindings.
156 --function ioncore.submap_leave(cmd, guard)
157 -- return putcmd(cmd, guard, {action = "submap_leave"})
160 local function mact(act_
, kcb_
, cmd
, guard
)
161 local st
, en
, kcb2_
, area_
=string.find(kcb_
, "([^@]*)@(.*)")
162 return putcmd(cmd
, guard
, {
164 kcb
= (kcb2_
or kcb_
),
170 -- Creates a binding description table for the action of clicking a mouse
171 -- button while possible modifier keys are pressed,
172 -- both given by \var{buttonspec}, to the function \var{cmd}.
173 -- For more information, see Section \ref{sec:bindings}.
174 function ioncore
.mclick(buttonspec
, cmd
, guard
)
175 return mact("mclick", buttonspec
, cmd
, guard
)
179 -- Similar to \fnref{ioncore.mclick} but for double-click.
180 -- Also see Section \ref{sec:bindings}.
181 function ioncore
.mdblclick(buttonspec
, cmd
, guard
)
182 return mact("mdblclick", buttonspec
, cmd
, guard
)
186 -- Similar to \fnref{ioncore.mclick} but for just pressing the mouse button.
187 -- Also see Section \ref{sec:bindings}.
188 function ioncore
.mpress(buttonspec
, cmd
, guard
)
189 return mact("mpress", buttonspec
, cmd
, guard
)
193 -- Creates a binding description table for the action of moving the mouse
194 -- (or other pointing device) while the button given by \var{buttonspec}
195 -- is held pressed and the modifiers given by \var{buttonspec} were pressed
196 -- when the button was initially pressed.
197 -- Also see section \ref{sec:bindings}.
198 function ioncore
.mdrag(buttonspec
, cmd
, guard
)
199 return mact("mdrag", buttonspec
, cmd
, guard
)
203 -- Define bindings for context \var{context}. Here \var{binding} is
204 -- a table composed of entries created with \fnref{ioncore.kpress},
205 -- etc.; see Section \ref{sec:bindings} for details.
206 function ioncore
.defbindings(context
, bindings
)
207 local function filterdoc(b
)
209 for k
, v
in ipairs(b
) do
213 v2
.submap
=filterdoc(v2
.submap
)
215 if v2
.action
~="doc" then
221 return ioncore
.do_defbindings(context
, filterdoc(bindings
))
224 local function bindings_get_cmds(map
)
225 for k
, v
in pairs(map
) do
227 v
.cmd
=compiled2str
[v
.func
]
230 bindings_get_cmds(v
.submap
)
236 -- Get a table of all bindings.
237 function ioncore
.getbindings(maybe_context
)
238 local bindings
=ioncore
.do_getbindings()
239 if maybe_context
then
240 bindings_get_cmds(bindings
[maybe_context
])
241 return bindings
[maybe_context
]
243 for k
, v
in pairs(bindings
) do