Help Subroutines ||
Primitives and EEL Subroutines ||
Epsilon User's Manual and Reference >
Primitives and EEL Subroutines >
Input Primitives >
user int key;
user int full_key;
int generic_key(int k)
when_idle(int times) /* EEL subroutine */
add_buffer_when_idle(int buf, int (*func)())
delete_buffer_when_idle(int buf, int (*func)())
when_repeating() /* EEL subroutine */
The wait_for_key( ) primitive advances to the
next key, waiting for one if necessary. The variable key
stores the last key obtained from wait_for_key( ).
Some key combinations have both a generic and specific interpretation.
For instance, the <Plus> key on a numeric keypad has a generic
code identical to the <Plus> key on the main keyboard, but a
unique specific code. Epsilon sets the full_key variable to
the specific key code for that key, and key to the generic code
for the key (in this case, "+"). For keys with only one
interpretation, Epsilon sets key and full_key the same.
The generic_key( ) primitive returns the generic version of
the specified key. For keys with only one interpretation, it returns
the original key code.
When you call wait_for_key( ), it first checks to see if the
ungot_key variable has a key (see below) and uses that if it
does. If not, and a keyboard macro is active, wait_for_key( )
returns the next character from the macro. (The primitive also keeps
track of repeat counts for macros.) If there is no key in
ungot_key and no macro is active, the primitive checks to see
if you have already typed another key and returns it if you have. If
not, the primitive waits until you type a key (or a mouse action or
other event occurs--Epsilon treats all of these as keys).
When a concurrent process is outputting text into an Epsilon buffer,
it only appears there during a call to wait_for_key( ). Epsilon
handles the processing of other concurrent events like FTP transfers
during this time as well.
While Epsilon is waiting for a key, it calls the when_idle( )
subroutine. The default version of this function does idle-time code
coloring and displays any defined idle-time message in the echo area
(see the show-when-idle variable), among other things. The
when_idle( ) subroutine receives a parameter that indicates the
number of times the subroutine has been called since Epsilon began
waiting for a key. Every time Epsilon gets a key (or other event), it
resets this count to zero.
The when_idle( ) subroutine should return a timeout code in
hundredths of a second. Epsilon will not call the subroutine again
until the specified time has elapsed, or another key arrives. If it
doesn't need Epsilon to call it for one second, for example, it can
100. If it wants Epsilon to call it again as soon as
possible (assuming Epsilon remains idle), it can return
the subroutine has completed all its work and doesn't need to be
called again until after the next keystroke or mouse event, it can
-1. Epsilon will then go idle waiting for the next event.
(The return value is only advisory; Epsilon may call
when_idle( ) more frequently or less frequently than it
A mode may wish to provide additional functions that run during idle
time, beyond those the when_idle( ) subroutine performs itself.
The add_buffer_when_idle( ) subroutine registers a function
func so that it will be called during idle-time processing
buf is the current buffer. The
delete_buffer_when_idle( ) subroutine removes the specified
function from that buffer's list of buffer-specific idle-time
functions. (It does nothing if the function was not on the list.) A
buffer-specific when-idle function takes a parameter
must return a result in the same fashion as the when_idle( )
To add an idle-time task not associated with any specific
buffer, or one that runs even if a given buffer isn't the current one,
define a function with a name that starts with
Epsilon will call it whenever it's idle. It must take a parameter
times and return a result just like the when_idle( )
When you hold down a key to make it repeat, Epsilon does not call the
when_idle( ) subroutine. Instead, it calls the
when_repeating( ) subroutine. Again, this varies by
environment: under some operating systems, Epsilon cannot distinguish
between repeated key presses and holding down a key to make it
repeat. If this is the case, Epsilon won't call the function.
You can add your own logic for when a
key repeats by defining a function with a name that starts with
do_when_repeating_. The when_repeating( ) subroutine will
call it whenever it runs. It must take no parameters and return no
The is_key_repeating( ) primitive
returns nonzero if the user is currently holding down a key causing
it to repeat. Epsilon can't detect this in all environments, so the
primitive always returns
0 in that case.
int getkey() /* control.e */
Instead of calling wait_for_key( ) directly, EEL commands
should call the EEL subroutine getkey( ) (defined in
control.e), to allow certain actions that are written in EEL code to
take effect on each character. For example, the standard version of
getkey( ) saves each new character in a macro, if you're
defining one. It checks the EEL variable
which contains the length of the macro being defined plus one, or
zero if you're not defining a macro. For convenience, getkey( )
also returns the new key. The getkey( ) subroutine calls
wait_for_key( ). (If you want to add functions to
getkey( ), see The Name Table to make sure your
extension doesn't interfere with other extensions that may also add
to getkey( ).)
int in_macro(?int ignore_suspended)
The char_avail( ) primitive returns
0 if wait_for_key( )
would have to wait if it were called, and
1 otherwise. That is, it
returns nonzero if and only if a key is available from
ungot_key, a keyboard macro, or the keyboard.
The in_macro( ) primitive returns
1 if a keyboard macro
is running or has been suspended,
0 otherwise. If its optional
ignore_suspended parameter is nonzero, it counts a suspended macro
as if no macro were running. While processing the last key of a
keyboard macro, in_macro( ) will return
0, because Epsilon has
already discarded the keyboard macro by that time. Check the
key-from-macro variable instead to see if the key currently
being handled came from a macro.
There are some textual macros defined in eel.h which
help in forming the codes for keys in an EEL function. The codes for
normal ASCII keys are their ASCII codes, so the code for the key "a"
'a'; the same goes for Unicode characters. The
macro makes these normal keys into their Alt forms, so the code for
CTRL() macro changes a character
into the corresponding control character, so
CTRL('H') both represent the Ctrl-H key. Both
ALT(CTRL('q')) stand for the Ctrl-Alt-q key.
The remaining key codes represent those keys that don't correspond to
any possible buffer character, plus various key codes that represent
other kinds of input events, such as mouse activity.
FKEY() macro represents the function keys.
FKEY(12) are F1 and F12, respectively. Note that this
macro takes a number, not a character.
Refer to the cursor pad keys using the macros
KEYDELETE. You can
refer to the numeric keypad keys with the
NUMDIGIT(0) is N-0, and
NUMDIGIT(9) is N-9.
is the numeric keypad period, and
NUMENTER is the
<Enter> or <Return> key on the numeric keypad (normally mapped
The codes for the remaining keys are
GREYHELP for the +, -, *, /, =,
and Help keys on the numeric keypad (not every keyboard has all these
SPACEBAR for the <Enter>,
<Backspace>, <Tab>, <Esc>, and <Spacebar> keys,
#define NUMSHIFT(c) ((c) | KEY_SHIFT)
#define NUMCTRL(c) ((c) | KEY_CTRL)
#define NUMALT(c) ((c) | KEY_ALT)
#define KEY_PLAIN(c) ((c) & ~(KEY_SHIFT | KEY_CTRL | KEY_ALT))
macros make shifted, control, and alt versions of keys, respectively,
by turning on the bit in a key code for each of these properties:
NUMCTRL(NUMDIGIT(3)) is Ctrl-N-<PgDn>, and
NUMALT(KEYDELETE) is A-<Del>. The
macro strips away these bits.
In this version, NUMALT( ) and ALT( ) are the same, and
NUMCTRL( ) and CTRL( ) only differ on certain low-numbered
characters: the former always turns on the KEY_CTRL bit, while
the latter also generates ASCII control codes when given suitable
int make_alt(int k) /* control.e */
int make_ctrl(int k) /* control.e */
The make_alt( ) subroutine defined in control.e will return
an Alt version of any key. The make_ctrl( ) subroutine is
similar, but makes a key into its Control version. These may be used
instead of the ALT( ) and CTRL( ) macros.
IS_CTRL_KEY() macro to determine if a given key is a
control key of some kind. Its value is nonzero if the key is an
ASCII Control character, a function key with Control held down, or
any other Control key. It understands all types of keys. The macro
IS_ALT_KEY() is similar; its value is nonzero if the given key
was generated when holding down the Alt key.
A macro command recorded using the notation
<!find-file> uses the bit flag
CMD_INDEX_KEY. In this case the value of key is not a
true key, but rather the name table index of the specified command.
See Keys and their Representation for more information.
user int ungot_key;
If the ungot_key variable is set to some value other than its
usual value of
-1, that number is placed in key and
full_key as the new key when wait_for_key( ) is called next,
and ungot_key is set to
-1 again. You can use this to make a
command that reads keys itself, then exits and runs the key again when
you press an unrecognized key. The statement
ungot_key = key;
show_char(char *str, int key, ?int style)
The show_char( ) primitive converts a key code to its printed
representation, described in Keys and their Representation. For example,
the code produced by function key 3 generates the string
The string is appended to the character array
If show_char( )'s optional third parameter is present, and
nonzero, this primitive will use a longer, more readable printed
representation. For example, rather than
S-F-10, show_char( ) will return
Shift-F10. (Epsilon can only parse the
former style, in Epsilon command files and in all other commands that
use the get_keycode( ) primitive below.)
This function always represents non-Latin1 Unicode characters (those
in the range 256-65535) with their character names, like <GREEK
SMALL LETTER GAMMA>. With a style of
3, Epsilon does this for
Latin 1 characters (those in the range 32-255) too, thus representing
all Unicode characters by name. With a style of
2, Epsilon uses
Unicode character names for non-ASCII Latin 1 characters (those in the
range 128-255) but represents printable ASCII characters like "J"
as-is. With a style of
1, it represents all Latin 1 characters
(in the range 32-255) as-is, using Unicode character names only for
characters over 255.
%k sequence used by sprintf( ) and other functions,
described in Printf-style Format Strings, for a more convenient way to
translate keys or characters to text. It always uses style 1.
#define key_t int
int key_value(char *s, ?char **after)
stuff_macro(key_t *mac, int oneline)
The get_keycode( ) primitive is used to translate a sequence
of key names such as
"C-xC-A-f" into the equivalent key codes. It
moves past a quoted sequence of key names in the buffer and returns an
array of ints with the key codes. The same array is used each time
the function is called. The first entry of the array contains the
number of array entries. The primitive returns null if the string had
an invalid key name.
key_t macro represents the
type of a key. It's the same as an
int in this versions, but
not in older versions. Writing key_t instead of
#including the compatibility header file
oldkeys.h helps make
EEL code compatible with older versions.
The key_value( ) primitive also converts key names into key
codes, but it gets the key name from a string, not a buffer, and
returns a single key code at a time. It tries to interpret
s as a
key name, and returns its value. If the optional pointer
non-null, it must point to a character pointer. Epsilon sets
*after to the position in the string after the key name. When
s contains an invalid key name, key_value( ) returns
after is non-null) to
The stuff_macro( ) subroutine inserts a sequence of key names
into the current buffer in a format that get_keycode( ) can read,
surrounding the key names with
" characters. The list of keys is
specified by an array of ints in the same format get_keycode( )
uses: the first value contains the total number of array entries. If
oneline is nonzero, the subroutine represents line breaks with
\n so that the text stays on one line.
user char key_type;
user short key_code;
When wait_for_key( ) returns a key that comes directly from the
keyboard, it also sets the primitive variables key_type and
key_code. These let EEL programs distinguish between keys
that translate to the same Epsilon key code, for certain special
applications. The wait_for_key( ) primitive doesn't change
either variable when the key comes from ungot_key.
The key_code variable contains the sixteen-bit BIOS-style
encoding for the key that Epsilon received from the operating system,
if available. Its ASCII code is in the low eight bits and its scan
code is in the high eight bits.
The key_type variable has one of the following values, defined in
key was a special key without an ASCII translation, such as a function
key. Such keys are of type KT_NONASCII_EXT if they're one of
the keys on an extended keyboard that are synonyms to multikey
sequences on the old keyboard, such as the keys on the extended
keyboard's cursor pad.
A key type of
KT_ACCENT_SEQ indicates a multikey sequence
that the operating system or a resident program has translated as a
single key, such as an ê. Key type
means the operating system translated a single key to a graphics
character or foreign language character. Key type
KT_NORMAL represents any other key. Most keys have a key
type of KT_NORMAL.
A key type of
KT_MACRO means the key came from a macro. A
macro key recorded with the
EXTEND_SEL_KEY bit flag returns
a key type of
KT_EXTEND_SEL instead, but these extend codes
are not used in current versions of Epsilon. In either case, the
key_code variable is set to zero in this case.
In many environments, the key_code variable is always zero, and
key_type is either KT_NORMAL, KT_MACRO, or
Help Subroutines ||
Primitives and EEL Subroutines ||
Copyright (C) 1984, 2020 by Lugaru Software Ltd. All rights reserved.