## 6 Using the GNU Emacs MFL Mode ¶

MFL sources are usual ASCII files and you may edit them with any editor you like. However, the best choice for this job (as well as for many others) is, without doubt, GNU Emacs. To ease the work of editing script files, the `mailfromd` package provides a special Emacs mode, called MFL mode.

The elisp source file providing this mode, `mfl-mode.el`, is installed automatically, provided that GNU Emacs is present on your machine. To enable the mode, add the following lines to your Emacs setup file (either system-wide `site-start.el`, or your personal one, `~/.emacs`):

    (autoload 'mfl-mode "mfl-mode")
    (setq auto-mode-alist (append auto-mode-alist
                           '(("\\.mfl$" . mfl-mode))))

The first directive loads the MFL mode, and the second one tells Emacs to apply it to any file whose name ends in ‘`.mfl`’ suffix.

MFL mode provides automatic indentation and syntax highlighting for MFL sources. The default indentation setup is the same as the one used throughout this book:

- Handler and function definitions start at column 1;
- A block statement, i.e. ‘`do`’, ‘`done`’, ‘`if`’, ‘`else`’, ‘`elif`’ and ‘`fi`’, occupies a line by itself, with the only exception that ‘`do`’ after an ‘`on`’ statement is located on the same line with it;
- A ‘`do`’ statement that follows function or handler definition is placed in column 1.
- Each subsequent level of nesting is indented two columns to the right (see mfl-basic-offset).
- A closing statement (‘`done`’, ‘`else`’, ‘`elif`’, ‘`fi`’) is placed at the same column as the corresponding opening statement;
- Branch statements (‘`case`’ and ‘`when`’) are placed in the same column as their controlling keyword (‘`switch`’ and ‘`on`’, correspondingly (see mfl-case-line-offset).
- Loop substatements (see Loop Statements) are offset 5 columns to the right from the controlling `loop` keyword. (see mfl-loop-statement-offset). Continuation statements within loop header are offset 5 columns from the indentation of their controlling keyword, either `for` or `while` (see mfl-loop-continuation-offset).

The mode provides two special commands that help navigate through the complex filter scripts:

`C-M-a`

  Move to the beginning of current function or handler definition.

`C-M-e`

  Move to the end of current function or handler definition.

Here, current function or handler means the one within which your cursor currently stays.

You can use `C-M-e` repeatedly to walk through all function and handler definitions in your script files. Similarly, repeatedly pressing `C-M-a` will visit all the definitions in the opposite direction (from the last up to the very first one).

Another special command, `C-c C-c`, allows to verify the syntax of your script file. This command runs `mailfromd` in syntax check mode (see Testing Filter Scripts) and displays its output in a secondary window, which allows to navigate through eventual diagnostic messages and to jump to source locations described by them.

All MFL mode settings are customizable. To change any of them, press `M-x customize` and visit ‘`Environment/Unix/Mfl`’ customization group. This group offers two subgroups: ‘`Mfl Lint group`’ and ‘`Mfl Indentation group`’.

‘`Mfl Lint group`’ controls invocation of mailfromd by `C-c C-c`. This group contains two variables:

MFL-mode setting: mfl-mailfromd-command ¶

  The `mailfromd` to be invoked. By default, it is ‘`mailfromd`’. You will have to change it, if `mailfromd` cannot be found using `PATH` environment variable, or if you wish to pass it some special options. However, do not include `--lint` or `-I` options in this variable. The `--lint` option is given automatically, and include paths are controlled by `mfl-include-path` variable (see below).

MFL-mode setting: mfl-include-path ¶

  A list of directories to be appended to `mailfromd` include search path (see include search path). By default it is empty.

‘`Mfl Indentation group`’ controls automatic indentation of MFL scripts. This group contains the following settings:

MFL-mode setting: mfl-basic-offset ¶

  This variable sets the basic indentation increment. It is set to 2, by default, which corresponds to the following indentation style:

      prog envfrom
      do
        if $f = ""
          accept
        else
          ...
        fi
      done

MFL-mode setting: mfl-case-line-offset ¶

  Indentation offset for `case` and `when` lines, relative to the column of their controlling keyword. The default is 0, i.e.:

      switch x
      do
      case 0:
        ...
      default:
        ...
      done

MFL-mode setting: mfl-returns-offset ¶

  Indentation offset of `returns` and `alias` statements, relative to the controlling `func` keyword. The default value is 2, which corresponds to:

      func foo()
        alias bar
        returns string

MFL-mode setting: mfl-comment-offset ¶

  Indentation increment for multi-line comments. The default value is 1, which makes:

         /* first comment line
            second comment line */

MFL-mode setting: mfl-loop-statement-offset ¶

  Indentation increment for parts of a `loop` statement. The default value is 5, which corresponds to the following style:

      loop for stmt,
           while cond,
           incr
      do

MFL-mode setting: mfl-loop-continuation-offset ¶

  If any of the `loop` parts occupies several lines, the indentation of continuation lines relative to the first line is controlled by `mfl-loop-continuation-offset`, which defaults to 5:

      loop for set n 0
                set z 1,
           while n != 10
                or z != 2,
           set n n + 1