GIMP Developer Site now have improved navigation!

Script-Fu Tools

This is a user manual for the ScriptFu tools.

The ScriptFu tools let you develop plugins and to process images in batches. They are more general purpose than, for example, image filter plugins.

The ScriptFu tools are:

  1. Console: a graphical IDE letting plugin authors edit and test snippets.
  2. Eval: a PDB procedure that lets other languages call the ScriptFu interpreter to execute snippets. It is not an application program, but a function.
  3. Server: a plugin that runs a server background process that evaluates snippets, submitted over the network by clients. It is not an application program, but a daemon. The server can run in a host computer and a client in a separate computer can access the remote server.
  4. Text Console: a textual command line similar to the graphical ScriptFu Console. It is an application program.

Terminology

ScriptFu’s language is a dialect of the Scheme programming language, augmented with functions to call the Gimp PDB. The tools interpret “snippets” of that language. By “snippet” we mean a piece of text in ScriptFu’s dialect of the Scheme language.

A snippet can be part of an intended plugin but a snippet can’t itself be a plugin, since a snippet can’t register in the PDB. So, you can only test the “run function” of a plugin, or snippets thereof.

ScriptFu Console

The ScriptFu Console is a graphical IDE letting plugin authors edit and test snippets. Probably the most popular ScriptFu tool.

It is most like a command-line program in a terminal: you type some text, hit the Return key, and see the result scroll by. But it has a graphical user interface, using a mouse.

Starting the console

Start the Gimp app.

If you are debugging a snippet, you might start Gimp in a terminal so you can see debugging messages from the ScriptFu interpreter.

Choose the menu Filters>Development>Script-Fu>Console. Expect a window to appear.

Using the console

The pane at the bottom is a text editor. Click the cursor into it, type some text, and press the Return key. You can also cut and paste, or drag-and-drop, into the text editor.

ScriptFu interprets the text and appends the result to the history in the top pane. The displayed result is:

  1. what the snippet writes to stdout (the default output port of Scheme language)
  2. and what the ScriptFu Interpreter writes to stdout as the yielded value of each top level expression in the snippet.
  3. and any error message

When a snippet is in an installed plugin, it’s stdout will be printed in the terminal in which Gimp was started, if any (unless the snippet itself redirects the Scheme output port).

Note that the ScriptFu Console prints all results for a snippet in one multi-line tranche, not each line in real time as generated. The yielded values of the top-level expressions are often concatenated in a one line string, when the snippet itself does not insert newlines.

Scrolling the history

The Up and Down Arrow keys will scroll through the history. Pressing the Up Arrow key will put the prior command into the editor pane.

The history of commands, but not the history of results, is persistent across sessions of Gimp.

The history is finite; the editor discards the oldest commands.

Browsing

The Browse button opens a new window showing the PDB Browser. Then choose the Apply button of the PDB Browser. That will insert a template of a call to the selected PDB procedure, into the editor pane. You will usually need to substitute actual argument values for formal argument names in the template.

(You can also start a PDB Browser from the Help menu, but it won’t have an Apply button.)

Other limitations

Currently, the window will not stay on top, and may get hidden behind the main Gimp window.

Currently, the text editor is only one line tall, and shows line breaks as a character glyph.

It is primitive, and doesn’t have the features of a full-fledged IDE, such a command completion and syntax highlighting.

ScriptFu Eval

ScriptFu Eval is a PDB procedure that lets other languages call the ScriptFu interpreter to execute snippets. It is not an application program, but a PDB procedure.

So, Eval is unlike Script-Fu Server, because:

  1. the process starts and stops for every evaluated snippet.
  2. it has no long running interpreter state
  3. it runs in the current Gimp context of the calling plugin.

As a plugin, it has no user interface and cannot be called except in run mode NONINTERACTIVE.

Calling ScriptFu Eval from Python

You can call plug-in-script-fu-eval from the Gimp Python Console, or from a Gimp plugin in the Python language.

In the Gimp Python Console:

Python
proc = Gimp.get_pdb().lookup_procedure('plug-in-script-fu-eval')
# A Config is a set of arguments
config = proc.create_config()
# Arguments to the procedure are each a property of the config.
# Here, the arg is the snippet to be evaluated, a string text
# and the name of the argument is "script".
config.set_property('script', '(quit 1)')
result = proc.run(config)
print (result)
print (result.index[0])

This prints:

<Gimp.ValueArray object at 0x7f3847b4b1d0 (GimpValueArray at 0x2520640)>
<enum GIMP_PDB_EXECUTION_ERROR of type Gimp.PDBStatusType>

In this example, the evaluated Scheme snippet does nothing but quit with error code 1. Again, most snippets are executed for their side effects.

Note that the Gimp Python Console does not show what the ScriptFu interpreter printed or what the snippet output. That output goes to the terminal where Gimp was started, expect:

script quit with code: 1

Also, since the snippet returned an error, expect in the Gimp Error Console:

GIMP Error Calling error for procedure 'pug-in-script-fu-eval': Unknown error.

