# add-file-hook(2)

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

## NAME

add-file-hook - Declare file name context dependent configuration

## SYNOPSIS

n add-file-hook "extensions" "fhook-name"

## DESCRIPTION

add-file-hook defines a macro binding between a file name or file type and a set of macros. This binding enables file type dependent screen highlighting and key bindings to be performed. For a higher level introduction refer to File Hooks.

add-file-hook operates in two different modes to establish the type of file:-

- Content recognition, by examination of the contents of the file.
- File extension recognition.

Content recognition has the highest priority and is used in preference to the file extension.

add-file-hook is called multiple times to add new recognition rules. The rules are interrogated in last-in-first-out (LIFO) order, hence the extension added last has a greater precedence than those added first. This ordering allows default rules to be over-ridden.

## Initialization

add-file-hook must be initialized prior to the first call, using an invocation of the form:-

    0 add-file-hook

with a numeric argument n of 0, and no arguments. This invocation resets the file hooks by deleting all of the installed hooks.

## File Extension Recognition

add-file-hook with no numerical argument n allows the extension of a file (or the base file name if there is no extension) to be used to determine which user defined setup macro is to be executed. The extensions argument is a space separated list of file endings (as opposed to true extensions) and is usually specified with the extension separator. For example, the extension "`.doc`" may indicate that the file is a document and therefore the indent, wrap and justify buffer modes are required. This may be performed automatically by defining a macro which adds these modes and adding a file hook to automatically execute this macro whenever a file "`*.doc`" is loaded.

The command arguments are defined as follows:-

extensions

