How to Create an Undo Group in GIMP Scripts
This guide explains how to bundle multi-step operations in GIMP into
a single undo step using undo groups. By implementing undo groups in
your custom Python-Fu or Script-Fu scripts, you ensure that complex,
multi-action modifications can be cleanly reverted with a single undo
command (Ctrl+Z), preventing the undo history from becoming
cluttered and protecting the user's workflow.
Why Use an Undo Group?
By default, every modification a script makes—such as creating a layer, applying a blur filter, or transforming a selection—creates an individual entry in GIMP’s Undo History. A script executing ten separate actions forces the user to press undo ten times to revert the canvas to its original state.
An undo group treats all procedural operations between its start and end markers as a single atomic event.
Python-Fu Implementation
In Python-Fu (standard in GIMP 2.8 and 2.10), undo groups are managed either via the image object directly or through the Procedural Database (PDB).
1. The Core Methods
To open and close the group:
- Start:
image.undo_group_start()orpdb.gimp_image_undo_group_start(image) - End:
image.undo_group_end()orpdb.gimp_image_undo_group_end(image)
2. Using
try...finally for Safety
Always enclose operations in a try...finally block. If
an unhandled exception occurs while an undo group is open, GIMP's undo
stack can become corrupted or permanently locked. The
finally clause guarantees that the undo group closes
regardless of errors.
def my_custom_script(image, drawable):
# Begin the undo group
image.undo_group_start()
try:
# Step 1: Add a new layer
new_layer = pdb.gimp_layer_new(image, image.width, image.height,
RGBA_IMAGE, "Processed Layer", 100, NORMAL_MODE)
pdb.gimp_image_insert_layer(image, new_layer, None, 0)
# Step 2: Fill the layer
pdb.gimp_drawable_fill(new_layer, WHITE_FILL)
# Step 3: Apply an effect
pdb.plug_in_gauss(image, new_layer, 10.0, 10.0, 0)
finally:
# Always close the undo group
image.undo_group_end()Script-Fu (Scheme) Implementation
In Script-Fu, use the standard PDB functions
gimp-image-undo-group-start and
gimp-image-undo-group-end.
(define (script-fu-my-operation image drawable)
;; Start the undo group
(gimp-image-undo-group-start image)
;; Multi-step operations
(let* ((new-layer (car (gimp-layer-new image
(car (gimp-image-width image))
(car (gimp-image-height image))
RGBA-IMAGE
"Script Layer"
100
LAYER-MODE-NORMAL))))
(gimp-image-insert-layer image new-layer 0 0)
(gimp-drawable-fill new-layer FILL-WHITE)
)
;; End the undo group
(gimp-image-undo-group-end image)
(gimp-displays-flush)
)Best Practices
- Pair Every Call: Every call to
undo_group_startmust have a matchingundo_group_end. Nesting is supported, but mismatched calls will cause abnormal undo behavior. - Do Not Disable Undo: Avoid using
gimp_image_undo_disable()unless working on temporary scratch images. Disabling undo clears the existing history entirely, preventing the user from undoing prior work. - Flush Displays After Closing: Call
gimp_displays_flush()afterundo_group_end()to update the UI only after all steps are finalized.