Script-Fu Programmer’s Reference

About

This describes Script-Fu, a language for scripting or writing plugins for the GIMP application. This is a reference, not a tutorial.

Audience

Authors of GIMP plugins that use the Script-Fu language.

Disambiguation

Script-Fu can refer to the language or the system that implements it. Script-Fu the system has several associated tools, notably the Script-Fu Console which is a GUI REPL to execute short scripts. Many scripts in the Script-Fu language are distributed with GIMP and implement some menu items in GIMP.

Alternatives

You can write GIMP plugins in other languages such as C, Python, Lua, and Vala. In any language that supports GObject Introspection.

Versions

This documents version 3 of Script-Fu, with notes where it differs from version 2.

Script-Fu itself has not changed much in GIMP version 3, but the bound PDB API has. Thus many scripts that worked in GIMP version 2 will need porting to work in GIMP version3. Porting is usually simple, requiring a few name changes and a few signature changes to calls to PDB procedures.

A document explains the changes needed to port a script from GIMP version 2 to 3.

References to underlying languages

Script-Fu language is a dialect or extension of underlying languages. This documents what is atop or special or different from the underlying languages. See also:

The procedures in the GIMP Programmers Data Base (PDB) are callable in the Script-Fu language. To explore the PDB, use the PDB Browser in the GIMP app.

Overview

Script-Fu is a language and a set of tools for programming plugins of the GIMP application.

What is a GIMP plugin?

A plugin is a program that extends the GIMP application. You can only launch plugins from within the GIMP app. You can use Script-Fu to write plugins for GIMP.

Some plugins appear as menu items in the GIMP app. Many plugins are “filters” that alter an image.

Other plugins save or load image files of different formats. Such plugins are usually written in C.

Other plugins are “apps” that are long-lived and show windows for tasks. For example, the PDB Browser and the Script-Fu Console, which help authors of Script-Fu scripts. Such plugins are often written in C.

Script-Fu interpreters

The Script-Fu language is interpreted. An embedded interpreter underlies each plugin written in Script-Fu.

Since the language is interpreted, there is no compilation step. There is an install and registration step. Installation is just copying a script file to a certain directory. Registration happens when GIMP runs and queries the files in the directory. Registration enters the plugin in the PDB as a procedure.

Since GIMP 3, there is a separate executable program called “the Script-Fu interpreter” just as there is “the Python interpreter.” But many of the Script-Fu tools also have an embedded interpreter and some plugins (those in the /scripts directory) are interpreted by the long-lived “Script-Fu extension” process.

Architecturally, the Script-Fu interpreter wraps another interpreter, the TinyScheme interpreter.

Script-Fu language derives from Lisp

Script-Fu interprets the TinyScheme dialect of the Scheme language, augmented by functions to call the GIMP PDB and augmented by functions to declare plugins.

TinyScheme language is a subset of the Scheme language defined by the RSR5 standard. TinyScheme lacks hygenic macros and some other features of the RSR5 standard.

Scheme language is a dialect of Lisp. Lisp is a functional programming language with support for imperative programming.

Plugin features and Script-Fu

Most plugins of GIMP have these features:

  • an optional GUI e.g. a dialog of settings for the plugin
  • settings (i.e. preferences i.e. defaults) persistent between runs of the plugin, even in different sessions of GIMP
  • a run mode i.e. interactive or non-interactive
  • exists in the PDB so it is callable by other plugins, browseable, and introspectable
  • can display progress and messages to the user

The Script-Fu system implements much of these features on behalf of a plugin written in Script-Fu. (In other language plugins, these features are inherited from a class: GIMP Plugin.)

This document does not describe in detail these general features of GIMP plugins, or the GIMP PDB. See elsewhere.

Templates for a Script-Fu plugin

Minimal, hello-world plugin

This is a minimal plugin:

(define (script-fu-basic-plug-in) (gimp-message " hello world "))
(script-fu-register "script-fu-basic-plug-in" "Basic" "test" "me" "free" "2023" "")
(script-fu-menu-register "script-fu-basic-plug-in" "<Image>/Fu-plug-in")

