Previous
|
Up
|
Next
|
Other Process Primitives |
Primitives and EEL Subroutines |
Character Types |
Epsilon User's Manual and Reference >
Primitives and EEL Subroutines >
Control Primitives >
Control Flow
error(char *format, ...)
when_aborting() /* control.e */
quick_abort()
Epsilon provides several primitives for altering the
flow of control from one statement to the next. The
error( ) primitive takes arguments like say( ),
displays the string as say( ) does, and then aborts the current
command, returning to the main loop (see The Main Loop). In
addition this primitive discards any type-ahead and calls the
user-defined subroutine when_aborting( ) if it exists. The
standard version of when_aborting( ) optionally rings the bell
and removes the erroneous command from any keyboard macro being
defined. The primitive quick_abort( ) acts like
error( ) but displays no message.
user char user_abort;
int abort_key;
check_abort()
The variable user_abort is normally 0 . It is set to
1 when you press the key whose value is abort_key. To
disable the abort key, set abort_key to -1 . By default,
the abort_key variable is set to Control-G. Use the
set-abort-key command to set the abort_key variable.
See Interrupting a Command.
The primitive check_abort( ) calls error( ) with the
argument "Canceled." if the variable user_abort is
nonzero. Use the primitive check_abort( ) whenever a command
can be safely aborted, since otherwise an abort will only happen when
the command returns. Epsilon calls check_abort( ) internally
during any searching operation (see Searching Primitives),
when you use the delay( ) primitive (described below) to wait, or
(optionally) during certain file matching primitives (see Listing Commands & Buffers & Files) and file input/output (see File Reading Primitives).
leave(?int exitcode)
when_exiting() /* EEL subroutine */
The primitive leave( ) exits Epsilon with the specified exit
code (or 0 if omitted). A nonzero exit code keeps Epsilon from
saving any settings it normally would, such as the currently selected
font's name, or the sizes of any resized dialogs.
Just before calling leave( ),
Epsilon's standard commands call any subroutine whose name starts with
do_when_exiting_ . It receives one integer parameter, nonzero if
the user said to exit without checking for unsaved buffers or saving
the session. It should return no result. (It can abort if it needs
to prevent Epsilon from exiting; it should never do this if its
parameter was nonzero, though.) Epsilon also calls the
when_exiting( ) subroutine; modifying it was an earlier way
to customize Epsilon's behavior when exiting.
delay(int hundredths, int condition, ?int buf)
The delay( ) primitive takes an argument
specifying a period of time, in hundredths of a second, and a bit
pattern specifying additional conditions (with codes specified in
codes.h). It waits until one of the conditions occurs, or until the
specified time limit is reached. A time limit of -1 means to
wait forever.
The condition code COND_KEY makes Epsilon return when a key
is pressed or any key-generating input event occurs (like a mouse
event, or getting the focus). The condition code
COND_TRUE_KEY is similar, but only returns on actual keys,
not mouse events or other events. The condition code
COND_PROC makes Epsilon return when a concurrent process is
waiting for input, or has exited. The condition code
COND_PROC_EXIT makes Epsilon return when a concurrent
process has exited. For the last two conditions, Epsilon checks on
the buffer specified by the optional parameter buf . If buf is
missing or zero, it checks the buffer named "process". These
conditions are ignored if no process is running in the specified
buffer.
The condition flag COND_RETURN_ABORT , in combination with
COND_KEY, makes the delay( ) primitive return if the user
presses the abort key, instead of aborting by calling the
check_abort( ) primitive. (Note that if you don't specify
COND_KEY or COND_TRUE_KEY as well, the primitive ignores
all keys, including the abort key.)
This function varies a bit from one operating system to another. For
example, the Unix version of Epsilon can't detect when a process is
currently waiting for input, so it can only return when a process
exits. Also see the timing functions in Timing.
int do_recursion()
leave_recursion(int val)
int recursive_edit() /* control.e */
int recursive_edit_preserve() /* control.e */
char _recursion_level;
The do_recursion( ) primitive starts a new
loop for getting characters and interpreting them as commands. A
recursive edit preserves the current values of the variables
has_arg, iter, this_cmd, and prev_cmd,
but does not preserve the current buffer, window, or anything else.
(See The Main Loop.) Exit the recursion by calling the
leave_recursion( ) primitive. It arranges for the main loop to
exit, instead of waiting for another key to be executed. The call to
do_recursion() will then return with a value of val , the
argument of the call to leave_recursion( ).
Sometimes a recursive edit is done "secretly," and the user
doesn't know that one is being used. For example, when Epsilon reads
the name of a file using completion, it's actually doing a recursive
edit. Keys like <Space> exit the recursive edit with a special
code, and the function that did the recursive edit displays a menu,
or whatever is needed, and then does another recursive edit.
Other times (typing Ctrl-r in query-replace, for example),
the user is supposed to exit the recursive edit explicitly using the
exit-level command. When you're supposed to use
exit-level to exit, Epsilon displays extra [ ] 's in the
mode line as a reminder. The recursive_edit( ) subroutine does
a recursive edit, and arranges for these [ ] 's to appear by
modifying the _recursion_level variable. It contains the
number of extra [ ] 's to display. The recursive_edit( )
subroutine returns the value returned by do_recursion( ).
The recursive_edit_preserve( ) subroutine calls
recursive_edit( ). If the user changes the current buffer or
window during the recursion, recursive_edit_preserve( ) returns
to the original buffer or window before itself returning. If the user
deleted the original buffer or window during the recursive edit, this
subroutine remains in the new buffer or window and returns 0 . It
returns 1 otherwise.
If you call leave_recursion( ) when there has been no matching
do_recursion( ), Epsilon automatically invokes the command
exit. If exit returns instead of calling the
primitive leave( ), Epsilon begins its main loop again.
int setjmp(jmp_buf *location)
longjmp(jmp_buf *location, int value)
Epsilon implements aborting by two special primitives that allow
jumping from a function to another point in that function or any of
the functions that called it. The setjmp( ) primitive marks
the place to return, storing the location in a variable declared like
this:
jmp_buf location;
After calling setjmp( ) with a pointer to this structure, you
can return to this place in the code at any time until this function
returns by calling the longjmp( ) primitive. The first argument
is a pointer to the same structure, and the second argument may be
any nonzero value.
The first time setjmp( ) is called, it returns a zero value.
Each time longjmp( ) is called, Epsilon acts as if it is
returning from the original setjmp( ) call again, returning the
second argument from the longjmp( ). For example:
one()
{
jmp_buf location;
if (setjmp(&location)){
stuff("Back in one\n");
return;
} else
stuff("Ready to go\n");
two(&location);
}
two(loc)
jmp_buf *loc;
{
stuff("In two\n");
longjmp(loc, 1);
stuff("Never get here\n");
}
This example inserts the lines
Ready to go
In two
Back in one
jmp_buf *top_level;
The error( ) primitive uses the jump buffer pointed to
by the top_level variable. If you wish to get control when
the user presses the abort key, temporarily change the value of
top_level to refer to another jump buffer. Make sure you
restore it, however, or subsequent aborting may not work.
Previous
|
Up
|
Next
|
Other Process Primitives |
Primitives and EEL Subroutines |
Character Types |
Epsilon Programmer's Editor 14.04 manual. Copyright (C) 1984, 2021 by Lugaru Software Ltd. All rights reserved.
|