# fileHooks(2)

[Home] [Commands] [Variables] [Macro-Dev] [Glossary]

## FILE HOOKS

File hooks provide a mechanism to automatically invoke a set of macros for a given buffer type when the following events occur:

- Loading of a file into a buffer
- Moving into a buffer (i.e. making a buffer current)
- Moving out of a buffer (i.e. making another buffer current)
- Deleting an active buffer

The file hook selection (see below) is performed on the file name / extension and on the textual content of the buffer using add-file-hook.

Refer to Language Templates for a description of how the file hooks are used to define a new template for a new text format.

The hook macros allow buffer modes and highlighting, applicable to the text type of the file, to be applied to the buffer. In addition, the associated hook macros may be located in a separate file and are loaded on demand when the file reading determines that a set of hook macros are required.

Consider a file hook definition of the form;

    add-file-hook ".c .h" "fhook-c"

which binds the file hook fhook-c to any files that are loaded with the extension .c and .h. The operations undertaken by MicroEmacs 2009 are defined as follows when a file `foo.c` is loaded:-

- Attempt to load file `foo.c`, if `foo.c` is not found then create a new buffer and assign file name `foo.c`.

- If `foo.c` is found then load file into buffer. Search the first line(s) of the buffer for magic hook text (add-file-hook with argument).

- If magic hook was not found then determine hook name from the file extension (add-file-hook information).

- If a hook command is located, assign the file hook fhook-c to the buffer, assign the buffer entry (begin) hook macro of bhook-c; assign a buffer exit hook of ehook-c.

- If the macro fhook-c is undefined then execute the macro file hkc.emf from the MicroEmacs home directory in an attempt to load the macro. If the file myc.emf is defined, then the modifications to the language template are applied after hkc.emf is loaded.

- If the macro fhook-c is (now) defined then `foo.c` is TEMPORARILY made the current buffer and the file hook macro fhook-c is executed to completion and the previous current buffer is restored. [TEMPORARY here implies that no buffer hooks are executed on the flip in/out of `foo.c`].

- The current buffer is officially swapped to `foo.c`. At this point the ehook of the old current buffer is executed (while its still current) and then `foo.c` is swapped in to become the current buffer; the begin buffer hook bhook-cmode is then executed for `foo.c` (if it exists).

- If the user moves to another buffer execute the end hook macro ehook-cmode (if it exists) and move to the new buffer, executing it's begin hook.

- If the user subsequently returns to buffer `foo.c` execute the previous buffers end hook macro, set the current buffer to foo.c and execute the begin hook macro bhook-c (if it exists).

- If the user kills buffer `foo.c`, if `foo.c` is the current buffer then an alternative buffer is made current, `ehook` and `bhook` executed as normal. If macro dhook-c is defined then `foo.c` is TEMPORARILY made the current buffer and the delete hook macro dhook-c is executed to completion and the previous current buffer is restored.

The name of the file hook macro name is important, hook commands must commence with the text fhook-mode where mode is an identifier for the operating mode. The name space is decomposed as follows:-

- The initial f is removed and replaced with b for the begin hook macro and e for the end hook macro.

- When the fhook macro is undefined the mode component is removed and the file hk mode.emf is executed from the MicroEmacs home directory in an attempt to define the macro.

The fhook- nomenclature may be omitted provided that the name is less than 6 characters, however the file, begin and end hook macros MUST commence with f, b and e respectively. In addition the macros must be defined as no auto file loading is performed.

## Buffer Hook Variables

The macros bound to a buffer may be interrogated, the variables $buffer-fhook(5), $buffer-bhook(5), $buffer-ehook(5) and $buffer-dhook(5) contain the names of any associated macro attached as a macro hooks, defining the file, begin, end and delete hooks respectively. If a macro is not bound then the empty string `""` is returned. Setting the variables has the effect of defining the hook and is a method by which the buffer hooks may be affected after the buffer has been loaded.

## Determination of a new file

The file hook fhook-XXX numeric argument may be used to determine if the file associated with a buffer is a new file created by the user, or an existing file. Typically this distinction is used to determine whether a boiler template is added to the file or not. The macro argument @# is defined as zero (0) if this is a new file that has been created, or non-zero otherwise.