The first line defines the “run function” of the plugin. Here the run function has no arguments and just says “hello world.” You would craft a run function to do something useful.

The second and third lines are special functions of Script-Fu.

The second line declares metadata and the signature of the plugin. Here, the plugin has no arguments, and empty signature.

The third line declares the plugin’s appearance in the GIMP app menus, which is optional.

This text would be in a file named “hello-world.scm” installed in the /scripts directory.

Version 3 filter plugin

This is a minimal plugin in the new style of version 3:

#!/usr/bin/env gimp-script-fu-interpreter-3.0
(define (script-fu-basic-plug-in
          image
          drawables)
        (gimp-message " hello world "))
(script-fu-register-filter "script-fu-basic-plug-in" "Basic" "test" "me" "free" "2023" ""
                            SF-ONE-DRAWABLE)
(script-fu-menu-register "script-fu-basic-plug-in" "<Image>/Fu-plug-in")

One difference is the shebang in the first line. This means the standalone Script-Fu interpreter will interpret the script, independently from other plugins.

Another difference is the run function has formal arguments for the standard arguments for a filter: image and drawables, but the call to script-fu-register-filter does not declare them.

Another difference is the call to script-fu-register-filter has the argument SF-ONE-DRAWABLE to specify the capability of the plugin re multi layers. This example is contrived, because the plugin actually ignores the drawables and actually could work no matter how many layers the user selected.

This text would be in a file named “hello-world.scm” installed in the /plug-ins/hello-world directory (a directory having the same name as the plugin script file.) The file must have executable permissions.

Other example plugins

A more elaborate hello-world in the Gimp repo illustrates a version 3 plugin, installed to the /plug-ins directory and independently interpreted, but not registering as a filter.

A script in the Gimp repo illustrates all types of arguments that you can declare in the signature of a plugin and demonstrates the corresponding widgets.

Features of the Script-Fu language

These are features beyond simple Scheme or TinyScheme:

  • special functions to declare and define a GIMP plugin
  • binding to the GIMP PDB procedures for processing images
  • pre-defined symbols for GIMP constants i.e. enumerations
  • Unicode strings
  • i18n internationalization/localization of any GUI
  • ftx extension for filesystem operations
  • re extension for regular expressions
  • byte IO
  • a few functions not in Scheme, defined in the usual init.scm for a Scheme interpreter
  • other Scheme functions whose meaning is implementation dependant (e.g. quit)

Script-Fu special functions

The special functions are:

  • script-fu-register
  • script-fu-menu-register
  • script-fu-register-filter

These declare a plugin to the PDB. These functions are not in the Scheme language proper, and not in the PDB.

Calls to these functions are usually located at the end of a plugin script file.

They are implemented in C language and bound as foreign functions to Scheme.

The first argument to these functions is a string name. The name is the name of the plugin registered in the PDB, and must match the name of the run function defined in Scheme at the top of a script. The name must have prefix “script-fu-” else the plugin will fail to register.

The function script-fu-register-filter is new for version 3. It registers an “image procedure”, one that always receives the image and list of drawables that a GIMP user must have already selected. You don’t declare the image and drawables arguments in a call to script-fu-register-filter. Also, a plugin that registers by this function gets a GUI more similar to plugins in other languages (by the class GimpProcedureDialog.) You can only use script-fu-register-filter in new style plugin scripts.

The Script-Fu binding to the PDB

The binding from Scheme to GIMP is part of the Script-Fu system.

Unlike bindings for other languages of plugins (such as the Python binding) the binding is not automatic using GObject Introspection (GIR.) Instead, the binding is mostly hand-coded in C.

The binding defines a symbol into the Scheme language for each procedure in the GIMP PDB. (In other language bindings, the binding is to the similar libgimp.)

The binding also marshalls arguments to and return values from calls to the PDB. The binding marshalls C types to Lisp types and vice versa.

To understand the signatures of Script-Fu’s binding of calls to the PDB, read the C signatures in the PDB Browser and mentally convert to a Scheme type.

