.. highlight:: ada .. _Customizing_and_Extending_GNAT_Studio: ************************************* Customizing and Extending GNAT Studio ************************************* .. index:: customization GNAT Studio provides several levels of customization, from simple preference dialogs to powerful scripting capability through the Python language. This chapters describes each of these capabilities. Color Themes ============ .. index:: themes The :guilabel:`Color Theme window` shows a list of color themes to choose from, presented in the form of a list of screenshots. Clicking on the button underneath a screenshot applies the given color theme to GNAT Studio. Applying a color theme modifies the corresponding GNAT Studio preferences. It is therefore possible to customize the colors after a theme has been applied, through the preferences dialog. GNAT Studio supports importing themes which use the TextMate (:file:`.tmTheme`) format: at startup, GNAT Studio will look in the directory :file:`GNATSTUDIO_HOME/.gnatstudio/themes/` and will include all the :file:`.tmTheme` found at the first level of this subdirectory. You can also import your themes in the :file:`INSTALL/share/gnatstudio/color_themes/themes/` directory if you want to share themes accross your team. Custom Fonts ============ .. index:: fonts In addition to the system fonts, GNAT Studio will load the fonts located under :file:`share/gnatstudio/fonts`) in the GNAT Studio installation directory. The supported formats are :file:`.otf`, :file:`.ttf` and :file:`.ttc`. This mechanism works only on UNIX/Linux systems; under Windows, fonts need to be added at the system level. Fonts that are added directly in this directory may not show up in the list of fonts in the preferences dialog, but it is still possible to use them by entering the font name manually. .. index:: key shortcuts; editing .. _The_Key_Shortcuts_Editor: The Key Shortcuts Editor ======================== .. image:: key-shortcuts.png :width: 100% This editor is started through the :menuselection:`Edit --> Preferences` menu, then by selecting the :guilabel:`Preferences` page. It provides a convenient way to edit the keyboard shortcuts that are available throughout GNAT Studio. All keyboard shortcuts are associated with actions, which are either predefined in GNAT Studio, or defined in your customization python files, as documented in :ref:`Customizing_through_XML_and_Python_files`. The main part of the editor is a list showing all actions that are defined in GNAT Studio, grouped into categories. There are literally hundreds of such actions, and finding the one you should use might be difficult. To simplify the search, you can use the filter field at the top-right corner of the editor. Typing any text in this field will restrict the list of actions to those that contain the text either in their name, their description, their keyboard shortcut, or the menus the action is bound to. Entering keyboard shortcut is in fact easier done via the :guilabel:`Grab` button next to the filter field. Click on it, then type the shortcut you are looking for. By using the local configuration menu (click on the top-right button of the editor), you can further restrict what is displayed in the editor: * :guilabel:`Shortcuts only` will only display the actions that have an actual shortcut, and hide all the others. * :guilabel:`Show categories` can be unset if you just want to display a flat list of all the actions. * All menus in GNAT Studio are themselves bound to actions. In general, it is better to associate a key shortcut to the action itself, as opposed to the menu. For this reason, GNAT Studio by default does not list all the menus in the keyboard shortcuts editor. However, historically, GNAT Studio used to show all menus there and you can get this behavior back by enabling the :guilabel:`Show all menus` configuration. When you select an action, GNAT Studio will display its documentation in the bottom part of the editor. This documentation also includes a pointer to the python file that defines the action (or whether it is built-in in GNAT Studio), as well as the list of menus that will execute this action when selected. Finally, the editor includes a set of buttons on its right side, which are grouped into two logical sets: * The top three buttons allow you to control `Key themes`. These are sets of keyboard shortcuts that are either provided as part of GNAT Studio (for instance GNAT Studio provides an :index:`Emacs key theme` which attempts to emulate some of the Emacs key bindings) or created by the user. The first box lists all known themes, and lets you alternate between them simply by selecting their name. This will unset all existing key bindings except the ones you have set manually, and replace them with the shortcuts loaded from the key theme. This also updates all the menus to reflect the new shortcuts. The :guilabel:`Reset` button will discard all the key bindings you have manually overridden, and revert to the theme's default key bindings. The :guilabel:`Create` lets you create a new key theme by copying all the current shortcuts (those from the theme and the ones you have set manually) into a new theme. In effect, this creates a new XML file in the directory :file:`$HOME/.gnatstudio/key_themes`. Removing a custom key theme is done by deleting the file from that directory, no GUI is provided for this at the moment. * The second group of buttons lets you edit the shortcut for the currently selected action either by removing a shortcut, or by overriding the ones that are currently set. When you click on the :guilabel:`Add` button, GNAT Studio waits for you to press any keyboard shortcut you wish to associate with the action. This shortcut can include multiple keys, so for instance to get an Emacs-like binding you could for instance press :kbd:`Ctrl-x` and then press :kbd:`Ctrl-k`. After pressing the last key in the sequence, wait for a short delay and GNAT Studio will associate the resulting shortcut to the action and update the menus, when relevant, to show the new binding. Note that multi-key shortcuts cannot be displayed in menus due to technical limitations of the GUI toolkit. Any change to the shortcuts is immediately and automatically saved, so that they become instantly usable in GNAT Studio, and will be restored properly when GNAT Studio is restarted. .. _Editing_Plugins: Editing Plugins ================ .. index:: plugins You can extensively customize GNAT Studio through external plugins, either ones you write (see :ref:`Customization_files_and_plugins`) or using one of the plugins in GNAT Studio's own collection. Some plugins are loaded by default when GNAT Studio starts (such as support for the CVS version management system and support for highlighting in various programming languages) and others are available but not loaded automatically, such as Emacs emulation mode. Some plugins provided with GNAT Studio are: * :file:`Makefile` support .. index:: Makefile A plugin that parses a :file:`Makefile` and creates menus for each of its targets so you can easily start a :command:`make` command. * Cross-references enhancements Some plugins take advantage of GNAT Studio's cross-references information to create additional menus for navigation such as jumping to the primitive operations of Ada tagged types and to the body of Ada separate entities. * Text manipulation Several plugins provide support for advanced text manipulation in the editors, for example to align a set of lines based on various criteria or to manipulate a rectangular selection of text. You can graphically choose which plugins are loaded on startup by opening the preferences editor dialog (:menuselection:`Edit --> Preferences...` menu), under the :guilabel:`Plugins` section. This section lists all the known plugins on the left. By selecting one particular plugin, the corresponding preferences page is opened on the right. Each plugin page comes with the same layout: * A :guilabel:`General` group This group indicates the exact location of the plugin file. Moreover, this group contains a toggle button (:guilabel:`Loaded at startup`) which allows you to decide if this plugin should be loaded or not in the next GNAT Studio session. As described in :ref:`Customization_files_and_plugins`, GNAT Studio searches for plugins in various directories and, based on these directories, decides whether to automatically load the plugin on startup. * An optional :guilabel:`Preferences` group This group lists all the preferences related to the selected plugin, allowing you to customize the plugin behavior. Note that this group is displayed only if preferences have been registered for this plugin. * A :guilabel:`Documentation` frame This frame displays the plugin file documentation. By convention, each plugin starts with a comment indicating the purpose of this plugin and more detailed documentation on its usage. If you have modified the list of plugins that should be loaded at startup, you will need to restart GNAT Studio, since it cannot unload a module due to such an action having too many possible effects on GNAT Studio: then, a dialog is displayed asking you whether you would like to exit GNAT Studio when closing the preferences editor dialog. All the changes explicitly set by the user in the list of plugins to load at startup are saved in :file:`$HOME/.gnatstudio/startup.xml`. .. _Customizing_through_XML_and_Python_files: Customizing through XML and Python files ======================================== .. index:: customization .. _Customization_files_and_plugins: Customization files and plugins ------------------------------- You can customize many capabilities in GNAT Studio using files it loads at startup. For example, you can add items to the menu and tool bars as well as defining new key bindings, languages, and tools. Using Python as a programming language, you can also add new facilities and integrate your own tools into the GNAT Studio platform. GNAT Studio searches for these customization files at startup in several different directories. Depending on where they are found, they are either automatically loaded by GNAT Studio (and thus can immediately modify things in GNAT Studio) or may only be made visible in the :guilabel:`Plugins` section of the preferences editor dialog (see :ref:`Editing_Plugins`). GNAT Studio searches these directories in the order given below. Any script loaded later can override operations performed by previously loaded scripts. For example, they can override a key shortcut, remove a menu, or redefine a GNAT Studio action. In each directory name below, :file:`INSTALL` is the name of the directory in which you have installed GNAT Studio. :file:`HOME` is your home directory, either by default or as overridden by the :file:`GNATSTUDIO_HOME` environment variable. In each directory, only files with :file:`.xml` or :file:`.py` extensions are used. Other files are ignored, although for compatibility with future versions of GNAT Studio you should not have to keep other files in these directories. * Automatically-loaded, global modules The :file:`INSTALL/share/gnatstudio/plug-ins` directory contains the files GNAT Studio automatically loads by default (unless overridden by the user via the :guilabel:`Plugins` section of the preferences editor dialog). These plugins are visible to any user on the system using the same GNAT Studio installation. Reserve this directory for critical plugins that almost everyone will use. * Not automatically-loaded, global modules The :file:`INSTALL/share/gnatstudio/library` directory contain files GNAT Studio displays in the :guilabel:`Plugins` section of the preferences editor dialog but does not load automatically. Typically, these files add optional capabilities to GNAT Studio that many users generally will not use. * :file:`GNATSTUDIO_CUSTOM_PATH` Set this environment variable before launching GNAT Studio to be a list of directories, separated by semicolons (';') on Windows systems and colons (':') on Unix systems. All files in these directories with the appropriate extensions are automatically loaded by default by GNAT Studio, unless overridden by the user through the :guilabel:`Plugins` section of the preferences editor dialog. This is a convenient way to have project-specific customization files. You can, for example, create scripts that set the appropriate value for the variable and then start GNAT Studio. Depending on your project, this allows you to load specific aliases which do not make sense for other projects. These directories are also used to search for icons referenced in your plug-ins. * Automatically loaded user directory The directory :file:`$HOME/.gnatstudio/plug-ins` is searched last. Any script in it is loaded automatically unless overridden via the :guilabel:`Plugins` section of the preferences editor dialog. This is a convenient way for you to create your own plugins or test them before you make them available to all GNAT Studio users by copying them to one of the other directories. * Automatically loaded together with the project When GNAT Studio loads the project file called :file:`.gpr`, it will automatically look for a python file called :file:`.ide.py`. In this file, you are expected to define two parameterless subprograms, called :guilabel:`initialize_project_plugin` and :guilabel:`finalize_project_plugin`; GNAT Studio will call the first one when the project is loaded, and call the second one if/when another project is loaded. If the file is not found GNAT Studio looks for such file for all projects that the root project extends. This method is convenient for providing project-specific behaviors, and means that the GNAT Studio plugin can be checked under version control together with the project file. This feature is implemented via a the GNAT Studio plugin :file:`auto_load.py`. Any script loaded by GNAT Studio can contain customization for various aspects of GNAT Studio, such as aliases, new languages or menus, in a single file. Python files ^^^^^^^^^^^^ You can format the Python plugin in any way you want (as long as it can be executed by Python, of course), the following formatting is suggested. These plugins are visible in the :guilabel:`Plugins` section of the preferences editor dialog, so having a common format makes it easier for users to understand each plugin: * Comment Your script should start with a comment on its goal and usage. This comment should use Python's triple-quote convention, rather than the start-of-line hash ('#') signs. The first line of the comment should be a one line explanation of the goal of the script, separated by a blank line from the rest of the comment. * Implementation Separate the implementation from the initial comment by a form-feed (control-L); the startup scripts editor only displays the first page of the script in the first page of the editor. .. highlight:: python If possible, scripts should avoid executing code when they are loaded. This gives the user a chance to change the value of global variables or override functions before the script is actually launched. Instead, you should connect to the :command:`"gps_started"` hook, as in:: ^L ########################################################### ## No user customization below this line ########################################################### import GPS def on_gps_started (hook_name): ... launch the script GPS.Hook ("gps_started").add (on_gps_started) XML files ^^^^^^^^^ .. highlight:: xml XML files must be UTF8-encoded by default. In addition, you can specify any specific encoding through the standard command:`` declaration, as in the following example:: encoded text These files must be valid XML files, i.e. must start with the `` tag and contain a single root XML node, the name of which is arbitrary. The format is therefore:: ... The first line after the `` tag should contain a comment describing the purpose and usage of the script. This comment is made visible in the the preferences page associated with this plugin, under :guilabel:`Plugins` section of the preferences editor dialog. The list of valid XML nodes that you can specify under :file:`` is described in later sections. It includes: * :ref:`\\ ` * :ref:`\\ ` * :ref:`\\ ` * :ref:`\\ ` * :ref:`\\ ` * :ref:`\\ ` * :ref:`\\ ` * :ref:`\