Python plugin developer guide, part 1

I’m a Python newbie, so if you are at least that good :-D, you should be able to dive in and write useful Python plugins for your favourite editor too! This is the first in what I hope will be a series of notes and tutorials to help you along the way.

Where can I find examples to steal from inspire me?

Any good developer knows that a good way to launch into a new area is to look at examples, so here is a list of places I’ve encountered.

Remember to respect others’ copyrights, and give credit where it is due.

Where do I put my code?

The Pâté Python plugin looks in several places to find usable plugins, you should be able to use the Python console to find a directory you can use for your developments. Select it, and press “Reload”:

Launch it from the View menu, and then ask KDE where your files should go:

Or, if that’s a bit hard to read, like this:

>>> from PyKDE4.kdecore import *

>>> print KStandardDirs.locateLocal(“appdata”,”pate”)

/home/srhaque/.kde/share/apps/kate/pate

Try the directory

If the given directory does not exist, create it. Press Reload, and the new directory should be visible:

You are ready to create your plugin in the new directory! This plugin directory will be added to the initial value of sys.path used for all plugins.

Plugin structure and naming

Your plugin can be just a single .py file, such as “console.py”, or multiple files contained in a directory. A single .py file is useful for simple things, but if you want to use .ui files or multiple Python files, a directory is recommended. If you use this option, the main plugin file must be named after the directory, so:

  • If the directory is called “console”
  • The main plugin file must be named “console/console.py”

In the directory case, the directory is added to sys.path to load the main plugin file and other Python modules you may have. Since sys.path is searched by Python in order to load modules, having the same plugin in multiple locations would be very confusing. Pâté supports this by refusing to load identically named plugins; instead they are highlighted as being hidden:

This also means you can just copy one of the plugins supplied with Kate to get started!

 

Kate in KDE 4.9

With KDE SC 4.9 around the corner and according to tradition, it’s time to have a look at what’s new in Kate.