Most conversions of elementary types are natural. For example, a C integer converts to a Scheme numeric and a C string converts to a Scheme string.

A document in the Gimp repo describes other conversions from GIMP types to Scheme types.

Pre-defined symbols

Script-Fu defines many symbols over and above TinyScheme and Scheme.

These symbols are immutable and you cannot globally redefine them although you could redefine them in a let block.

Pre-defined symbols for GIMP constants i.e. enumerations

The Script-Fu language defines symbols for each enumeration value of the GIMP library and the GEGL library. You often pass these symbols as arguments to calls to the PDB. These symbols are in upper case. These symbols match the symbols in the respective libraries, except they omit the “GIMP_” or “GEGL_” prefix.

For example, RUN-INTERACTIVE is the symbol for one of the enumerated values in the GimpRunMode enumeration.

Script-Fu specific pre-defined symbols for constants

Script-Fu defines these symbols:

TRUE  alias for 1
FALSE alias for 0
NULL  alias for 0

These are C-isms that you should not use in new code.

Symbols for strings about the filesystem:

gimp-directory  the path to the directory where GIMP is installed, aka PREFIX
gimp-data-directory
gimp-plug-in-directory
gimp-locale-directory
gimp-sysconf-directory
DIR-SEPARATOR the ASCII character used as separator in filesystem paths, e.g. forward slash
SEARCHPATH-SEPARATOR the ASCII character used as separator in PATH lists, e.g. colon

The SF- enumeration of argument types

Script-Fu defines symbols used to declare types of arguments to a plugin. They are of the form “SF-xxx” e.g. SF-STRING. See “Signatures of Script-Fu Plugins”.

Script-Fu defines symbols SF-SLIDER and SF-SPINNER used to declare widget types for arguments of type SF-ADJUSTMENT.

The SF- enumeration of plugin capabilities

Since GIMP version 3, a plugin can declare its capabilities re whether it can process multiple drawables. Then a plugin’s menu item is enabled in the GIMP GUI only when the user has selected an appropriate count of drawables.

These only declare a contract, which an ill-behaved plugin might fail to fulfill. A well-behaved plugin should return an error when passed a list of drawables that doesn’t meet the contract.

SF-ONE-DRAWABLE         Requires exactly one drawable
SF-ONE-OR-MORE-DRAWABLE All drawables often processed independently,
                        sequentially, with side effects on the drawables.
SF-TWO-OR-MORE-DRAWABLE Requires two or more drawables. Often a binary operation
                        yielding a new drawable.

These are valid only for new-style, version 3 plugins that register by script-fu-register-filter.

Unicode support

Unlike some Scheme dialects and unlike the original TinyScheme itself, the Script-Fu interpreter implements Unicode strings.

All data of string type in Script-Fu are sequences of Unicode characters, i.e. wide characters. Script-Fu encodes Unicode character using UTF-8, so a character is one to three bytes.

The length of a string is the length in characters, not bytes.

In a Lisp script, you represent certain literals by a sharp constant.

In Script-Fu, you can represent Unicode characters by sharp character constants :

#\a

represents lower case ASCII “a”.

You can also represent Unicode characters by sharp numeric constants, for example:

#\x3bb

represents the two byte encoding of the Greek character called lambda, whose codepoint is hexadecimal 3bb.

Symbols are not Unicode but ASCII. (Here symbol has the Lisp meaning of a name in the script.) So a script’s text must be ASCII. Evaluation of string data that is Unicode might not work.

i18n internationalization/localization

In a Script-Fu plugin script, you can annotate a string literal for translation:

_"To be translated."

Any string literal so annotated will usually appear in the user’s native language in the GUI dialog for a plugin.

You only use this annotation in declarations of a plugin’s signature and the plugin’s appearance in the GIMP GUI.

(In Lisp terminology, the “_” character marks a special form that the Script-Fu interpreter recognizes. It is not in the form of a function call in Lisp.)

For internationalization to succeed, annotated plugins must be processed as follows. A translator must translate annotated strings, into a .po file. At install time, the translations must be installed.

