ScriptFu refers to GIMP support for plugins written in the Scheme language.
The GIMP Scheme interpreter implements TinyScheme, a dialect of the Scheme language, a dialect of the Lisp language. The GIMP TinyScheme interpreter specializes it for image processing, adding a few more symbols to the TinyScheme language.
Some Scheme plug-ins are distributed with GIMP and some are distributed by third parties.
This describes GIMP 2 and GIMP 3 plugins. ScriptFu is mostly unchanged from GIMP 2 to GIMP 3, except to accomodate changes to GIMP itself.
- 1 Audience
- 2 Overview
- 3 Tutorials
- 4 Scheme plugins and the GIMP Procedural DataBase (PDB)
- 5 The language for defining ScriptFu plugin parameters
- 6 GIMP constants in ScriptFu
- 7 Examples and templates
- 8 The Tiny Scheme language
- 9 Internationalization
- 10 The ScriptFu Console
- 11 Debugging ScriptFu scripts
- 12 ScriptFu uses numeric GIMP object ID's
- 13 ScriptFu architecture
- 14 Future directions using GObject introspection
This is mainly for authors of third party plugins. This page is a basic introduction with references to further reading. This is somewhat about programming language theory: ScriptFu as a language.
There are many Scheme plugins in the GIMP repository, providing important capabilities of GIMP. If you write a particularly useful Scheme plugin, it could find its way into the GIMP repository.
If you are interested in enhancing the Scheme interpreter of GIMP, it is written in C and its source is in the GIMP repository under /gimp/plug-ins/script-fu.
GIMP plug-ins let you program image manipulation algorithms. Scheme language GIMP plug-ins are interpreted. They can call procedures in the GIMP Procedural Database (PDB) as well as the functions built into the Scheme language. They are distributed as text files called scripts with suffix ".scm". They are registered in the PDB with a name like "script-fu-...". They may appear in the GIMP user interface, in pull-down or pop-up menus.
Installation and debugging is covered in the tutorials.
Scheme plugins and the GIMP Procedural DataBase (PDB)
Scheme plugins are in the PDB and call the PDB
Calling procedures in the PDB
Scheme language plugins can call PDB procedures, as well as functions of the Scheme language. (They do not call functions from the libgimp library.) Example Scheme constructs for calling a PDB procedure:
(script-fu-clothify image drawable 1 2 3 4 5)calls the PDB procedure script-fu-clothify, which is another plugin
(gimp-image-get-drawables image )calls an internal procedure, more or less the get-drawables method of the Image class of the Gimp module
PDB procedures called from a Scheme plugin return a list.
Scheme plugins in the PDB
Scheme language plugins are also in the PDB. Plug-ins register themselves in the PDB. The functions built into the interpreter for registering a plugin are:
Registration means declaring:
- the name and parameters of a plug-in (the signature)
- other metadata such as help and author
- declaring how and where a plug-in will appear in the GIMP menus, if at all.
ScriptFu plugins can return a value, when the script's run function's last line is a simple reference to a symbol. Unlike GIMP plugins in other languages, you do not register the types of return values.
All plugins understand a runtime "run mode". In NONINTERACTIVE (batch) mode, they do not provide a user interface. Most plugins take a run mode parameter. When a plugin calls a plugin, it usually passes a run mode. PDB procedures that are kind "Internal" do not usually accept a run mode parameter.
The language for defining ScriptFu plugin parameters
This is covered by many tutorials.
The only official documentation seems to be in the comments of the test-sphere.scm plugin in the GIMP repository.
Parameters are declared using a set of constants declared by the interpreter, the SF_... constants (an enumeration.)
Each parameter is declared by a triple of arguments to the script-fu-register function.
Each triple comprises:
- a SF_... constant
- a string name
- a list that further specifies the parameter, the list contents depending on the SF_... constant
Most SF_... constants denote not only the type of the parameter, but how it appears in the dialog that ScriptFu can present in the GIMP GUI. (What kind of control widget will appear in the GUI.)
GIMP constants in ScriptFu
The ScriptFu interpreter also recognizes symbols for constants defined by GIMP. You use these symbols as arguments in calls to PDB procedures. They are generally of the form GIMP-... , that is, upper case with hyphens.
Examples and templates
Many examples can be found in the tutorials.
Many examples are in the GIMP repository at /gimp/plug-ins/script-fu/scripts.
A very brief and incomplete example, giving the basic structure of a plugin, is:
(define (script-fu-my-plugin ... ) ) (script-fu-register "script-fu-my-plugin" ... ) (script-fu-menu-register "script-fu-my-plugin" ... )
In the above example, you define the "run function" of your plugin, then call two functions to register it. After you install your script, your plugin will be in the PDB, and may appear in the GIMP GUI.
The Tiny Scheme language
Scheme is a dialect of Lisp. Lisp is a pure programmer's language with a very simple syntax.
GIMP provides a subset of the Scheme language called TinyScheme. The set of functions implemented by the TinyScheme interpreter of GIMP is smaller than the set implemented by the full Scheme language. But you can textually include third party Scheme functions inside your plug-in.
Early versions of GIMP used a different dialect of Lisp for ScriptFu plugins (called SIOD.) You may occasionally find ancient scripts in that dialect.
Lisp is beautiful because it is can be interpreted by a small program (an interpreter for Lisp written in Lisp can be a few tens of lines.) ScriptFu (the plugin support offered by GIMP) is implemented by a small interpreter written in the C language, part of GIMP
You can declare intent to internationalize strings in ScriptFu plugins using "_" notation before strings, for example:
You only need to internationalize strings that appear in the GUI.
Getting people to translate your strings is another matter.
The ScriptFu Console
You can open a ScriptFu Console using the menu item Filters>Development>Script-Fu>Script-Fu Console.
The console is a window executing a REPL, a read-evaluate-print-loop. That is, you enter a construct in the ScriptFu language, enter Return, and see a printed result.
The console executes in the current context of the GIMP app. Thus for example, in the console:
will return, and print the representation of, a list whose first element is the number of images, and whose second element is a vector of image ID's.
The ScriptFu Console lets you browse the PDB. It shows the signature of PDB procedures in terms of C language types, so you must mentally translate into Scheme language.
The Apply button in the Script-Fu Procedure Browser will translate for you and paste a construct into the Script-Fu Console. Then you can enter Return in the console to execute the pasted construct.
Debugging ScriptFu scripts
Print GIMP messages
You can print to the message bar of the GIMP app using:
(gimp-message "my message")
The messages are ephemeral, only visible until the next message overwrites it.
You can enable the tracing feature of the interpreter using:
(set-output-port (open-output-file "/dev/stderr"))
usually at the start of your script. This will make the TinyScheme interpreter print many messages about its execution, to the console (terminal, i.e. to stderr) where the GIMP app was started. Note that stdin and stdout are used by the outer interpreter, ScriptFu, for communication with the GIMP app.
The trace is not easy to understand, it shows the nested or recursive nature of Lisp interpretation. The trace is most useful to explain any errors in Scheme syntax. The trace is less useful to explain errors in calls to PDB procedures.
Tracing capability is also a compile time option. You might need a GIMP binary that was compiled with ScriptFu tracing enabled. See the C preprocessor variable USE_TRACING in scheme.h. The tracing capability defaults to "enabled" but the builder of your GIMP may have changed it.
Write to a console
You can write to the console using:
(write "my message" (open-output-file "/dev/stderr"))
That will write to the console where the GIMP app was started.
You can also use other Scheme I/O functions to say write to a file. Scheme uses "port" objects. The call above to open-output-file returns a port object.
Enable ScriptFu logging of PDB calls
Starting with GIMP 3, the ScriptFu interpreter uses GLib logging. You can enable it by setting an environment variable before starting the GIMP app in a console:
Then the ScriptFu interpreter will print many messages about its interpretation of calls to the PDB.
script-fu:102): scriptfu-DEBUG: 12:50:33.159: In script_fu_marshal_procedure_call()
ScriptFu warnings go to a console
If you suspect errors in a script, it it important to start GIMP in a console, since ScriptFu prints warnings to the console.
For example, you may see:
(script-fu:102): scriptfu-WARNING **: 12:45:44.166: in script, permitting too few args to gimp-edit-copy
These warnings do not depend on setting the environment variable G_MESSAGES_DEBUG.
ScriptFu uses numeric GIMP object ID's
GIMP identifies its objects with numeric ID's (as well as with C pointers.) ScriptFu uses the numeric ID's internally.
This is opaque to scripts. That is, ordinarily you need not think about it. You store returned objects in Scheme variables without worrying about it. However, a printed representation of a GIMP object appears as a numeral. And you could use a literal numeral when a reference to a GIMP object is required (in extraordinary circumstances.)
The ScriptFu interpreter and the ScriptFu Console are "GIMP extensions", that is, separate processes. The ScriptFu interpreter receives a message from the GIMP app when you choose certain menu items.
If the ScriptFu interpreter crashes, you must restart GIMP.
The ScriptFu interpreter process reads all its (and your) scripts when it starts. If you edit a script, you can ask the running ScriptFu interpreter process to reread the scripts. Use the menu item Filters>Development>Script-Fu>Refresh Scripts You can't do this when a script is already running (while its dialog is up.)
The architecture is different for other interpreters, e.g. the Python interpreter, which is started, and terminates, when you choose a menu item.
ScriptFu is a wrapper of a TinyScheme interpreter. This differs from the architecture of other GIMP interpreters, such as the Python interpreter. GIMP starts the ScriptFu wrapper once, and later passes it the name of a GIMP plugin that a script implements. Conversely, GIMP starts the Python interpreter many times, and passes it the name of a file containing a Python script, along with a parameter that signifies whether the script is being queried or run.
ScriptFu is a wrapper of a TinyScheme interpreter. ScriptFu is the outer interpreter and TinyScheme is the inner interpreter. The TinyScheme interpreter is minimal, but small and fast. The TinyScheme interpreter in GIMP is mostly unchanged from the repository for TinyScheme.
The TinyScheme interpreter itself has several parts. The innermost part of TinyScheme is an interpreter written in C. It implements a small subset of the Lisp language e.g. car and cdr. The second part is a set of defines that implements a larger language from the Lisp family, the Scheme language. The set of defines are in the the file script-fu.init, written in the Scheme language. This file also is mostly unchanged from the original in the repository for TinyScheme. The third part is a set of defines that implements an even larger language, for compatibility with earlier versions of ScriptFu. The set of defines are in the the file script-fu-compat.init, written in the Scheme language. This file is specific or custom to GIMP's use of TinyScheme.
The startup of ScriptFu grows the language. ScriptFu starts the innermost TinyScheme interpreter, which then interprets the script-fu.init and script-fu-compat.init files to yield a larger language. Then ScriptFu defines "foreign functions", making the language even larger. The "foreign functions" make GIMP PDB procedure names appear as function symbols in the ScriptFu language. The interpretation of a foreign function engenders a call to a function of GIMP using the C ABI. When the ScriptFu extension starts, it also reads all the Scriptfu scripts, registers them in the PDB, and retains a copy of their Scheme text in memory, i.e. the state of the interpreter. So the GIMP functions in the ScriptFu language are both the PDB procedures written in other languages, and the PDB procedures written in the ScriptFu language itself.
Future directions using GObject introspection
Starting with GIMP 3, the preferred architecture for plugins uses GObject introspection (GI) of the libgimp API. For example, a GIMP Python plugin usually uses the PyGObject module for GObject introspection.
GIMP developers are considering replacing the ScriptFu interpreter with a standard Lisp interpreter (Guile) that might be capable of GObject introspection.
The ScriptFu interpreter is not capable of GObject introspection.