Next: , Previous: The GPS Shell, Up: Scripting GPS


16.8.4 The Python Interpreter

Python is an interpreted object-oriented language, created by Guido Van Rossum. It is similar in its capabilities to languages such as Perl, Tcl or Lisp. This section is not a tutorial on python programming. See http://docs.python.org/ to access the documentation for the current version of python.

If python support has been enabled, the python shell is accessible through the Python window at the bottom of the GPS window. You can also display it by using the menu Tools->Consoles->Python.

The full documentation on what GPS makes visible through python is available through the /Help/Python extensions.

The same example that was used to show the GPS shell follows, now using python. As you can notice, the name of the commands is similar, although they are not run exactly in the same way. Specifically, GPS benefits from the object-oriented aspects of python to create classes and instances of these classes.

In the first line, a new instance of the class Entity is created through the create_entity function. Various methods can then be applied to that instance, including find_all_refs, which lists all references to that entity in the location window:

     >>> e=GPS.Entity ("entity_name", "file_name.adb")
     >>> e.find_all_refs()

The screen representation of the classes exported by GPS to python has been modified, so that most GPS functions will return an instance of a class, but still display their output in a user-readable manner.

Python has extensive introspection capabilities. Continuing the previous example, you can find what class e is an instance of with the following command:

     >>> help(e)
     Help on instance of Entity:
     
     <GPS.Entity instance>

It is also possible to find all attributes and methods that can be applied to e, as in the following example:

     >>> dir (e)
     ['__doc__', '__gps_data__', '__module__', 'called_by', 'calls',
     'find_all_refs']

Note that the list of methods may vary depending on what modules were loaded in GPS, since each module can add its own methods to any class.

In addition, the list of all existing modules and objects currently known in the interpreter can be found with the following command:

     >>> dir ()
     ['GPS', 'GPSStdout', '__builtins__', '__doc__', '__name__', 'e', 'sys']

You can also load and execute python scripts with the execfile command, as in the following example:

     >>> execfile ("test.py")

Python supports named parameters. Most functions exported by GPS define names for their parameters, so that you can use this Python feature, and make your scripts more readable. A notable exception to this rule are the functions that take a variable number of parameters. Using named parameters allows you to specify the parameters in any order you wish, e.g:

     >>> e=GPS.Entity (name="foo", file="file.adb")

16.8.5 Python modules

On startup, GPS will automatically import (with python's import command) all the files with the extension .py found in the directory $HOME/.gps/plug-ins, the directory $prefix/share/gps/plug-ins or in the directories pointed to by GPS_CUSTOM_PATH. These files are loaded only after all standard GPS modules have been loaded, as well as the custom files, and before the script file or batch commands specified on the command lines with the --eval or --load switches.

As a result, one can use the usual GPS functions exported to python in these startup scripts. Likewise, the script run from the command line can use functions defined in the startup files.

Since the import command is used, the functions defined in this modules will only be accessible by prefixing their name by the name of the file in which they are defined. For instance if a file mystartup.py is copied to the startup directory, and defines the function func, then the latter will be accessible in GPS through mystartup.func.

Python's own mechanism for loading files at startup (the environment variable PYTHONSTARTUP) is not suitable for use within the context of GPS. When python is loaded by GPS, the GPS module itself is not yet available, and thus any script that depends on that module will fail to load correctly. Instead, copy your script to one of the plug-ins directories, as documented above.

If you are writing a set of python scripts that other people will use, you need to provide several things:

The following example defines a python command that inserts a line full of dashes ('-') at the current cursor location. This command is associated with the key binding <control-c n>, and can be distributed as a single XML file.

     # This code can be stored in a file test.py in $HOME/.gps/plug-ins
     from GPS import *
     
     def add_dashes_line():
        Editor.replace_text (current_context().file().name(),
                             current_context().location().line(),
                             current_context().location().column(),
                             "--------------------------------", 0, 0)
     GPS.parse_xml ("""
        <action name="dashes line">
           <shell lang="python">test.add_dashes_line()</shell>
           <context>Source editor</context>
        </action>
        <key action="dashes line">control-c n</key>
     """)
     

Several complex examples are provided in the GPS distribution, in the directory examples/python. These are modules that you might want to use for your own GPS, but more important that will show how GPS can be extended from Python.

If your script doesn't do what you expect it to do, there are several ways to debug it, among which the easiest is probably to add some "print" statements. Since some output of the scripts is sometimes hidden by GPS (for instance for interactive commands), you might not see this output.

In this case, you can reuse the tracing facility embedded in GPS itself. Modify the file $HOME/.gps/traces.cfg, and add the following line:

     PYTHON.OUT=yes

This will include the python traces as part of the general traces available in the file $HOME/.gps/log. Note that it may slow down GPS if there is a lot of output to process.