A space separated list of file extensions, which are to be checked, this list includes the extension separator (typically dot ('`.`'). It should be noted that the extension search is actually a comparison of the tail of the string, as such files such as makefile, which do not have an extension, are specified literally.

fhook-name

The name of the file hook to execute. This is the name of the macro to execute that initializes the buffer.

As an example:-

    define-macro fhook-doc
        1 buffer-mode "indent"
        1 buffer-mode "wrap"
        1 buffer-mode "justify"
    !emacro

    add-file-hook ".doc" "fhook-doc"

It is quite possible that the same macro should be executed for a text file, i.e. "`*.txt`" this is achieved by a single add-file-hook as the space (' ') character is used as an extension separator, e.g.

    add-file-hook ".doc .txt" "fhook-doc"

There are three special file hooks, which are fhook-binary, fhook-rbin and fhook-default, these are not predefined, but if the user defines them then they are executed whenever a file is loaded in binary or reduced binary mode (see buffer-mode(2)) or the extension does not match any of those defined.

Considering the `fhook-XXX` prefix, the initial 'f' character must be present as this is changed to a 'b' and an 'e' when looking for the enter (begin) buffer and exit buffer hooks. These hooks are executed whenever the user swaps to or from a buffer (including creating and deleting). So for the given example, if the fill ignore characters are to be changed then this operation this is performed by defining the `bhook-XXX` and `ehook-XXX` macros, e.g.:-

    ; Begin hook - entering the buffer - save the current fill-ignore characters
    define-macro bhook-java
        !if &exi .fhook-java.fill-ignore
            set-variable .fhook-java.ofill-ignore $fill-ignore
            set-variable $fill-ignore .fhook-java.fill-ignore
        !endif
    !emacro

    ; End hook - leaving the buffer - restore the fill-ignore characters
    define-macro ehook-java
        !if &exi .fhook-java.fill-ignore
            set-variable $fill-ignore .fhook-java.ofill-ignore
        !endif
    !emacro

    ; Fix up the $fill-mode so that we wrap java doc parameters. Do this by
    ; removing the "@" from the $fill-ignore variable.
    !if &sin "@" $fill-ignore
        set-variable .fhook-java.fill-ignore $fill-ignore
        set-variable .fhook-java.fill-ignore &rep .fhook-java.fill-ignore "@" ""
    !endif

File hooks are often used to setup the desired buffer modes, hilighting, local key bindings, abbreviation file, etc.

Buffer hooks are usually used to set and restore conflicting global variables.

## File Content Recognition

add-file-hook with a non-zero numerical argument n defines a macro binding between the content in a file and a set of macros. This binding enables file type dependent screen hi-lighting and key binding to be performed. For a full description of file hooks refer to File Hooks, for file extension dependent hooking refer to add-file-hook(2).

The content defined file hooks interrogate the contents of a file on loading and search for a magic string identifier embedded in the text which uniquely identifies the file type.

The recognition process performs a search of the first n (numerical argument) non-blank lines of the file, searching for the regular expression specified by the extensions argument. The sign of the numerical argument n is interpreted as follows:-

- -ve - Case insensitive search
- +ve - Case sensitive search

The command arguments are defined as follows:-

extensions

A regular expression string defining the text to be searched for.

fhook-name

The name of the file hook to execute. This is the name of the macro to execute that will initialize the buffer.

The search commences from the first non-blank line in the file, if the regular expression, defined by extensions is located then the file hook fhook-name is invoked. This is typically used to identify files which do not have file extensions i.e. UNIX shell script files. To identify a shell script file which commences with:-

    #!/bin/sh

The following file hook is used:-

1 add-file-hook "#!/.*sh" "fhook-shell"

Note that "`.*sh`" also matches `/bin/csh`, `/usr/local/bin/zsh` etc, so care should be taken to ensure that the regular expression string is sufficiently well specified to recognize the file type.

The second class of embedded text are explicit identifiers embedded into the text. The embedded strings take the form:

`-*-` mode `-*`
`-*-` Mode: mode; ... `-*-`
`-!-` mode `-!-`

The `-*-` notation belongs to GNU Emacs, but MicroEmacs 2009 recognizes the construct and extracts the string correctly. The `-!-` notation is MicroEmacs 2009 specific and is provided so as not to cause conflict with GNU Emacs. MicroEmacs 2009 searches for either construct on the first non-blank line of the file.

The explicit strings are defined with a negative numerical argument n, which identifies them as explicit rather than magic text strings. The string should be defined in lower case and matches a case insensitive string take from the file. e.g. to define a file hook for a make file:

    #_____________________________-!-Makefile-!-________________________________
    #
    # Make file for MicroEmacs using the Microsoft MSCV 2.0/4.0 development kit.
    #
    # Author      : Jon Green
    # Created     :  020197.1002
    # Last Edited : <150297.1942>
    # File        : makefile.w32
    ....

might be defined as:

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

## NOTES

## Automatic Macro File Loading

add-file-hook performs an automatic load of a macro file if the fhook macro is not present in memory. The file name of the command file containing the macro is automatically derived from the name component of the fhook macro name. The fhook- part of the name is stripped off and prepended with hk and suffixed with .emf. Hence, macro fhook-doc would be searched for in file `hkdoc.emf` within the MicroEmacs 2009 directory. The command file is automatically loaded and executed.

In cases where the fhook macro is not located in an equivalent hook file, the file location of the macro may be explicitly defined for auto loading via a define-macro-file(2) invocation.

As an example, consider the C-mode file hook, used to load `.c` files. The loading of a C header file (`.h`) utilizes the same highlighting modes, but it's startup sequence is slightly different when handling new files. In this case the fhook-cmode for `.c` and fhook-hmode for `.h` files are located in the same hook file namely `hkcmode.emf`.

    define-macro-file hkcmode fhook-hmode

    add-file-hook ".c .cc .cpp .def .l .y .i .ac"   "fhook-cmode"
    add-file-hook ".h .hpp"                         "fhook-hmode"

In this case the define-macro-file has been used to inform MicroEmacs 2009 of the location of the fhook-hmode macro thereby overriding the automatic load of a file called hkhmode.emf. The fhook-cmode macro requires no such definition as it is located in a hook file that matches the mode name, `hkcmode.emf`.

## Extending a standard hook definition

The standard file hook files hk XXX.emf should not be modified. The standard file hooks may be extended with local definitions by defining a file my XXX.emf, which is an extension to the hook file hk XXX.emf. This is automatically executed after hk XXX.emf. Refer to sections Language Templates and File Hooks for details.

## File Extensions

The file extensions are specified as a space separated list of file name endings. Back-up file endings such as tilde (`~`) are not classed as correct file endings and are skipped by the file hook search, hence a file ending "`.c~`" invokes the same hook function as a "`.c`" file. It is therefore not necessary to add the backup and auto-save endings to the file hook definition.

The extension separator, usually dot (`.`), is typically added to the extensions list, they may be omitted with effect where a file always ends in the same set of characters. A notable example is "`makefile`" which includes no extension, as such, MicroEmacs 2009 applies the same hook function to a file called `Imakefile` as the endings are the same.

## Binary Files

It is sometimes useful to associate file types as binary files, so that they are immediately loaded in binary. In this case, both file extension and content recognition methods (i.e. of a magic string) are applicable. In both cases the file is bound to the well known hook `fhook-binary` which automatically loads the file in a binary mode.

Note, that for the content recognition process for a binary hook, the load time is doubled as the file is initially loaded in the default text mode, the binary hook function forces a second load operation in binary.

## SUMMARY

add-file-hook is summarized as follows:-

- Binds one or more extensions to a macro called fhook-xxxx.
- Extensions are typically specified with the dot (`.`) separator.
- Multiple extensions are specified as a space separated list.
- Binds a regular expression search string to a macro called fhook-xxxx.
- The absolute value of the numerical argument determines the number of lines in the file over which the regular expression search is made.
- The sign of the numerical argument determines if the regular expression search is case (in)sensitive.
- When one of the files with a known file extension, or recognized content, is loaded macro fhook-xxxx is executed.
- fhook-xxxx, if undefined, is automatically searched for in file hk xxxx.emf.
- When the buffer containing the known file is entered (i.e. gains focus), then entry macro bhook-xxxx is executed.
- When the buffer containing the known file is exited (i.e. looses focus), then the exit macro ehook-xxxx is executed.

## EXAMPLE

The standard set of supported file types by MicroEmacs 2009, at the time of writing, is defined as:-

    ; reset the file hook list
    0 add-file-hook
    ; Add file extension hooks.
    ; Files loaded in binary mode do not need hook as fixed
    add-file-hook "*help* *info* .ehf"                            fhook-ehf
    add-file-hook "*bindings* *commands* *variables*"             fhook-lists
    add-file-hook "*buffers*"                                     fhook-blist
    add-file-hook "/ *directory* *files*"                         fhook-dir
    add-file-hook "*registry*"                                    fhook-reg
    add-file-hook "*icommand* *shell* *gdb* *dbx*"                fhook-ipipe
    add-file-hook ".emf"                                          fhook-emf
    add-file-hook ".doc .txt"                                     fhook-doc
    add-file-hook ".1 .2 .3 .4 .5 .6 .7 .8 .9 .so .tni .sm"       fhook-nroff
    add-file-hook ".c .h .def .l .y .i"                           fhook-c
    add-file-hook ".cc .cpp .hpp .rc"                             fhook-cpp
    add-file-hook "Makefile makefile .mak"                        fhook-make
    add-file-hook "Imakefile imakefile"                           fhook-imake
    add-file-hook ".sh .ksh .csh .login .cshrc .profile .tcshrc"  fhook-shell
    add-file-hook ".bat .btm"                                     fhook-dos
    add-file-hook ".man"                                          fhook-man
    add-file-hook ".dmn"                                          fhook-dman
    add-file-hook ".ini .hpj .reg .rgy"                           fhook-ini
    add-file-hook ".htm .html"                                    fhook-html
    add-file-hook ".htp .hts"                                     fhook-hts
    add-file-hook ".tcl"                                          fhook-tcl
    add-file-hook ".rul"                                          fhook-rul
    add-file-hook ".awk .nawk .gawk"                              fhook-awk
    add-file-hook ".p .pas"                                       fhook-pascal
    add-file-hook ".vhdl .vhd"                                    fhook-vhdl
    add-file-hook ".fvwm .fvwm2rc"                                fhook-fvwm
    add-file-hook ".java .jav"                                    fhook-java
    add-file-hook ".nsr"                                          fhook-nsr
    add-file-hook ".erf"                                          fhook-erf
    ; Add magic hooks
     1 add-file-hook "^#!/.*sh"               fhook-shell ; UNIX shell files
     1 add-file-hook "^#!/.*wish"             fhook-tcl
     1 add-file-hook "^#!/.*awk"              fhook-awk
     1 add-file-hook "^#VRML"                 fhook-vrml
    -4 add-file-hook "<html>"                 fhook-html
    -1 add-file-hook "-[*!]-[ \t]*c.*-[*!]-"         fhook-c     ; -*- C -*-
    -1 add-file-hook "-[*!]-[ \t]*c\\+\\+.*-[*!]-"   fhook-cpp   ; -*- C++ -*-
    -1 add-file-hook "-[*!]-[ \t]nroff.*-[*!]-"      fhook-nroff ; -*- nroff -*-
    -1 add-file-hook "-!-[ \t]*shell.*-!-"           fhook-shell ; -!- shell -!-
    -1 add-file-hook "-!-[ \t]*msdos.*-!-"           fhook-dos   ; -!- msdos -!-
    -1 add-file-hook "-!-[ \t]*makefile.*-!-"        fhook-make  ; -!- makefile -!-
    -1 add-file-hook "-!-[ \t]*document.*-!-"        fhook-doc   ; -!- document -!-
    -1 add-file-hook "-!-[ \t]*fvwm.*-!-"            fhook-fvwm  ; -!- fvwm -!-
    -1 add-file-hook "-!-[ \t]*erf.*-!-"             fhook-erf   ; -!- erf -!-
    -1 add-file-hook "-!-[ \t]*fold:.*-!-"           fhook-fold  ; -!- fold:... -!-

## OBSCURE INFORMATION

This section includes some low-level information which is so obscure it is not relevant to the typical user.

## Resolving Loading Order Problems

There is a potential loading order problem involving auto-loading of file libraries and the setting up of bhook and ehook. E.g. if the main fhook function has been defined as a define-macro-file(2), but the bhook or ehooks have not the when a buffer is created as only the fhook is define, only the fhook is set, the rest remain disabled even though the execution of the macro file will define these extra hooks.

To solve this problem simply define the bhook/ehooks as well. Note that automatically loaded hooks do not suffer from this problem as the macro file is executed before the hooks are assigned, thereby ensuring the all the hooks are defined.

## SEE ALSO

File Hooks, Language Templates, $buffer-bhook(5), $buffer-ehook(5), $buffer-fhook(5).

(c) Copyright JASSPA 2009
Last Modified: 2009/09/23
Generated On: 2009/10/12

</HMTL>