The macro argument status is typically tested on entry to the macro as follows:-

    define-macro fhook-mode
        !if &not @#
            ; This is a new file. Do new file things
        !else
            ; This is an existing file
        !endif
        ; Set up bindings
    !emacro

An example of a generic hook file is given at the end of this section which elaborates on the file hooks.

## Begin and End hooks

The begin and end hooks are usually used to save and restore global states which require special settings for a particular buffer type. This typically involves saving and restoring global variables which are used by other buffers in a different configuration. For example the following is used to reformat the time stamp string; the time stamp is a global variable $timestamp(5) and if it is changed in one buffer, it must be restored ready for another. In this case the old time stamp is retained in a local buffer variable whenever the buffer is entered, the time stamp is then modified for the buffers requirements. On exit from the buffer the old time stamp format is restored to it's former state.

    0 define-macro bhook-foo
        set-variable .timestamp $timestamp      ; Save old time stamp.
        set-variable $timestamp "19%Y/%M/%D %h:%m:%s"
    !emacro

    0 define-macro ehook-foo
        set-variable $timestamp .bhook-foo.timestamp
    !emacro

Note that in both cases the define-macro(2) invocation is defined as zero, this merely hides the macro from the command line since both are private macros not normally invoked by the user.

## FILE HOOK SELECTION

MicroEmacs 2009 may be reconfigured to operate in different modes (referred to a Major Modes in GNU emacs(1)) using the macro file hooks. The file hooks allow the working environment to be customized for the editing of text of a particular sort, by importing text specific macros, key rebinding and highlighting.

MicroEmacs 2009, by default, loads a file into a buffer with default global modes with no highlighting. There are no mode specific key bindings, variable settings, macros or highlights, buffer interaction behaves in it's default state. The state of the buffer interaction may be modified through the use of the buffer modes (see Operating Modes), for example the 'C' programming language automatic indent indent(2) changes the characteristics of the `tab` character and performs language specific indentation of statements. When a text specific set of highlighting rules are applied to the buffer, the text becomes emphasized through the use of color applied selectively to the text i.e. comments, keywords, strings are shown in different colors, allowing them to be differentiated without studying the content.

Setting the operating mode of the buffer would be tedious to perform from the command line, instead MicroEmacs 2009 uses three different prioritized criteria to endeavor to select the correct operating mode. The operating mode is applied to the buffer by execution of a set of file specific macros, referred to a hook commands. The selection criteria of the hook commands is performed as follows, ordered in lowest to highest priority:-

File Name

MicroEmacs 2009 uses the filename and/or the file extension to select a start-up hook command. File names and extensions are bound to a set of macro hooks in a space separated list e.g.

add-file-hook "c cpp" "fhook-cmode"
add-file-hook "doc txt README" "fhook-doc"

The space separated list of names are interpreted as either file extensions or filenames. In this case any file with the extension .c, .cpp is bound to a file hook called fhook-cmode e.g. `foo.c`. Similarly files with the extension .doc or .txt are interpreted as plain text documents and are bound to fhook-doc. e.g. `foo.txt`. The entry README that exists in the documentation hook list may refer to a file `README` and also `foo.README`, both cases invoke the document hook.

The file selection is the lowest priority selection criteria but usually satisfies most mode selection requirements.

Magic Strings

There are cases when file extensions may be omitted from files, typically these files include an identifier, or magic string, on the first line of the file which is used to identify the file to the operating system or application e.g. shell scripts under UNIX. MicroEmacs 2009 automatically interrogates the top of every file that is loaded to locate some form of identification string. The identification strings are defined in a similar way to the file name hooks, except instead of defining a file extension the location and text content of the identifier is defined:

1 add-file-hook "#!/bin/sh" "fhook-shell"
1 add-file-hook "#!/usr/local/bin/wish" "fhook-tcl"

In this case, any file that commences with "#!/bin/sh" is interpreted as a shell script and invokes the shell hook fhook-shell. Where the identifier does not appear on the first non-blank line, the argument may be increased to the number of lines to be searched. Also it the magic sting should be search for without exact(2m) mode then the argument should be negated, e.g.