Improved Support for Custom Color Schemas

  • improved “Colors” tab in the “Fonts & Colors” config page
  • configurable colors: search & replace, code folding, indentation line,
  • schema export and import honor background colors (bug #291868) and font
  • “highlight selection” plugin and “search and replace” plugin now use search & replace colors from Kate’s color schema

Line Modification System

  • new option to disable in the editor settings: Appearance > Borders > [ ] Show line modification markers
  • colors of the line modification system are configurable

Build Plugin

  • reworked config page (including advanced settings for remote debugging)
  • support for remote debugging

Further Changes

  • new option in Open/Save config page: [ ] Add newline at end of file on save
  • all fixes in the bug tracker

Python plugin user guide

KDE 4.9 has branched, and so the Pâté plugin “host” for Python plugins has moved from Kate’s playground to be a mainstream plugin. Since a plugin-for-plugins might be a bit confusing, here is a quick tour of how it is managed and works, and especially a few rough edges it still has.

NOTE If you’ve installed this from a package, hopefully your distro will have added kate.so under PyKDE4 as needed, but if you are building from source, see the notes at the end of this post.

Start by enabling the enabling the Pâté plugin:

That should cause the Pâté plugin’s configuration page to pop into existence, but you may need to press the Reload button to see the right hand pane filled in like this:

Enable specific Python plugins of interest, and press the Reload button. The comment will be set to “Loaded”, then close and reopen the dialog (rough edge #1) to see any new configuration pages that the plugin provides:

Go back to the Pâté plugin’s configuration page, and now look at the second tab:

Use the combo box to select one of the built-in support modules (kate and kate.gui) or any of the loaded plugins. The first tab shows HTML documentation for the Python code and you can see any actions it has added into the Kate UI on the second tab (this will be empty for the built-in modules, but not for console):

It looks as though the Python console has added one entry to the View menu, alog with a shortcut. And so it has:

Yaay! See if you can guess what to do next :-)

 

IF YOU HAVE BUILT FROM SOURCE

And then installed the results in say /usr/local, attempting to enable the plugin may result in a crash with something this on the terminal:

>  File "/home/.../kate/plugins/pate/kate/__init__.py", line 38, in <module> from PyKDE4.kate import Kate
> No module named kate
> Could not import kate"

This is because the Pate build should install kate.so as part of the PyKDE4 bindings, but typically, a developer build will install this locally, and not to where the remaining system-supplied PyKDE4 files are installed:

Install the project...
 -- Install configuration: "RelWithDebInfo"
 -- Up-to-date: /usr/local/lib/python2.7/dist-packages/PyKDE4/kate.so
 ...

The system-supplied PyKDE4 binding modules should be in Python’s sys.path:

srhaque> python
 Python 2.7.3 (default, Apr 20 2012, 22:39:59)
 [GCC 4.6.3] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import sys
 >>> print sys.path
 ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7']

For me, Ubuntu puts PyKDE4 at /usr/lib/python2.7/dist-packages/PyKDE4, so we need a link from there to the actual location:

srhaque> ls -l /usr/lib/python2.7/dist-packages/PyKDE4/kate.so
lrwxrwxrwx 1 root root 53 May 20 09:51 /usr/lib/python2.7/dist-packages/PyKDE4/kate.so -> /usr/local/lib/python2.7/dist-packages/PyKDE4/kate.so

Note that just having this location in PYTHONPATH and/or in sys.path does not work because the PyKDE4 needs an __init__.py to be seen (see the one in the system directory to understand why).

I’ve not thought of a good way to simplify this for developers, and I assume end-users won’t see it because we’ll install in the default path. Suggestions/fixes welcome.

 

Extending Kate with Python

So there I am, a confirmed Kate user, and now I need to find my way around a codebase of over 100,000 files using GNU ID utils. The rather crude answer for Kate 3 was to write a wrapper around the lid(1) utility and the DCOP scripting interface of Kate, all driven from the built-in Konsole. The result was clunky but somewhat usable. But Kate 3? In 2010? Because the version of KDE on our primary development environment is the venerable KDE 3.3!

Eventually though, I decide the time had come for something a little nicer, and the answer seemed to lie in Kate 4 and scripting, except that the Javascript API didn’t seem to offer a way to get to the ID database. That had me stumped for a while until I came across Pâté, which allowed Kate 4 to be extended in Python. Sadly, it was unmaintained and there things stalled until, inexorably, I got to the point where the itch needed scratching.

That most basic driver of Open Source usually comes with strings attached, like the need to find a way to work in a new codebase, and with a new team of hackers. Plus, in the this case, the minor issue of being pretty much a Python newbie. Luckily it turns out that Kate has one of the most responsive teams I’ve encountered, the Pâté code seemed reasonably tractable, and the Python C API solidly documented. What could possibly go wrong? :-) Not that much, because we now have:

  • A Kate plugin based on Pâté
  • A Python debugger console Pâté plugin
  • And oh yes, an ID file integration Pâté plugin

The Kate plugin has a configuration page that allows individual Python plugins to be enabled or disabled, and if need be, system installed plugins to be overridden. Like the original Pâté, Python plugins can hook into Kate’s menus and shortcuts. Unlike the original, this version:

  • Allows Python plugins to supply Kate configuration pages just like native Kate plugins
  • Uses Python pickling to save configuration data, so arbitrary Python objects can be part of a plugin’s configuration
  • Provides for reloading Python plugins, which is really handy when writing new plugins
  • Supported threaded Python
  • Provides direct access to the documentation for Python plugins (though if anybody can figure out how to be information for variables, as well as classes and function, that would be wonderful!)
  • The sample Console and ID plugins try to show a selection of techniques

But help is always welcome to do better (How *should* i18n be done? What might Python 3 involve? What about some decent developer docs?). Any takers or clues much appreciated!