<title>Plugins</title>

<h1>Introduction</h1>

Eskil provides a plugin system where a plugin can preprocess data
before being compared and displayed.

A plugin is a Tcl script that must follow a specific format.
Example plugins are included in the kit.
Dump one of the included plugins to see what it looks like.

When searching for a plugin "x", files "x" and "x.tcl" will
match. The search path is current directory, "plugins" directory,
the directory where Eskil is installed, "plugins" directory where
Eskil is installed, and also the internal "plugins" wrapped into Eskil.

<h1>Usage</h1>

The command line options for plugins are:
  *  -plugin plugin     : Use plugin
  *  -plugininfo info   : Pass info to plugin (plugin specific)
  *  -plugindump plugin : Dump plugin source to stdout
  *  -pluginlist        : List known plugins

<h1>General Format</h1>

A plugin is a Tcl script file that must start with the verbatim sequence
"##Eskil Plugin :". A plugin is sourced and used in its own safe
interpreter and thus have free access to its own global space. Hookup
points are defined by declaring specifically named procedures as specified
below, and apart from those, a plugin can define and do whatever within
the limits of a safe interpreter.

In addition to the standard safe interpreter environment, a plugin has
access to stdout as well. By using the command line option -pluginallow,
the plugin is run in a standard interpreter and may e.g. do exec to utilize
external tools.

A plugin is set up with these global variables filled in:
  *  ::WhoAmI : The name of the plugin
  *  ::Info   : The contents of -plugininfo parameter
  *  ::Pref   : A copy if Eskil's internal preferences array.
  *  ::argv   : A copy of the command line from Eskil's invocation

<h1>File plugin</h1>

To process the files being compared, the following procedure should be
defined in the plugin file:

<pre>proc PreProcess {side chi cho} {...}</pre>

The arguments given to PrePrecess are:

  *  side : left or right, indicating which file is being handled
  *  chi : An input channel for reading the original file
  *  cho : An output channel for writing the processed file

A plugin may give a result that has a line-by-line correspondence to
the original, in which case the preprocessed data is used for comparing
while the original is used for displaying.  The PreProcess procedure
should return 0 to signify this case.

If the PreProcess procedure returns 1, the processed data is used also for
displaying.

If Eskil is run with Tcl 8.6 or newer, PreProcess is run as a couroutine
and may yield. The left and right side will then be called alternately
until they return. This allows a plugin to take both sides into account
for decisions if needed.

<h1>Directory plugin</h1>

To be used for file comparison in a directory diff, the following procedure
should be defined in the plugin file:

<pre>proc FileCompare {ch1 ch2 info1 info2} {...}</pre>

The arguments given to FileCompare are:

  *  ch1:  An input channel for reading the first file.
  *  ch2:  An input channel for reading the second file.
  *  info1: A dictionary with info about the first file.
  *  info2: A dictionary with info about the second file.

Info dictionaries contain at least elements "name" and "size".

The FileCompare procedure can give the following return values:

  *  0 : Files are not equal
  *  1 : Files are equal
  *  2 : Files are equal as far as the channels have been read.
         Let the normal comparison finish the job.