-4 add-file-hook "<html>" "fhook-html"

invokes fhook-html whenever "`<html>`", "`<HTML>`" etc. is found in the first 4 lines of a file header, e.g.:

    <!-- Comment line -->
    <HtMl>

A match on a string identifier is assigned a higher priority than the file extension. It is recommended that magic strings are only used where there are no predefined file extensions, or conflicts exist between files with the same extension containing data interpreted in a different context.

Explicit Strings

The last method allows an explicit identifier string to be embedded into the text of the file informing MicroEmacs 2009 which mode it should adopt. GNU Emacs supports this (see Major Mode in the GNU Emacs documentation) type of operation by insertion of strings of the form:

-*- mode -*-

Where mode represents the major mode within GNU Emacs. The same format as used by Magic Strings can be used to find and extract the mode, e.g.:

-1 add-file-hook "-[*!]-[ \t]nroff.*-[*!]-" "fhook-nroff"

The definition would detect the GNU Emacs mode defined in an Nroff file e.g.

.\" -*- nroff -*- "
.TH man 1
.SH NAME
...

It should be stressed that the -*- syntax belongs to GNU Emacs and NOT MicroEmacs 2009, MicroEmacs 2009 provides a mechanism to locate, extract and interpret the string. The -*- syntax should only be applied to files if it is known that the mode is a GNU mode.

A MicroEmacs 2009 specific string is also provided, defined as:

-!- mode -!-

where mode is an arbitrary string defined by add-file-hook. User defined modes may be created and assigned to files with this syntax, this does not conflict with the GNU Emacs command. For example to assign a new mode mymode to a file we would define the following:-

-1 add-file-hook "-!-[ \t]mymode.*-!-" "fhook-mymode"

Files containing a the following identifier would be loaded with mymode hook:

# -!- mymode -!-
#
# Last Modified: <120683.1014>

## FILE HOOK SCRIPTS

The buffer hook files hk name.emf typically follow a standard layout, and are generally associated with hi-lighting as follows, mode in this case is the name of the file mode associated with the file:-

    !if &seq .hilight.mode "ERROR"
        set-variable .hilight.mode &pinc .hilight.next 1
    !endif
    ;
    ; Define the hilighting
    ;
    0 hilight .hilight.mode 1                $global-scheme
    hilight .hilight.mode 2 "\*\*"           .scheme.comment
    hilight .hilight.mode 4 "\"" "\"" "\\"   .scheme.string
    hilight .hilight.mode 0 "'.'"            .scheme.quote

    hilight .hilight.mode 1 "if"             .scheme.keyword
    hilight .hilight.mode 1 "elif"           .scheme.keyword
    hilight .hilight.mode 1 "else"           .scheme.keyword
    ...

    ; Reset the hilighting printer format and define the color bindings.
    0 hilight-print .hilight.mode
    hilight-print .hilight.mode "i"  .scheme.comment
    hilight-print .hilight.mode "b"  .scheme.keyword .scheme.variable
    hilight-print .hilight.mode "bi" .scheme.string .scheme.quote
    ...

    ; Define the indentation tokens
    0 indent  .hilight.mode 2 10
    indent .hilight.mode n "if" 4
    indent .hilight.mode s "elif" -4
    indent .hilight.mode s "else" -4
    indent .hilight.mode o "endif" -4
    indent .hilight.mode n "while" 4
    ...

    define-macro fhook-mode
        ; if arg is 0 this is a new file so add template
        !if &not @#
            etfinsrt "mode"
        !endif
        set-variable $buffer-hilight .hilight.mode
        set-variable $buffer-indent .hilight.mode
        1 buffer-mode "time"
        1 buffer-mode "indent"
        buffer-abbrev-file "mode"
    !emacro

The previous example shows how the fhook-mode numeric argument is used to determine if this is a new file. If the argument @# is zero then this is interpreted as a new file, in this case a standard template is inserted (from file mode.etf) and the generic strings such as `$YEAR$` replaced with construction information. The template is generally used for standard headers and skeleton text body.

In addition an abbreviation file mode.eaf (see eaf(8)) is bound to the buffer using the buffer-abbrev-file(2) command and the buffer hi-lighting enabled by assignment of the $buffer-hilight(5) variable.

