home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
jed098-4.zip
/
JED
/
DOC
/
HOOKS.TXT
< prev
next >
Wrap
Text File
|
1997-02-01
|
11KB
|
318 lines
This file documents the various hooks for extending JED.
A `hook' is simply a user defined S-Lang function that may be used to extend
the editor or to modify how it behaves under certain circumstances. There
are two kinds of hooks that vary according to whether the hook is called
``internally'' from the editor by the underlying C code or whether the hook
is called from another S-Lang routine. The hooks may be subdivided further
according to their scope. They may apply to all buffers (globally), only
buffers sharing the same mode (modal), or to a single buffer (local).
Global Hooks.
The global hooks affect all buffers. They are:
1. `command_line_hook': This hook is called from within the editor to
parse the command line arguments. It is defined in the file
`site.sl' and cannot be customized by the user. However, the it may
be customized by the system manager. In addition to parsing the
command line arguments the default value of this hook also loads the
user's personal initialization file.
2. `jed_startup_hook': Although this function is defined in `site.sl',
it can be changed by a user because it is called after the user
initialization file is loaded. This hook is called just prior to
the main editing loop of the editor. It also calls the hook
`startup_hook' which may be defined by the user as a convenient way
to customize `jed_startup_hook'. See `exit_hook' for an example of
how this may be exploited.
3. `exit_hook': This hook is called when the intrinsic function
`exit_jed' is called. Although it has no default definition does
not mean that it is not useful. For example, one could use:
define exit_hook()
{
variable ch;
if (BATCH) exit_jed();
flush("Really Exit? ");
ch = getkey();
if ((ch == 'Y') || (ch == 'y')) exit_jed ();
error ("Aborted!");
}
to confirm the exit. Note also that although `exit_jed' calls this
function, `exit_hook' will not be called again if it int turn calls
`exit_jed'.
Also, for MSDOS it might be desirable for the editor to exit in the
same directory that it started. This will work:
define exit_hook()
{
variable dir;
if (bufferp("*scratch*"))
{
sw2buf("*scratch*");
(,dir,,) = getbuf_info();
change_default_dir(dir); pop();
}
call( "exit_jed" );
}
Like many hooks, if an error is generated by the hook, the function
that called it will fail and the operation will be aborted.
Finally, `exit_hook' and `startup_hook' may be used together to
implement a way of saving the state of the editor. A minimal
implementation might be:
variable Jed_State_File = dircat (getenv ("HOME"), ".jedstate");
define exit_hook ()
{
variable file = buffer_filename ();
variable cmd;
if (strlen (file))
{
% This is mainly for MSDOS to fix the backslash character
% used for path names.
file = str_quote_string (file, "\\", '\\');
cmd = Sprintf ("() = find_file (\"%s\");", file, 1);
cmd = Sprintf ("%s\ngoto_line (%d); goto_column (%d);",
cmd, whatline (), what_column (), 3);
() = write_string_to_file (cmd, Jed_State_File);
}
exit_jed ();
}
define startup_hook ()
{
if (1 == file_status (Jed_State_File))
{
() = evalfile (Jed_State_File);
() = delete_file (Jed_State_File);
}
}
4. `suspend_hook': This hook has no default value and is called just
before suspending the editor. One might use it as a simple way of
prohibiting suspension, e.g.,
define suspend_hook ()
{
error ("Suspending not allowed.");
}
5. `resume_hook': It is called immediately after JED resumes after being
suspended. This hook is predefined only on VMS systems. This does
not mean that it cannot be used on other systems as well. For
example, here is a silly use
define resume_hook ()
{
message ("Welcome back!");
}
but I am sure that you will think of something more clever.
6. `mode_hook': Immediately after JED loads a file into a buffer, it
calls `mode_hook' to set the mode of the buffer. The default value
is defined in `site.sl'. This hook is called with with the file name
extension of the file as its only parameter. This function sets the
mode of the buffer based on the value of the file name extension.
There are several ways to customize this hook. The easiest is to
simply call the function `add_mode_for_extension' with the mode that
is to be associated with a particular extension. For example,
suppose that you edit files with names like `main.c++'. To have
`c_mode' associated with files of this type, simply call:
add_mode_for_extension ("c", "c++");
The important point to realize is that the first parameter is the
name of the mode but it should not include the `_mode' part of the
mode name.
The other way to customize mode_hook is through the function pointer
`mode_hook_pointer' which the user can define to set the mode. If
the function pointed to by `mode_hook_pointer' returns non-zero,
`mode_hook' will return to the calling routine. Specifically, the
default value of `mode_hook' looks like:
define mode_hook (ext)
{
if (mode_hook_pointer (ext)) return;
.
.
}
One could simple point `mode_hook_pointer' to something like:
define set_no_mode (ext)
{
return 1;
}
mode_hook_pointer = &set_no_mode;
Typically, one would do something useful like:
define my_mode_hook (ext)
{
if (strcmp ("pas", ext)) return 0;
my_pascal_mode ();
return 1;
}
mode_hook_pointer = &my_mode_hook;
Here `my_pascal_mode' is a hypothetical pascal mode.
As a final example, consider the case where one would like to set the
mode based on the filename and NOT the extension. For example, the
Elm mailer user files of the form `snd.XXX' and one would like to use
text mode on such files. Again, the solution is to use the
`mode_hook_pointer':
define my_mode_hook (ext)
{
variable file;
(file,,,) = getbuf_info ();
if (0 != strncmp (file, "snd.", 4)) return 0;
text_mode ();
return 1;
}
mode_hook_pointer = &my_mode_hook;
Finally, the global variable `Default_Mode' may be pointed to a
function to set the mode if a suitable mode was not obtained from the
extension. By default, it has the value:
Default_Mode = &text_mode;
7. `find_file_hook': This hook is called after a file is read into the
editor via the internal function `find_file'. It is passed the full
filename of the file read into the buffer. The supplied default for
this function simply looks for an autosave file and warns the user
if it should be used instead. It might also be used to preprocess
the buffer before the user starts to edit it.
*** Note: This hook will most like be changed such that it is
called beore the file is read in.
8. `format_paragraph_hook': This hook is called after a paragraph is
formatted but only if the a prefix argument was given prior to the
execution of the internal function `format_paragraph'. That is, the
default binding of `format_paragraph' is `ESC q'. Pressing `ESC 1'
immediately before pressing `ESC q' will format the paragraph and
then call `format_paragraph_hook'. The default definition for this
hook left and right justifies the paragraph.
9. `is_paragraph_separator': This hook is called by the editor to locate
paragraph delimeters. If defined, it applies globally to all buffers
except those which have a local definition (see the `par_sep' hook).
The default value is coded in C and basically reduces to:
define is_paragraph_separator ()
{
bol();
if (looking_at("\\") or looking_at("%")) return (1);
skip_white();
return (eolp());
}
which is useful for TeX mode. The hook must simply return a non-zero
value if the current line is a paragraph delimeter or zero if it is
not.
Mode Hooks:
These are hooks that get called when the editor enters a particular
mode. Usually, one just wants to defined keys. For this purpose, use the
`local_setkey' function.
1. `tex_mode_hook': This hook is called when JED starts its TeX mode.
Use it to bind certain functions that either have no binding or have
one that you do not like, e.g.,
define tex_mode_hook ()
{
local_unsetkey ("^C");
local_setkey ("latex_do_environment", "^C^E");
local_setkey (" \\alpha", "^Ca");
local_setkey (" \\Alpha", "^CA");
local_setkey (" \\Beta", "^CB");
local_setkey (" \\beta", "^Cb");
% etc...
}
Notice that in this hook, I have simply set keys `Ctrl-C a', etc... to
insert `\alpha', etc...
2. c_mode_hook
3. fortran_hook
4. text_mode_hook
5. mail_hook
A useful hook here is to defined Ctrl-C Ctrl-C to send the message al
la emacs:
define mail_hook ()
{
local_unsetkey ("^C");
local_setkey ("send", "^C^C");
}
6. slang_mode_hook
7. dired_mode_hook
8. fortran_hook
Local hooks:
These hooks apply to individual buffers. They must be ``declared'' to
the buffer using the intrinsic function `set_buffer_hook'.
1. `par_sep': function used to determine where paragraph boundaries
are. See the hook `is_paragraph_separator' for more information.
2. `indent_hook': function called after a line is indented by the
function `indent_line'.
3. `wrap_hook': function called after a line is wrapped. For example,
in writing this document, I want the lines following the numbers to
be offset some. So I wrote:
define text_mode_wrap_hook ()
{
variable p;
push_spot ();
go_up(1); bol (); skip_white ();
p = POINT;
skip_chars ("0-9");
if ((p != POINT) and looking_at (". "))
{
go_down(1); bol (); skip_white ();
p = what_column ();
bol (); trim ();
whitespace (p + 3);
}
pop_spot ();
}
In fact, I always use this in text_mode so I put in in my
`text_mode_hook':
define text_mode_hook ()
{
set_buffer_hook ("wrap_hook", "text_mode_wrap_hook");
}