The [binding] command.
Introduction
The binding command lets you create and manipulate key bindings
(aka keyboard shortcuts) in Alpha.
Bindings are associated with Tcl procs (or Tcl scripts): this is a
characteristic they share with menu items which can also be associated with
Tcl procs (see the [menuItem] reference file).
A key binding is defined by the following attributes:
- a code which identifies the key. This key can designate either
a character code (i-e the code-point of a character) or a virtual
keycode corresponding to a physical key on the keyboard.
- a string specifying which modifier keys are pressed together
with the key;
- a boolean value telling whether the code is to be interpreted as a
character code or a virtual keycode;
- an optional tag which is used to specify that this key binding should
be executed only if a particular mode is in force.
A key binding is uniquely determined by these parameters. The code and
the modifiers are required parameters. The other parameters are optional.
By default, a code is interpreted as a character code. If the tag is empty
or unspecified, the binding is global, otherwise it is mode-specific.
The [binding] command establishes a link between a key combo
and an action to execute, represented by a Tcl proc.
Synopsis
The formal syntax of the [binding] command is:
binding subcommand ?options? |
The possible subcommands are described below. Depending on the subcommand,
various options can be additionally specified.
Specifying a key combo
The [allowed] subcommand
This subcommand lets you filter the bindings, that is to say allow only
certain kinds of bindings to be executed. The filtering is based on the
modifier keys. The command lets you specify, based on the modifiers, which
bindings should be accepted by the application: only bindings involving
these modifiers will be executed.
The syntax can take three forms:
binding allowed
binding allowed modifiers
binding allowed all
In the first form, the command returns the modifiers which are currently
accepted. The other forms are used to specify the set of modifiers which
are allowed.
By convention, the returned string can be:
- any combination of the letters c, o, s,
z, e ;
- an empty string if no bindings are allowed.
The letters c, o, s, z have the
same meaning as described in the Specifying a key combo section. The letter e is used to designate bindings which do
not have a modifier key (for instance bindings defined for the carriage
return).
An empty string means that all the bindings are disabled.
Under normal circumstances, the command returns "szoce"
which means that all the bindings are allowed. But, if a modal dialog is
displayed, the core suspends all the bindings and the returned value, in
that case, would be an empty string.
The third form is a convenience to reenable all the bindings. This
command can be useful if all the bindings have been accidentally suspended
and the application seems unresponsive. To restore them, just invoke the
command binding allowed all.
Note that another technique to restrict some bindings is to specify
a context with the -context
option of the [binding create] command.
The [create] subcommand
This subcommand creates a new binding or redefines an already existing
one. It accepts a few options. The complete syntax is:
binding create ?option value...? {modifiers key} proc
The command has two required arguments:
- the {modifiers key} argument represents the key combination as
explained in the Specifying a key combo section.
- the proc argument is a Tcl proc or a block of Tcl instructions.
Here are the currently supported options:
- the -context option lets you
specify a required context, that is to say a condition to meet for the
binding to be active. When the key combo for this binding is pressed, the
binding is executed only if the application is in the given context. The
value for this option is an integer. The available context values are
described in the table below.
- the -creator option lets you specify a four-character type
(similar to Mac OS creator types) to identify a collection of bindings, for
instance all the bindings created by a package. This can be useful for
packages to keep track of their bindings (see the
[binding list]
command).
- the -help option lets you specify a description string for
the binding. It is useful only for information purposes.
- the -prefix option lets you specify a prefix combination. It
is used to build composite bindings à la emacs. See the
Composite bindings section below.
- the -tag option lets you specify the name of a mode associated
with the key binding. This makes the binding mode-specific instead of
global. If it is not specified, the key binding will be global.
The possible values for the -context option are:
Name | Value | Description |
None | 0 | no context is required |
Exists Doc Window | 1 | there must exist at least one document window |
Active Doc Window | 2 | the frontmost window must be a document window |
Exists Root Window | 3 | there must exist at least one view root window |
Active Root Window | 4 | the frontmost window must be a view root window |
If there is already a binding corresponding to the same key combination,
it is overwritten by the new one.
Note also that the [binding allowed] command
has precedence over the -context
option: the context condition is tested only if the binding's modifiers
are allowed.
The [delete] subcommand
This subcommand is used to delete a key binding. The syntax is:
binding delete ?option value...? {modifiers key}
The possible options are -tag and -prefix: they have the same meaning as the
-tag and -prefix options in the [binding create]
command.
If the binding does not exist, the command is just ignored.
See the Specifying a key combo section for
the format of the {modifiers key} argument.
The [info] subcommand
This subcommand returns information about an existing key binding.
The syntax is:
binding info (command|context|help) ?option value...? {modifiers key}
The third argument indicates which kind of info is desired. It can be one of the
following keywords:
- command to return the Tcl script associated with the binding.
- context to return the context required by the binding. See
the -context option and the meaning
of the possible values in this table.
- help to return the description string of the binding. This is
the string which was optionnally specified with the -help option when the binding was created with the
[binding create] command.
The possible options are -tag and
-prefix: they have the same meaning as the
-tag and
-prefix options in the [binding create]
command.
If the binding does not exist, the command raises an error.
See the Specifying a key combo section for
the format of the {modifiers key} argument.
The [list] subcommand
This subcommand returns a list of the currently existing key bindings. The
syntax is:
binding list ?option value...?
One can specify some options to restrict the returned list to
bindings satisfying these options. The available options are:
-command, -creator, -key, -modifiers, -prefix, -tag, -virtual.
If the command is invoked without any argument, it returns a list of
all the currently defined bindings. This list may be augmented each time a
new mode is loaded.
This allows you to specify key codes or modifiers separately. The value
of the -key option can be either a numeric value or a character enclosed
between single quotes. The value of the -modifiers option is a string
made of the c, o, s, z, f, v
letters.
See the Specifying a key combo section.
The -virtual option can be used to list only character code
bindings (if the value is 0) or only virtual keycode bindings (if the value
is 1).
Each element of the list returned by the [binding list] command is
a sublist describing a particular key binding. This sublist contains 6 or 8
elements:
- the modifier string (an empty string if there are no modifier specifications)
- the key code (decimal value or letter)
- the tag (an empty string if the binding is global)
- the creator (an empty string if no creator was specified)
- the Tcl script attached to the binding
- the help string attached to the binding
- the modifier string of the prefix (empty if there are no modifier specifications)
- the key code of the prefix (decimal value)
The last two elements are present only if the binding is composite, that is
to say if it has been defined with a -prefix option.
For instance, if a binding is created like this:
binding create -creator "abcd" -tag Tcl {cv 112} Tcl::doSomethingProc
the returned sublist will be
cv 112 Tcl abcd Tcl::doSomethingProc ""
This command can be used to find if there exists a key binding
bound to a particular Tcl proc. For instance:
binding list -command Tcl::doSomethingProc
The [binding info] command with the -creator option
can also be useful to identify a collection of bindings. It is useful for
packages in order to keep track of the bindings they define. If a
collection of bindings have been declared with a -creator option like
this
binding create -creator "ABCD" {modifiers key} proc
it is possible to get the list of all these bindings with the following command:
binding list -creator "ABCD"
See examples in the Examples section below.
Note that character code bindings corresponding to a character are
case insensitive: they are stored internally using the code of the
uppercase character even if the definition was invoked using a lowercase
character. On output, all the character code bindings corresponding to a
printable character are written with this character (uppercase form between
single quotes); the other bindings (including virtual key bindings) are
represented by the decimal value of the key. So, if a binding has been
defined for 'a', the character returned in [binding list] will be
'A'. This is consistent with the way bindings are displayed in menus.
Specifying a key combo
Many subcommands of the [binding] command take a keyboard shortcut argument of the form
{modifiers key}
This argument describes a key combination. It is a two-elements Tcl list:
- the first item of this list (modifiers) corresponds to the modifier keys pressed
in the combination;
- the second item (key) is the key.
The next paragraphs explain how to specify both of them.
The modifiers are specified as a string made of some of the
following letters:
Letter | Description |
c | corresponds to the Command key (⌘ ) |
s | corresponds to the Shift key (⇧ ) |
o | corresponds to the Option key (⌥ ) |
z | corresponds to the Control key (⌃ ) |
v | specifies whether the main key is a character code or as a virtual key code. |
The modifier string must be specified as an empty string if no modifiers are associated
with the key combo. For more information about the modifier v
, see the
Character codes vs. virtual keycodes section below.
There are three ways of specifying the main key:
- as a numeric value representing the code-point of the character (if it
is a character code binding) or the code of the key (if it is a virtual
keycode binding). The value can be expressed in hexadecimal, octal or
decimal notation. For instance the character A (code 65 in the ASCII
encoding) can be represented numerically by one of the following values: 65
in decimal, 0101 in octal or 0x41 in hexadecimal.
- in the case of a character code binding, instead of specifying the
code-point of the character, one can specify the character itself between
single quotes. For instance,
{c 'A'}
is the same as {c 65}
.
- in the case of a virtual keycode binding, instead of specifying the
code of the key, one can use a symbolic name. Some symbolic names (like Home, Up, Right) have been defined to designate the principal
non-letter keys of the keyboard. See the table in the
Symbolic key names section below.
Note that character code bindings are case insensitive. So Command-a
and Command-A
are identical. If you really want the
Shift key to be part of the binding, you must specify the letter
s
in the modifier string. For instance, the string {cs 65}
corresponds to the ⇧⌘A
combination, but {c 'A'}
is synonym of {c 'a'}
and corresponds to the
⌘A
combination.
Character codes vs. virtual keycodes
A keyboard equivalent may be either a character code or a
virtual keycode. Only one is used by the application at any given time: a
virtual keycode binding always has precedence over a character code binding.
Note that zero is a valid virtual keycode.
Symbolic key names
Here is the list of the predefined symbolic names which can be used to
specify a virtual key binding. These values are case insensitive, so one
can use HOME, home, Home indifferently. The following table gives
the numeric key codes corresponding to the symbolic names:
Name | Keycode |
Clear | 0x75 |
Delete | 0x33 |
Down | 0x7d |
End | 0x77 |
Enter | 0x4c |
Esc | 0x35 |
F1 | 0x7a |
F2 | 0x78 |
F3 | 0x63 |
F4 | 0x76 |
F5 | 0x60 |
F6 | 0x61 |
F7 | 0x62 |
F8 | 0x64 |
F9 | 0x65 |
F10 | 0x6d |
F11 | 0x67 |
F12 | 0x6f |
F13 | 0x69 |
F14 | 0x6b |
F15 | 0x71 |
Help | 0x72 |
Home | 0x73 |
Kpad= | 0x51 |
Kpad* | 0x43 |
Kpad/ | 0x4b |
Kpad+ | 0x45 |
Kpad- | 0x4e |
Kpad. | 0x41 |
Kpad0 | 0x52 |
Kpad1 | 0x53 |
Kpad2 | 0x54 |
Kpad3 | 0x55 |
Kpad4 | 0x56 |
Kpad5 | 0x57 |
Kpad6 | 0x58 |
Kpad7 | 0x59 |
Kpad8 | 0x5b |
Kpad9 | 0x5c |
Left | 0x7b |
NumLock | 0x47 |
PageDown | 0x79 |
PageUp | 0x74 |
Return | 0x24 |
Right | 0x7c |
Space | 0x31 |
Tab | 0x30 |
Up | 0x7e |
Composite bindings
The -prefix option can be used in the [binding create]
command to define composite bindings. Its value is a two-elements Tcl list
of the form {modifiers key}
with the same meaning as with the main
key argument of the [binding create] command.
For instance, in order to define the binding
⌃⌥B Z
(which
means, first press ⌃⌥B
, then press Z
), the instruction is:
binding create -prefix {oz 'B'} {"" 'Z'} someProc
The binding ⌃⌥B Z
will trigger the Tcl proc
designated by someProc.
For this mechanism to work, the simple ⌃⌥B
binding must
also be defined and must be bound to the [prefixBinding] core
command like this:
binding create {oz 'B'} prefixBinding
The [prefixBinding] core command takes care of waiting for the second
part of the binding to be entered (here the letter Z
) and then to execute
the code designated by someProc.
Bindings with an infix
There is an even more elaborate kind of composite bindings which involves
an infix, like for instance ⌃A
5
⌥B
:
here the infix is 5 and means that the action which is bound to the combo
⌃A ⌥B
will receive the value 5 as an additional
argument which it can interpret in different ways.
The embrace package, for instance, makes use of this
technique: the ⌃B S
combo encloses the
word under the insertion cursor in square brackets. If you type for example
⌃B
3
S
,
then the group of three preceding words will be enclosed in square brackets.
To create a binding accepting an infix, one must specify the
-infix option in the [prefixBinding] command. The value of
the -infix option is a regular expression which describes which
values are considered an infix: for instance [1-5r]
means that the
infix could be a digit between 1 and 5 or the letter r. Similarly
the regular expression (\d+|[a-c])
allows any number (made of one
or more digits) or one of the letters a, b, c.
Here is an example:
binding create {z 'A'} { prefixBinding -infix {(\d+|r)} }
binding create -prefix {z 'A'} {"" 'B'} someProc
If the user executes the binding ⌃A
, the [prefixBinding]
command will be expecting an infix (something matched by the regular
expression) hopefully followed later by the letter B
.
If finally the entered combo is ⌃A
15
B
, the proc someProc will be invoked
with an additional argument 15. This proc should know how to handle this
argument. The infix is not compulsory though: if the user enters something
that is not matched by the regular expression, it is assumed that there is
no infix, so the user could type ⌃A B
as
well (in that case, the additional argument will be an empty string).
Important: it is up to the user (and to the developer of
packages!) to avoid ambiguities. With the example above, a new binding for
the combo ⌃A R
would never work because
the letter r would be interpreted as an infix and would expect
another keydown event to complete the binding.
Examples
Here are a few basic examples which can be executed one by one in the
Tcl Shell (⌘Y
) in Alpha:
proc bindingActionProc {idx} {
alertnote "Command $idx triggered"
}
# Define a few commands
for {set i 1} {$i < 12} {incr i} {
set cmd$i "test::bindingActionProc $i"
}
# Bindings to letter A (resp opt-cmd-A, ctrl-cmd-A, and ctrl-opt-cmd-A)
binding create -help "do something" {co 65} $cmd1
binding create -help "perform something" {cz 65} $cmd2
binding create -help "something else" {coz 65} $cmd3
# Bindings to letter L
binding create {co 76} $cmd4
binding create -tag Tcl {co 76} $cmd5
binding create -tag Python {co 76} $cmd6
binding create -tag Ruby {co 76} $cmd7
# A virtual keycode binding attached to opt-F5.
# Note that the v modifier could be omitted here.
binding create {ov F5} $cmd8
binding create -tag Tcl {ov F5} $cmd9
binding create -tag Ruby {ov F5} $cmd10
# The Help key
binding create {v Help} $cmd11
# Get a list of all the bindings
binding list
# Get a list of all the bindings associated with letter L
binding list -key 76
# Get a list of all the bindings using opt-cmd
binding list -modifiers "co"
# Get a list of all the bindings defined in Ruby mode
binding list -tag Ruby
# Get a list of all the opt-cmd bindings in Ruby mode
binding list -modifiers "co" -tag Ruby
# Get a list of all the bindings attached to the action contained in
# the cmd1 variable
binding list -command $cmd1
# Find the command associated with the opt-cmd-L combo in Ruby mode
binding info command -tag Ruby {co 'L'}
# Get the help string associated with a binding
binding info help {co 65}
# Delete the previous binding
binding delete -tag Ruby {co 76}
Last updated 2021-05-21 14:43:34