ADR 2025011: User Script Specification

Status

  • Accepted

Context

OmegaT provides a scripting feature that allows users to extend the functionality of the application using languages like Groovy and JavaScript. Historically, the specification of this feature, especially regarding directory locations and event-driven execution, has not been clearly documented. This has led to inconsistencies in how different parts of the application interact with scripts.

Script Storage Locations

There are currently two main locations related to scripts:

  1. User-defined Script Directory: Configurable via Options > Scripting.... It defaults to the scripts folder in the current working directory. This directory is used by the Scripting Window to list available scripts and to monitor for event-driven scripts.

  2. OmegaT Configuration Script Directory: Located at <configDir>/script (e.g., ~/.omegat/script on Linux). This directory is returned by StaticUtils.getScriptDir().

Inconsistency

SegmentExportImport uses the OmegaT Configuration Script Directory to exchange data with external scripts. It writes source.txt, target.txt, and selection.txt to this directory and monitors it for import.txt. However, users typically store their scripts in the User-defined Script Directory. If a script wants to interact with SegmentExportImport, it must know to look in the configuration directory, which is often counter-intuitive.

Event-driven Scripts

OmegaT can automatically execute scripts when certain events occur. These scripts must be placed in specific subdirectories of the User-defined Script Directory. The supported events (defined in ScriptsMonitor.EventType) are:

  • application_startup: Executed when the scripting engine is initialized (shortly after OmegaT starts).

  • application_shutdown: Executed when OmegaT is closing.

  • entry_activated: Executed when a new segment is activated.

  • new_file: Executed when a new file is opened in the editor.

  • new_word: Executed when a new word is detected.

  • project_changed: Executed when the project state changes.

Scripting Languages

OmegaT supports any language for which a JSR-223 compliant script engine is available.

  • Groovy: The primary and default language (.groovy extension).

  • JavaScript: Supported via the built-in Nashorn engine or GraalJS (.js extension).

Decision

We clarify the following specifications for the Scripting feature:

  1. Script Directory Distinction:

    • The User-defined Script Directory (set in preferences, defaults to ./scripts) is the primary location for user-managed scripts, localization properties, and event-triggered scripts.

    • The OmegaT Configuration Script Directory (<configDir>/script) is reserved for internal data exchange and temporary files used by features like SegmentExportImport. Users should not store their scripts here unless they specifically intend to override internal behavior.

  2. Event Subdirectories:

    • Scripts located in subdirectories named exactly as the lowercase event names (e.g., scripts/application_startup/) will be automatically executed when the corresponding event occurs.

    • Scripts within these subdirectories are executed in alphabetical order.

    • Subdirectories are monitored by ScriptsMonitor.

  3. Script Metadata and Localization:

    • Script names and descriptions can be ernationalized and intlocalized using resource bundle files in a properties/ subdirectory relative to the script’s location.

    • Alternatively, non-localizable metadata can be embedded in the script file using the format:

      // :name = My Script :description = This script does something.
      
  4. Global Bindings:

    • Scripts have access to the following global variables:

      • project: The current project (ITranslationProject).

      • editor: The editor instance (IEditor).

      • glossary: The glossary instance (IGlossaries).

      • mainWindow: The main application window (IMainWindow).

      • Core: Access to org.omegat.core.Core class.

      • console: A logger instance (IScriptLogger) for printing to the Scripting Window console.

      • res: A ResourceBundle for the script (if a .properties file is provided).

  5. GUI Interaction:

    • Scripts that need to perform GUI operations should define a gui function. OmegaT will ensure this function is executed on the Event Dispatch Thread (EDT).

  6. Console Mode:

    • In console mode, ConsoleBindings is used to mock GUI elements, providing a safe environment for script execution without a graphical display.

Consequences

  • Better clarity for both users and developers regarding script behavior.

  • Documented event-driven script mechanism.

  • Identified need to eventually unify or better integrate the user script folder and the configuration script folder.