Third-party annotated plugins won’t actually be translated unless the author follows a similar process and distributes translation files with the plugin script.

Translated strings are known in advance and fixed at distribution time. Script-Fu does not support translation of strings generated at run time.

ftx and re extensions

Script-Fu includes the ftx (OS and filesystem) and re (regular expression) extensions. An extension in Scheme is C code that defines more functions into the language.

See the gimp repo for more information:

Byte IO

Since characters are Unicode in Script-Fu, you can’t use characters as bytes. Since version 3, ScriptFu has functions to read and write streams a byte at a time.

Byte IO is not part of the RSR5 standard.

See the separate document on this site.

Other defined functions

Script-Fu has some functions not in Scheme and not specific to GIMP. Some are implemented in the TinyScheme interpreter itself, and some in Scheme scripts in the usual init.scm for a Scheme interpreter.

The print function is not in RSR5 but is defined in ScriptFu. It is a call to the display function on the current output stream, but adds a newline. (Probably for backward compatibility with scripts written in the SIOD dialect.)

The quit function is usually defined in Scheme but with implementation dependent meaning re a process. In Script-Fu, it stops evaluation of the script and returns the optional error-code argument to the caller of the plugin script. Note that it does not stop the execution of the Script-Fu extension process, only the evaluation of the current script. It does not stop the Script-Fu Console process.

The cond-eval function is defined but in a limited way. That function lets you evaluate conditionally on the prior loading of other Scheme modules following the SRFI conventions.

Signatures of Script-Fu plugins

You declare the signature of a Script-Fu plugin in a call to script-fu-register. (The call also declares other metadata of the plugin.) The signature is declared in a varying length suffix of the arguments to script-fu-register. Each in argument is declared in a sequence of three values.

For example:

(script-fu-register "script-fu-test-sphere"
  ... metadata arguments...
  SF-ADJUSTMENT "Radius (in pixels)" (list 100 1 5000 1 10 0 SF-SPINNER)
  ... more triples, one for each additional argument ...
)

The three values are:

  • an SF- constant
  • a string label to appear alongside a widget in the plugin’s dialog
  • a value that defines a default or further constrains the argument (a list for some argument types)

Declaring in arguments to a plugin

The SF- enumeration declares the type of a plugin argument. The corresponding type in Scheme and C is not well documented, but you can easily infer it. When you browse the PDB to study the signature of a plugin, you will see the declared types as the corresponding bound C types.

The SF- enumeration declares not only the type of the argument, but the kind of widget used in a dialog for the plugin. For example, SF-STRING and SF-TEXT yield argument of type string, but the first appears as a widget for entering a single line while the second appears appears as a widget for entering multiple lines.

Declaring resource arguments to a plugin

SF-BRUSH, SF-FONT, SF-GRADIENT, SF-PALETTE, and SF-PATTERN all specify an argument of type GIMP Resource. Resources are data installed with GIMP.

In ScriptFu, resources are represented by their integer ID’s. A script should treat these opaquely, receiving them and passing them unaltered to other functions.

In version 2, an SF-BRUSH triplet had a list for the third element of the triple. In version 3, Script-Fu only reads the first element of the list, the name of the brush.

A version 3 script that needs attributes of a brush should call methods of the brush. Version 2 scripts that used a brush may need porting.

Declaring GIMP type arguments to a plugin

Similarly, SF-IMAGE, SF-LAYER, SF-CHANNEL, SF-DRAWABLE, and SF-VECTORS all specify an argument having a GIMP object type.

In ScriptFu, GIMP objects are represented by their integer ID’s. That is, of Scheme type numeric. A script should treat these opaquely, receiving them and passing them unaltered to other functions.

When you declare an argument of the type GIMP object, the third argument is usually just an ignored place holder “-1”. Since object ID’s are not persistent you should not generally code integer literals for ID’s. Note that in a newly started GIMP app, the first opened image usually has ID 1, and you can use guessed integer literals in the Script-Fu Console.

SF-VALUE

SF-VALUE is deprecated and you should not use it in new code.