Calling ScriptFu Eval in batch mode

A more frequent use is to run a snippet in batch mode. You can’t just execute ScriptFu Eval from a command line, because, as said, it is not a program, it is a plugin that must be invoked from within Gimp.

gimp-console --batch-interpreter=plug-in-script-fu-eval --batch="(gimp-message \"foo\")"
Note the escaped quotes around the string “foo”, so that the command line shell doesn’t process the quotes.

Expect in the terminal:

script-fu-Warning: foo
batch command executed successfully

Here the first line is due to the snippet’s call to gimp-message, which prints to stdout when Gimp is in batch mode. Here the second line is printed by Gimp as the result of the batch.

A more useful example is to evaluate a file of Scheme language:

gimp-console --batch-interpreter=plug-in-script-fu-eval --batch="(load \"my.scm\")"

This also will print to the terminal.

ScriptFu Server

You start the server, then send snippets using a client, and receive results in the client.

The server is:

  1. is a long-running process
  2. has persistent interpreter state
  3. starts in the context of the Gimp app at the time the server is started.

You should only have one client at a time, since all clients share the same execution environment. A client can define objects such as images into the serving interpreter’s environment.

Starting the server

Start the Gimp app. Start it from a console i.e. terminal when you want the server to log to a terminal instead of a file.

  1. Choose the menu Filters>Development>Script-Fu>Start Server. Expect a dialog to appear.
  2. Choose the OK button. Expect the dialog to disappear. Also expect the server to be a running process and for it to write log messages to the console in which Gimp was started.
  3. Alternatively, in the dialog for the server, you choose a file for the server to log to. Then you can “tail -f” the file to see the log.

You can also start the server without a visible Gimp window by starting Gimp in batch (or headless) mode:

gimp-console --batch-interpreter=plug-in-script-fu-eval --batch="(plug-in-script-fu-server 1 \"127.0.0.1\" 10008 \"/tmp/SFserver.log\" )"

Monitoring the server

The server logs to stdout i.e. the terminal where it was started, or to a file.

Gimp’s Client for the ScriptFu Server

The Python 3 program plug-ins/script-fu/server/servertest.py on GIMP source is a simple client. It prompts you for snippets.

Usage: servertest.py <host> <port>
       (if omitted connect to localhost, port 10008)

Start it:

python3 path_to_gimp_source/plug-ins/script-fu/server/servertest.py

Expect a banner and a prompt:

Script-Fu-Remote - Testclient
>

Enter a snippet and press the Return key. Expect a result to be printed. Repeat.

Enter Control-D to quit the client.

The protocol

You can skip this unless you are developing a client.

A client sends a header of three bytes. The first byte is a magic byte indicating the protocol in use. The second and third byte are the length of the subsequent command.

A client then sends the command itself.

The server receives the header and the command, and interprets it as a Scheme text. Then the server responds.

The server first sends a header of four bytes. The first byte is a magic byte indicating the protocol in use. The second byte is a boolean that is true if the interpreter returned an error. The third and fourth bytes encode a 16-bit integer length of the rest of the response.

Then the server sends the rest of the response. Which is either the output to stdout of the interpreted snippet, or an error message.

For both the server and the client, when they use the recv() system call that is non-blocking, the call might use the flag MSG_WAITALL to ensure that all bytes are received, since recv() can return with whatever bytes are available.

Or the server and client should use some other strategy for assembling the components of the protocol. The server sends a header and a response body in separate messages, in two sends. The recv() call does not guarantee that a message is complete. When there are network errors, partial messages might be received, or the header message might be received and the response message never received.

Stopping the server

You can stop the server by quitting the Gimp app. The server is a separate process, but a child process of the Gimp app.

ScriptFu Text Console

ScriptFu Text Console is a textual command line similar to the graphical ScriptFu Console. It is an application program.

It is rarely used. It lacks the editing and history capabilities of the graphical ScriptFu Console and only works on Unixes like Linux and macOS.

Using the Text Console

In an Unix terminal i.e. at a command line:

gimp-console --batch-interpreter=plug-in-script-fu-eval --batch=-

Expect to see in the terminal:

Welcome to TinyScheme, Version 1.40
Copyright (c) Dimitrios Souflis

ts>

This magic encantation doesn’t name “plug-in-script-fu-text-console”, the name of the PDB procedure that is the plugin for ScriptFu Text Console. So how does it work? Behind the scenes, that plugin is invoked. Loosely speaking --batch=- denotes: read from stdin. Other plugins should not call the PDB procedure “plug-in-script-fu-text-console”; only the magic incantation should call it.

Now you can enter snippets followed by carriage return:

ts> (+ 2 3)
5
ts>

The text console responds with the result of interpretation, and then another prompt.

The prompt is “ts>” but the interpreter is ScriptFu, Gimp’s wrapper of the original TinyScheme interpreter. So you can also call Gimp’s PDB procedures:

ts> (gimp-get-images)
(0 #())
ts>

Control-C will terminate the text console, reverting to the shell prompt.

Last updated on