## MODIFYING FILE HOOKS

The standard hook files supplied with MicroEmacs 2009 should not be modified, changes to the file hooks may be applied using a separate macro file called my XXX.emf, this is automatically executed after the hk XXX.emf file is executed.

The extended hook functions may be defined company wide, or by the user, to over-ride some of the standard hook functions, or to extend the syntax of the base files with locally defined extensions. As an example, consider the following file myc.emf which extends the basic hkc.emf file set of hi-lighting tokens for the 'C' Language.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ;  Created By    : Steven Phillips
    ;  Created       : Thu Jun 18 15:34:05 1998
    ;  Last Modified : <230798.0854>
    ;
    ;  Description   Extension hilighting for the 'C' language.
    ;
    ;  Notes         Define the locally defined 'C' library types and definitions
    ;                as extensions to the 'C' programming language.
    ;
    ;  History
    ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ; MicroEmacs specific tokens
    hilight .hilight.c 1 "LINE"           .scheme.type
    hilight .hilight.c 1 "BUFFER"         .scheme.type
    hilight .hilight.c 1 "WINDOW"         .scheme.type
    hilight .hilight.c 1 "REGION"         .scheme.type
    hilight .hilight.c 1 "KEYTAB"         .scheme.type
    hilight .hilight.c 1 "KILL"           .scheme.type
    hilight .hilight.c 1 "KLIST"          .scheme.type
    hilight .hilight.c 1 "HILNODE"        .scheme.type
    hilight .hilight.c 1 "HILNODEPTR"     .scheme.type
    hilight .hilight.c 1 "HILCOLOR"       .scheme.type
    hilight .hilight.c 1 "SELHILIGHT"     .scheme.type
    hilight .hilight.c 1 "VIDEO"          .scheme.type
    hilight .hilight.c 1 "VVIDEO"         .scheme.type
    hilight .hilight.c 1 "FRAMELINE"      .scheme.type
    hilight .hilight.c 1 "IPIPEBUF"       .scheme.type
    hilight .hilight.c 1 "DIRNODE"        .scheme.type
    hilight .hilight.c 1 "UNDOND"         .scheme.type
    hilight .hilight.c 1 "meVARLIST"      .scheme.type
    hilight .hilight.c 1 "meVARIABLE"     .scheme.type
    hilight .hilight.c 1 "meCMD"          .scheme.type
    hilight .hilight.c 1 "meAMARK"        .scheme.type
    hilight .hilight.c 1 "meABREV"        .scheme.type
    hilight .hilight.c 1 "meMACRO"        .scheme.type
    hilight .hilight.c 1 "meNARROW"       .scheme.type
    hilight .hilight.c 1 "meREGISTERS"    .scheme.type
    hilight .hilight.c 1 "meSTAT"         .scheme.type
    hilight .hilight.c 1 "osdITEM"        .scheme.type
    hilight .hilight.c 1 "osdDIALOG"      .scheme.type
    hilight .hilight.c 1 "osdCHILD"       .scheme.type
    hilight .hilight.c 1 "meSCROLLBAR"    .scheme.type
    hilight .hilight.c 1 "osdCONTEXT"     .scheme.type
    hilight .hilight.c 1 "osdDISPLAY"     .scheme.type
    hilight .hilight.c 1 "RNODE"          .scheme.type
    hilight .hilight.c 1 "REGHANDLE"      .scheme.type
    hilight .hilight.c 1 "meDIRLIST"      .scheme.type
    hilight .hilight.c 1 "meNAMESVAR"     .scheme.type
    hilight .hilight.c 1 "meDICTADDR"     .scheme.type
    hilight .hilight.c 1 "meSPELLRULE"    .scheme.type
    hilight .hilight.c 1 "meDICTWORD"     .scheme.type
    hilight .hilight.c 1 "meDICTIONARY"   .scheme.type
    hilight .hilight.c 1 "meMODE"         .scheme.type

## SEE ALSO

Operating Modes, Language Templates, add-file-hook(2), indent(2).

(c) Copyright JASSPA 2009
Last Modified: 2009/08/29
Generated On: 2009/10/12

</HMTL>