It yields a string type in Scheme. The corresponding widget lets the user enter any string. SF-VALUE does not imply a numeric value.

Correspondence of signature in PDB and run function definition

The declaration of a plugin’s signature describes both the signature registered in the PDB and the signature of the run function defined in Scheme at the top of a script. The signature of the defined run function must match, else you get a run time error.

Undeclared run mode argument

You don’t need to declare the run mode argument to a plugin. GIMP passes each plugin a first argument the run mode. You see that in the PDB Browser. But the signature of the run function in a Script-Fu script does not have a run mode argument. Script-Fu hides it from a script. A script does not need to know what the run mode is (since a script should not implement GUI directly) and if it calls other plugins (in the PDB), it should usually pass run mode NON-INTERACTIVE so the called plugin does not present its dialog.

Undeclared arguments to filter plugins

In a call to script-fu-register-filter (new to version 3) you also do not declare the image and drawables arguments to a plugin. All “filter” plugins receive these arguments implicitly. The defined run function signature must have those formal arguments, and the PDB Browser will show those arguments. You just don’t need to declare triplets for them.

Return values

Plugins written in Script-Fu language do not return a value, other than an error status. All normal results are side-effects, usually on an image.

In Lisp, the value of a function is the value of the last evaluation. But Script-Fu discards the value of the last evaluation in the run function of a plugin. A Script-Fu plugin returns a success error status unless

  • the interpreter throws an error in Scheme code
  • or a called PDB procedure returns an error
  • or the plugin calls the quit or error functions

Plugins in other languages can declare and return values, unlike Script-Fu scripts.

Binding of values returned from calls to the PDB

A Script-Fu plugin script can call a PDB procedure.

In C language terms, such a call yields an error status separate from normal returned values.

When a call to the PDB fails, the script usually does not continue after the call. Instead, the plugin returns, propagating the error. In Scheme terminology, the script’s call to the PDB throws a Scheme exception, which if not caught calls the error function which terminates the plugin script that is calling the PDB. In other words, you can’t check the error status of a call to the PDB. A script could catch an error but most scripts don’t bother.

On a successful call to the PDB, Script-Fu binds the returned values into a Scheme data structure.

Version 2 values returned from the PDB

A call to the PDB that succeeds yields a list.

When the PDB procedure declares returning void, the list is empty.

When the PDB procedure declares returning one value, the list has one element.

When the single returned value is a C array, the list wraps a numeric length and a vector.

When the single returned value is a list (a GStrv), the list wraps a list of strings.

When the PDB procedure declares returning many values, the list has many elements. Any element itself can be a container i.e. another list.

When the PDB procedure declares returning boolean the returned value is TRUE (1) or FALSE (0) wrapped in a list.

Version 3 optional binding of values returned from the PDB

This is not implemented yet, but should be before GIMP 3.0

Since version 3 of Script-Fu you can optionally alter interpretation by calling, at the top of a script, a new special function:

(script-fu-use-v3)

This gives a more natural binding. A call to a PDB procedure returning a single element yields just that element, not wrapped in a list. A call to a PDB procedure returning boolean returns #t or #f.

Thus in version 2:


(if (= (car (gimp-image-is-valid 1))
        TRUE)
    do-something)

can be written in version 3 as:

(if (gimp-image-is-valid 1)
    do-something)

A script cannot mix the old and new idioms. Also, a script in the new idiom cannot call a PDB procedure that is itself a script using the old idiom. script-fu-use-v3 sets a flag in the interpreter in the current process which is the same interpreter that interprets called old scripts. Since most useful PDB procedures are not themselves Script-Fu scripts, i.e. few Script-Fu plugins call old Script-Fu plugins, this is usually not a problem.

Old and new flavors of Script-Fu plugins

There are two flavors of Script-Fu plugins:

  • old, in version 2 and version 3
  • new, only in version 3

Old plugins:

  • are installed in /scripts
  • are served by the Script-Fu extension process
  • call script-fu-register, declaring all arguments
  • have a GUI implemented by the Script-Fu system

