[Geany-Devel] My non-C plugin roadmap

Thomas Martitz kugel at xxxxx
Sun Mar 29 22:17:44 UTC 2015

Am 29.03.2015 um 19:17 schrieb Colomban Wendling:
> Le 29/03/2015 00:23, Thomas Martitz a écrit :
>> - New API functions to allow plugins to act as proxy plugins (pluxies).
>> These pluxies can then implement whatever is needed to execute code in
>> the in the actual plugin, like invoking an interpreter or firing up a
>> java vm. The pluxies call the new loader's API function on behalf of the
>> actual plugin. The API function to implement the pluxies is a simple
>> geany_register_pluxy() that, much like the normal plugin loader, that
>> pluxies use to pass a function pointer table which implements the
>> necessary hooks (probe(), load() and unload())
> That's the part I'm really fuzzy about.  I really don't see why we need
> this specific layer (maybe in an ideal world not bothering about how
> Geany currently does it): as asked on the other thread, why do we need
> anything beside geany_plugin_register() (required for everyone) and
> geany_plugin_unregister() (required only when registered sub-plugins, as
> the parent need to clean them up when it itself quits)?

I'll answer this question here in the hope the other thread can 
concentrate on the new loader itself. But it also kind of depends on how 
I designed the loader so I guess there will be some cross talk.

As with git master, Geany's core loader scans the plugin folder on 
startup and on opening the PM dialog. For each recognized plugin file it 
allocates a GeanyPluginPrivate and calls geany_load_module().

So this is where we come from:
- Geany initiates the scan (on behalf of the user)
- Geany has certain files it recognizes as plugins. It won't attempt 
other files.
- Geany allocates and frees the structure that holds everything it needs 
to know, this structure is opaque for actual plugins (and we need this 
to be able to extend it)

So, to support pluxies as first class citizens, I designed it such that 
Geany becomes able to scan additional files and hand the initialization 
of plugins to the proxy (instead of calling geany_load_module()). The 
idea is that Geany still performs the actual scan and builds up the 
plugin list in the PM dialog, so it's completely synchronous. Geany 
should still allocate the GeanyPluginPrivate structure for each plugin, 
for the proxied ones too. Note that proxy plugins too call the same 
geany_plugin_register() on behalf of the proxied plugins, like standard 
plugins have to too. Geany fully supervises which plugins are loaded, 
and when, so that it can provide a unified experience for the user, 
regardless of the plugin type that's behind the scenes.

Therefore my mechanism is based on plugins letting Geany know which 
files they can support, so that Geany's loader can scan for plugin files 
like ever, except it can match more types, and calls into the proxy to 
complete loading. For unloading the proxy is also called, to complete 
plugin finalization. For this, plugins need a way to provide Geany with 
the information it needs to load the additional plugins: file 
extension(s), and load/unload callbacks (and a probe, to resolve 
ambiguous file extensions).

To give a practical example:

with my new loader (no pluxies) it goes like this, and this is *very* 
similar to git master.

 > user opens PM dialog
1 Geany calls load_all_plugins(), which calls load_plugins_from_path($path)
2 for each $file in $path, Geany checks if the extension is 
G_MODULE_SUFFIX, and calls plugin_new($file, ...)
3 plugin_new() calls the plugins's  geany_load_module() (if new-style 
plugin, calls version_check, set_info() for old-style ones)
4 geany_load_module() is implemented by the plugin, and registers itself 
with geany_plugin_register()
< geany_plugin_register() adds the plugin to the plugin list, so that 
the PM can sort and show it

Now, with pluxies, it is completely the same except for:
2* for each $file in $path, Geany calls is_plugin($file) which matches 
additional file extensions (as provided by pluxies), it also calls the 
probe() hook to resolve ambiguous files (e.g. .so files, they can be 
core or libpeas plugins)
3* plugin_new() calls the load() hook registered by pluxies for the 
given extension. for standard plugins (without proxy) there is a 
predefined plugin_load_so() funtion that gets called instead.
4* The load-hook calls geany_plugin_register(), here Geany core and 
proxies work the same way

I designed it such, that the difference between standard plugins and 
proxied plugins is all contained in the load hook. The rest of Geany 
does not know about the difference. This ensures proxied plugins are 
first class citizens.

I hope you better understand my concept now. Let me emphasize again that 
it's focused having relatively little impact on Geany's core or existing 
plugins so that we can smoothly transition to a new non-C plugin world 
full of joy!

Best regards

More information about the Devel mailing list