Scripts are syntactically valid Python with certain extra annotations and structure that are used by Wing IDE to determine which scripts to load and how to execute them.

Only functions defined at the top level of the Python script are treated as commands, and only those that start with a letter of the alphabet. This allows the use of _ prefixed names to define utilities that are not themselves commands, and allows use of Python classes defined at the top level of script files in the implementation of script functionality.

Script Attributes

In most cases additional information about each script def is provided via function attributes that define the type of arguments the script expects, whether or not the command is available at any given time, the display name and documentation for the command, and the contexts in which the script should be made available in the GUI.

The following are supported:

ArgInfo

Argument information is specified using the CArgInfo class in the Wing API (wingapi.py inside bin in the Wing IDE installation, although the class is imported from Wing IDE's internals) and the datatype and formbuilder modules in Wing's wingutils package. The source code for this class and support modules is only available in the source distribution, although most use cases are covered by the following.

CArgInfo's contructor takes the following arguments:

Commonly Used Types

The following classes in wingutils.datatype.py cover most cases needed for scripting:

  • CBoolean -- A boolean value. Constructor takes no arguments.
  • CType -- A value of type matching one of the parameters sent to the constructor. For example, CType("") for a string, CType(1) for an integer, and CType(1.0, 1) for a float, or an integer.
  • CValue -- One of the values passed to the constructor. For example CValue("one", "two", "three") to allow a value to be either "one", "two", or "three".
  • CRange -- A value between the first and second argument passed to the constructor. For example, CRange(1.0, 10.0) for a value between 1.0 and 10.0, inclusive.

Additional types are defined in wingutils.datatype.py, but these are not usually needed in describing scripting arguments.

Commonly Used Formlets

The following classes in guiutils.formbuilder.py cover most of the data collection formlets needed for scripting:

CSmallTextGui -- A short text string entry area with optional history, auto-completion, and other options. The constructor takes the following keyword arguments, all of which are optional:

max_chars         -- Maximum allowed text length (-1=any, default=80)
history           -- List of strings for history (most recent 1st) or
                     a callable that will return the history (default=None)
choices           -- List of strings with all choices, or a callable
                     that will take a fragment and return all possible
                     matches (default=None)
partial_complete  -- True to only complete as far as unique match when
                     the tab key is pressed.  Default=True.
stopchars         -- List of chars to always stop partial completion.
                     Default=''
allow_only        -- List of chars allowed for input (all others are
                     not processed).  Set to None to allow all.  Default=None
auto_select_choice -- True to automatically select all of the entry text
                     when browsing on the autocompleter (so it gets erased
                     when any typing happens).  Default=False.
default           -- The default value to use.  Default=''
select_on_focus   -- True to select range on focus click; false to retain
                     pre-focus selection.  Default=False
editable          -- True to allow editing this field.  Default=True.

CLargeTextGui -- A longer text string. The constructor takes no arguments.

CBooleanGui -- A single checkbox for collecting a boolean value. The constructor takes no arguments.

CFileSelectorGui -- A keyboard-driven file selector with auto-completion, optional history, and option to browse using a standard file open dialog. The constructor takes the following keyword arguments:

want_dir          -- True to browse for a directory name (instead of a
                     file name).  Default=False.
history           -- Optional list with history of recent choices, most
                     recent first.  Default=()
default           -- The default value to use.  Default=''

Additional formlet types are defined in guiutils.formbuilder.py but these are not usually needed in collecting scripting arguments.

CPopupChoiceGui -- A popup menu to select from a range of values. The constructor takes a list of items for the popup. Each item may be one of:

None                 -- A divider
string               -- The value.  The label used in the menu is derived:
                        label = value.replace('_', ' ').title()
(value, label)       -- The value and label to use in menu.
(value, label, tip)  -- The value, label, and a tooltip to show when the
                        user hovers over the menu item.

CNumberGui -- A small entry area for collecting a number. The constructor takes these arguments (all are required):

min_value            -- The minimum value (inclusive)
max_value            -- The maximum value (inclusive)
page_size            -- Increment when scroller is used to browse the range
num_decimals         -- Number of decimal places (0 to collect an integer)

Additional formlets for collecting data are defined in guiutils.formbuilder.py, but these are not usually needed for scripting.

Magic Default Argument Values

Wing treats certain defaults values specially when they are specified for a script's arguments. When these default values are given, Wing will replace them with instances of objects defined in the API. This is a convenient way for the script to access the application, debugger, current project, current editor, and other objects in the API. All the default values are defined in the wingapi.py file, as are the classes they reference.

GUI Contexts

Scripts can use the contexts function attribute to cause Wing to automatically place the script into certain menus or other parts of the GUI. The following contexts are currently supported (they are defined in wingapi.py):

All scripts, under both short and fully qualified name, are always listed along with all internally defined commands in the auto-completion list presented by the Command by Name item in the Edit menu, and in the Custom Key Bindings preference.

Top-level Attributes

Default values for some of the Script Attributes defined above can be set at the top level of the script file, and some additional attributes are also supported:

Importing Other Modules

Scripts can import other modules from the standard library, wingapi (the API), and even from Wing's internals. However, because of the way in which Wing loads scripts, users should avoid importing one script file into another. If this is done, the module loaded at the import will not be the same as the one loaded into the scripting manager. This happens because the scripting manager uniquifies the module name by prepending internal_script_ so two entries in sys.modules will result. In practice, this is not always a problem except if global data at the top level of the script module is used as a way to share data between the two script modules. Be sure to completely understand Python's module loading facility before importing one script into another.

Internationalization and Localization

String literals and docstrings defined in script files can be flagged for translation using the gettext system. To do this, the following code should be added before any string literals are used:

import gettext
_ = gettext.translation('scripts_example', fallback=1).gettext
_i18n_module = 'scripts_example'

The string 'scripts_example' should be replaced with the name of the .mo translation file that will be added to the resources/locale localization directories inside the Wing installation.

Subsequently, all translatable strings are passed to the _() function as in this code example:

kMenuName = _("Test Base")

The separate _i18n_module attribute is needed to tell Wing how to translate docstrings (which cannot be passed to _()).

Currently, the only support provided by Wing for producing the *.po and *.mo files used in the gettext translation system is in the build system that comes with the Wing IDE sources. Please refer to build-files/wingide.py and build-files/README.txt for details on extracting strings, merging string updates, and compiling the *.mo files. On Linux, KDE's kbabel is a good tool for managing the translations.

Plugins

When a script contains the _plugin attribute at the top level, it is treated as a plugin that can enable/disable itself as a whole and/or be enabled/disabled by the user in preferences.

When _plugin is present, it contains (name, _activator_cb) where name is the display name of the plugin and activator_cb is a function minimally defined as follows for a plugin that is always enabled:

def _activator_cb(plugin_id):
  wingapi.gApplication.EnablePlugin(plugin_id, True)
  return True

The _activator_cb can also selectively enable the script by any code that accesses the Wing scripting API. For example, it could set up an instance that connects to signals in the API and calls wingapi.gApplication.EnablePlugin() to enable or disable itself according to project contents, file type in active editor, etc.

When a plugin is inactive, none of its commands are available and any added menus or menu items its adds to the GUI are removed. Plugins may denote particular commands as always available even when the plugin is inactive by setting the _plugin_override function attribute to True.

If the user disables a plugin in the Tools menu, this prevents loading of the plugin, and thus overrides _activator_cb and any _plugin_override attributes for the plugin.