New plugins:

  • are installed in /plug-ins like other plugins
  • are interpreted each in a separate process
  • can call script-fu-register-filter, not declaring standard args
  • have a GUI provided by the GimpProcedureDialog class of libgimp

The differences are slight but important. An old plugin that crashes can affect the GIMP app. Old plugin dialogs look and feel different from new plugin dialogs.

More about the Script-Fu extension process

Most plugin authors can skip this material.

The Script-Fu extension process serves plugins in the /scripts directory.

This process is started by the GIMP app when the GIMP app starts. This process querys the /scripts directory and registers in the PDB all the plugins there. It registers them as kind TEMPORARY (as seen in the PDB Browser.)

The process stays resident i.e. executing. The process communicates with the GIMP app via the extension protocol. When a user chooses a script’s menu item, GIMP sends the name of the plugin procedure, and arguments, to this process via the extension protocol.

If an old plugin crashes, it takes down the Script-Fu extension process and some menu items disappear from the GIMP app. That requires a user to restart GIMP.

The extension protocol is different from the plugin protocol used by plugins in other languages and Script-Fu new plugins. In that protocol, when a user chooses the menu item for a plugin in the GIMP app, GIMP forks a new process, an interpreter, to interpret the script associated with the plugin. If the plugin crashes, the GIMP app is unaffected.

Errors

This discusses the kinds of errors from a Script-Fu plugin script.

  • Syntax Discovered at query time i.e. after the first install, by the embedded TinyScheme interpreter. For example, unmatched parenthesis.

  • Registration Discovered at query time i.e. after the first install, by Script-Fu. The data for registration in a call to script-fu-register is flawed, e.g. not a sequence of triplets.

  • Binding Discovered at run time, by the embedded TinyScheme interpreter. A name i.e. symbol is not bound. Typically a typo. Or, a function name that is in Scheme but not TinyScheme, or a named procedure that is no longer in the PDB. Also known as “unbound variable.”

  • Scheme Type Discovered at run time, by the embedded TinyScheme interpreter. Some Scheme functions dynamically check the type of their arguments.

  • PDB Type Discovered at run time, by the Script-Fu wrapper. Script-Fu checks the Scheme type of arguments in calls to a PDB procedure, and the PDB checks the C type of arguments in calls to a PDB procedure. The PDB also range checks some arguments. Also know as a “calling error.”

  • Run-time PDB Discovered at run time, by a called PDB procedure. For example, passed an image type that the procedure cannot handle. Also known as an “execution error.”

  • Script data Discovered at run time, by a script, in passed or read data. A script should call throw, quit, or error to declare such an error. Calling gimp-message is not sufficient, since it does not always mean an error, and can be invisible to a user.

  • System error Discovered at run time, by the OS or by the embedded TinyScheme interpreter. For example, a runaway script exhausted memory allocated by the interpreter, or a file operation failed.

Errors detected in newly installed scripts: querying of plugin scripts

This is about errors detected in newly installed scripts, i.e. at query time:

  • syntax errors
  • errors in the registration metadata and signature declaration (which is just data)

Such errors are only printed to stderr/stdout. So authors of new scripts should start GIMP in a terminal/console, and monitor for errors in stderr/stdout. (There is an issue/enhancement to log registration time errors to Gimp Error Console.)

When there are such errors:

  • the plugin fails to register
  • its menu item is not in the GIMP app
  • you can’t invoke the plugin

Other error kinds will not be detected until run time of the plugin’s run function, when a user invokes the plugin.

GIMP queries the /scripts and /plug-in directories when GIMP starts. To query means to interpret/evaluate, passing an argument denoting the query phase. In the query phase, each script registers it’s plugin in the PDB. In other words, the call to script-fu-register is evaluated. The define of the run function of the plugin is also evaluated, but this only parses the run function for syntax errors, and does not evaluate the run function itself.

(Note that GIMP persists the registered information in a config file. Only script files which have changed since persisted are queried.)

Exceptions, catch, and the *error-hook*

Errors are usually fatal i.e. stop evaluation of a plugin script.

