Next: Adding new menus, Previous: Macro arguments, Up: Customizing through XML and Python files

#### 16.5.4 Filtering actions

By default, an action will execute in any context in GPS. The user just selects the menu or key, and GPS tries to execute the action.

It is possible to restrict when an action should be considered as valid. If the current context is incorrect for the action, GPS will not attempt to run anything, and will display an error message for the user.

Actions can be restricted in several ways:

1. Using macro arguments (see Macro arguments). If you are using one of the macro arguments defined in the previous section, anywhere in the chain of commands for that action, GPS will first check that the information is available, and if not will not start running any of the shell commands or external commands for that action.

   For instance, if you have specified `%F` as a parameter to one of the commands, GPS will check prior to running the action that there is a current file. This can be either a currently selected file editor, or for instance that the project view is selected, and a file node inside it is also selected.

   You do not have to specify anything else, this filtering is automatic

   Note however that the current context might contain more information than you expect. For instance, if you click on a file name in the Project View, then the current context contains a file (thus satisfies `%F`), but also contains a project (and thus satisfies `%p` and similar macros).

2. Defining explicit filters Explicit restrictions can be specified in the customization files. These are specified through the `<filter>`, `<filter_and>` and `<filter_or>` tags, see below.

   These tags can be used to further restrict when the command is valid. For instance, you can use them to specify that the command only applies to Ada files, or only if a source editor is currently selected.

##### 16.5.4.1 The filters tags

Such filters can be defined in one of two places in the customization files:

1. At the toplevel. At the same level as other tags such as `<action>`, `<menu>` or `<button>` tags, you can define named filters. These are general filters, that can be referenced elsewhere without requiring code duplication.
2. As a child of the `<action>` tag. Such filters are anonymous, although they provide exactly the same capabilities as the ones above. These are mostly meant for simple filters, or filters that you use only once.

There are three different kinds of tags:

`<filter>`
  This defines a simple filter. This tag takes no child tag.
`<filter_and>`
  All the children of this tag are composed together to form a compound filter. They are evaluated in turn, and as soon as one of them fails, the whole filter fails. Children of this tag can be of type `<filter>`, `<filter_and>` and `<filter_or>`.
`<filter_or>`
  All the children of this tag are composed together to form a compound filter. They are evaluated in turn, and as soon as one of them succeeds, the whole filter succeeds. Children of this tag can be of type `<filter>`, `<filter_and>` and `<filter_or>`.

If several such tags are found following one another under an `<action>` tag, they are combined through "or", i.e. any of the filters may match for the action to be executed.

The `<filter>`, `<filter_and>` and `<filter_or>` tags accept the following set of common attributes:

`name (optional)`
  This attribute is used to create named filters, that can be reused elsewhere in actions or compound filters through the `id` attribute. The name can take any form.
`error (optional)`
  This is the error message printed in the GPS console if the filter doesn't match, and thus the action cannot be executed. If you are composing filters through `<filter_and>` and `<filter_or>`, only the error message of the top-level filter will be printed.

In addition, the `<filter>` has the following specific attributes:

`id (optional)`
  If this attribute is specified, all other attributes are ignored. This is used to reference a named filter previously defined. Here is for instance how you can make an action depend on a named filter:

                <?xml version="1.0" ?>
                <test_filter>
                  <filter name="Test filter" language="ada" />
                  <action name="Test action" >
                     <filter id="Test filter" />
                     <shell>pwd</shell>
                  </action>
                </test_filter>

  A number of filters are predefined by GPS itself.

  `Source editor`
    This filter will only match if the currently selected window in GPS is an editor.
  `Explorer_Project_Node`
    Matches when clicking on a project node in the Project View
  `Explorer_Directory_Node`
    Matches when clicking on a directory node in the Project View
  `Explorer_File_Node`
    Matches when clicking on a file node in the Project View
  `Explorer_Entity_Node`
    Matches when clicking on an entity node in the Project View
  `File`
    Matches when the current context contains a file (for instance the focus is on a source editor, or the focus is on the Project view and the currently selected line contains file information).
`language (optional)`
  This attribute specifies the name of the language that must be associated with the current file to match. For instance, if you specify `ada`, you must have an Ada file selected, or the action won't execute. The language for a file is found by GPS following several algorithms (file extensions, and via the naming scheme defined in the project files).
`shell_cmd (optional)`
  This attribute specifies a shell command to execute. The output value of this command is used to find whether the filter matches: if it returns "1" or "true", the filter matches. In any other case, the filter fails.

  Macro arguments (%f, %p, ...) are fully supported in the text of the command to execute.

`shell_lang (optional)`
  This attribute specifies in which language the shell command above is written. Its default value indicates that the command is written using the GPS shell.
`module (optional)`
  This attribute specifies that the filter only matches if the current window was setup by this specific GPS module. For instance, if you specify "Source_Editor", this filter will only match when the active window is a source editor.

  The list of module names can be obtained by typing `lsmod` in the shell console at the bottom of the GPS window.

  This attribute is mostly useful when creating new contextual menus.

When several attributes are specified for a `<filter>` node (which is not possible with `id`), they must all match for the action to be executed.

         <?xml version="1.0" ?>
         <!-- The following filter will only match if the currently selected
              window is a text editor editing an Ada source file -->
         <ada_editor>
           <filter_and name="Source editor in Ada" >
             <filter language="ada" />
             <filter id="Source editor" />
           </filter_and>

           <!-- The following action will only be executed for such an editor -->

           <action name="Test Ada action" >
              <filter id="Source editor in Ada" />
              <shell>pwd</shell>
           </action>

           <!--  An action with an anonymous filter. It will be executed if the
                 selected file is in Ada, even if the file was selected through
                 the project view  -->

           <action name="Test for Ada files" >
               <filter language="ada" />
               <shell>pwd</shell>
           </action>
         </ada_editor>