[Geany-devel] GeanyPy Keybindings Again

Lex Trotman elextr at xxxxx
Mon Sep 12 23:37:24 UTC 2011

Hi Matthew,

On 13 September 2011 06:16, Matthew Brush <mbrush at codebrainz.ca> wrote:
> Hi,
> I started working on keybindings again for GeanyPy and I was hoping to get a
> little advice from the experts.

Can't provide any of that, but can heckle from the cheap seats :)

> I've hacked together some code that allows the single GeanyPy plugin to
> create new GeanyPlugin structs so that it can add multiple keygroups for the
> single plugin.  This actually seems to work fairly well considering how
> kludgey the implementation is (ie. copying structs from Geanys code into
> GeanyPy's code because they aren't exposed, etc.).

After 0.21 release extensions of the plugin interface can be
considered of course.

> Now I have two remaining challenges to overcome.  The first is that there
> doesn't seem to be a way to remove/delete a keygroup, that is to undo what
> plugin_set_keygroup does.  The function I think I need is
> keybindings_free_group(), but it's not in the plugin API, and I can't "fake"
> it like I've done with other parts since it requires the
> `keybinding_groups`.  So basically what's happening, is when a Python plugin
> is unloaded and is cleaned up, I free the "sub" GeanyPlugin and all it's
> memory.  Now when you go into the Preferences->Keybindings you see just
> weird things where the plugin name/keybindings were, presumably since Geany
> is reading from freed/adjacent memory or some such.

ATM plugin keygroups are unloaded automagically on plugin free.  We
need to keep that behavior or break all other plugins.

My suggestion is that plugins.c be extended so that each plugin can
have a list of keygroups (ie priv->key_group is a gslist). Unloading
the plugin should free all the keygroups in the list.

Then add to pluginutils a function to remove a keygroup from that list
(and which calls keybindings_free_group() in the background).  Geanypy
can call that when a "sub-plugin" goes away.

> So the first question is, is there a way to remove a plugin/keygroup from
> those registered with Geany?  At this point, I don't really care if it's a
> kludgey solution, I just want it working :)

Tut, tut, surely you want to find the elegant recursive provably
correct functional solution that runs in treacle :-)

> The second challenge I'm facing is coming up with a way for GeanyPy to
> manage connection of Python plugins keybindings and dispatching to them when
> a keybinding is pressed.  What I've done so far is, as mentioned above, to
> create a phony GeanyPlugin/GeanyKeygroup for each plugin, and each plugin
> gets allotted KEYBINDINGS_MAX bindings using the plugin_set_keygroup()
> function.  The problem I'm having now is how to associate the Python plugin
> (consider it a C struct if it helps) with the keybinding.  It seems like it
> would be easier if there was possibility of passing a closure or whatever
> it's called when connecting to the key binding, but GeanyKeyCallback doesn't
> seem to support this. I've a tried and failed so far with a few different
> ideas.  So, can anyone recommend a decent way of mapping which Python plugin
> connected to which keybinding and then call out to the plugin when the
> keybinding is activated?

Presumably you know how to call back into the interpretor (if not I
suggest looking at how PyGTK does it) so its just a matter of mapping
from the key_id to a Python callable, I'd have all keys call one
Python method that just looks up a callable in a dict by key_id.
Clearly that means you don't expose the Geany's set key but a new
Python function that records the key in the dict and calls Geany's set

> One last thing since I'm already writing a really long email, I notice in
> keybindings.h[1] in the GeanyKeyGroup definition, there's a 'plugin' member
> that is mentioned elsewhere in keybindings.c (I think) as being used by
> GeanyLua or some such.  What is this for, and would it be useful for what
> I'm trying to do with GeanyPy?

No just distinguishes between native and plugin keybindings.  Dunno
what the Lua references are.  Note that IIUC GeanyLua doesn't do any
of what you are trying to do so its not surprising that you need new
functionality in the plugin interface.

> Also, why is the comment above the definition "Plugins should not set these
> fields", while the comment for the 'plugin' member says "Used by plugins"?

Comment means this keybinding is "Used by plugin" if it is true.

> [1] http://git.geany.org/geany/tree/src/keybindings.h#n58
> Apologies for the really long message, but I'm at a bit of a loss (yet
> again).

Not lost, just geographically embarrassed :)


More information about the Devel mailing list