Errors are Scheme exceptions. On an exception, the interpreter unwinds call frames to the first catch Scheme function or finally calls the error Scheme function which is fatal.

Most scripts do not use a catch. An example of a script that does is contact-sheet.scm which catches file opening errors and ignores them.

They symbol *error-hook* is a hook in the embedded TinyScheme interpreter. You can redefine the symbol to alter error handling. Typically used in test frameworks.

(There are other hook symbols in the embedded TinyScheme interpreter, e.g. *sharp-hook* which you can redefine to alter the parsing of sharp constants.)

Initialization of the Script-Fu interpreter

This is for advanced authors, who might want to view the implementation of a function. This describes how the interpreter state is initialized.

We use the words “Script-Fu loads” to mean similar to the Scheme load function, which reads a script file and evaluates it. Often a loaded file contains only definitions, i.e. calls to “(define …)”, which is similar to an import in other languages. But a loaded file may have more than just defines. See the special case for Script-Fu below.

This describes a process that provides some backward compatibility. Any backward compatibility in Script-Fu might change in the future. For forward compatibility or future-proofing, a script author should not use deprecated functions in newly written scripts.

  1. Script-Fu initializes the embedded TinyScheme interpreter. This defines core Lisp functions into the interpreter state. The embedded TinyScheme interpreter and these core functions are written in C.

  2. Script-Fu makes extensions ftx and re define their functions into the interpreter. These extensions are in C.

  3. Script-Fu defines its special functions into the interpreter. The special functions are written in C.

  4. Script-Fu introspects or queries the PDB and defines into the interpreter each procedure in the PDB. A Scheme call to the PDB passes through wrapper functions in Script-Fu.

  5. Script-Fu defines into the interpreter aliases for PDB procedures whose name has changed from prior versions of GIMP. A table in C associates alias names to new names. This is for backward compatibility. (Only in Script-Fu are the old names deprecated, i.e. aliased and still useable. In other GIMP plugin languages in GIMP version 3, the old names may be obsolete and not useable. In Script-Fu version 2, the names are useable.)

  6. Script-Fu loads /scripts/script-fu.init. In other Schemes, this file is named “init.scm”. The file is a Scheme script. It defines more core functions into the interpreter, such as cadr. This step is typical of Lisp interpreters. But the file is slightly altered from the usual TinyScheme init.scm.

  7. Script-Fu loads /scripts/script-fu-compat.init This file is a Scheme script. For backward compatibility, it defines certain deprecated Scheme functions from earlier versions of Script-Fu that used the SIOD dialect of Lisp. It also defines the not-deprecated random function for random number generation.

  8. Script-Fu loads /scripts/plug-in-compat.init This file is a Scheme script. For backward compatibility, it defines functions for certain deprecated PDB procedures from earlier versions of the GIMP PDB. The functions are written in Scheme and wrap calls to newer PDB procedures. They are not just aliases for renamed PDB procedures, the wrappers may do more or convert signatures.

  9. Script-Fu loads each script file in two /script directories, the user owned /script directory and the system-wide /script directory. This defines into the interpreter state all the PDB functions that are old style plugins written in the Script-Fu language as well as any other defined functions in those files!

The last step deserves more discussion. Script-Fu specially loads the files, at times suppressing calls to Script-Fu special functions like script-fu-register. (When the Script-fu extension process initializes the interpreter, it doesn’t suppress those calls.) Thus every instance of the Script-Fu interpreter locally has the body of the functions defined in those files. Thus calls from a Scheme script to a PDB function whose implementation is also an old style Scheme script do not result in a remote procedure call back to GIMP to the PDB.

This also means that any Scheme files (.scm) in those directories that do not define plugins can never-the-less define into the interpreter state. For example, the file /scripts/script-fu-util.scm defines several “utility” functions into the interpreter state. In other words, script files in those directories can serve as libraries.

The order in which the files in /scripts are loaded is undefined.

Loading other Scheme scripts

A script can also load Scheme text files, even one whose suffix is not .scm, by explicitly calling load passing a path to a file. You can form a path to the standard script directories with the string constant gimp-directory.