Re: [Geany-Devel] My non-C plugin roadmap
Thomas, Thanks for that, it now makes it clearer where you are going, and allows the individual steps to make more sense. I agree with your four problems (shortened): - linkage - keybindings - plugin context - allow for proxies My concern is that the solutions seem complex, though, having followed your attempts over time to address these issues, I do understand that some of the "simple" options don't actually cut it. Will need to think on it further. Cheers Lex On 29 March 2015 at 10:23, Thomas Martitz wrote: > Hello, > > I was asked to share a bit about my roadmap regarding plugins. I'll try to > give you a better idea with this post. > > My ultimate goal is to implement a clean and maintainable way to support > non-C plugins, preferably using existing widely used techniques. I concluded > that libpeas[1] in conjunction with gobject-introspection can provide the > base for this. Since Geany is not at all prepared for this I have several > infrastructure which I do want to get merged into Geany. When Geany core is > sufficiently setup for this, the non-C plugin enablement can happen outside > the core, as a plugin, to stabilize there. > > So, here's the set of infrastructure changes for the core. Please let me > stress that all of this will happen in backward-compatible manner, no > existing plugins break as part of this. > > - linkage-cleanup (PR#429) - This changes the way plugins access Geany API > functions. Instead of exporting a pointer to a struct of structs of API > function pointers, now the APIs are exported directly. This work also > includes an effort to stop exporting all function (we do this currently as a > workaround to allow gtkbuilder to work), so *only* API function are exported > and plugins cannot call internal function anymore. This change is also > required to allow gobject-introspection to find geany functions at runtime > (through g_module_symbol()) in the future. > - new API functions for registering keybindings (PR#376). The current API > functions do not allow context information to be stored and passed to the > key handler function. This makes it very hard for non-C plugins to use these > function. So what's needed are key handlers that get the necessary context > information. This allows interprepted language plugins to register > keybindings. > - A new plugin loader mechanism (a thread about this is already running on > the devel list): Similarly to the keybindings, the plugin_* functions > implemented by plugins do not carry any context information, making it hard > for non-C plugins to implement them properly. Therefore a new loader > mechaism is needed so that the context information can be passed. The loader > works such that an API function is called to register a function pointer > table. This is crucial to possibly support plugins that register other > plugins (so called pluxies) which is simply not possible with the current > mechaism. The current loader is kept for backwards compatibility (but will > not receive new features). > - 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()) > > Once this is in place in the core, my roadmap contains the following items, > which are implemented (at least initially) in a plugin, so no further > changes to the cure should be necessary. > - Modify geanypy to use the new pluxy APIs. This will finally enable geanypy > to show the python plugins in the normal PM dialog and support keybindings > - Create a new pluxy that supports libpeas-based plugins (codename: peasy). > Peasy will use libpeas to load plugins and their metadata. > - Part of the peasy work is also work on creating vala and > gobject-introspection bindings for Geany's API functions, so that we can > support python, javascript and lua out of the box. > > This is my roadmap so far. It changed quite a bit since I started this > non-C-plugins effort a year ago, but I hope it will be good for everyone. > Please share your opinions on this or ask questions. > > Best regards. > ___ > Devel mailing list > Devel@lists.geany.org > https://lists.geany.org/cgi-bin/mailman/listinfo/devel ___ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-bin/mailman/listinfo/devel
[Geany-Devel] My non-C plugin roadmap
Hello, I was asked to share a bit about my roadmap regarding plugins. I'll try to give you a better idea with this post. My ultimate goal is to implement a clean and maintainable way to support non-C plugins, preferably using existing widely used techniques. I concluded that libpeas[1] in conjunction with gobject-introspection can provide the base for this. Since Geany is not at all prepared for this I have several infrastructure which I do want to get merged into Geany. When Geany core is sufficiently setup for this, the non-C plugin enablement can happen outside the core, as a plugin, to stabilize there. So, here's the set of infrastructure changes for the core. Please let me stress that all of this will happen in backward-compatible manner, no existing plugins break as part of this. - linkage-cleanup (PR#429) - This changes the way plugins access Geany API functions. Instead of exporting a pointer to a struct of structs of API function pointers, now the APIs are exported directly. This work also includes an effort to stop exporting all function (we do this currently as a workaround to allow gtkbuilder to work), so *only* API function are exported and plugins cannot call internal function anymore. This change is also required to allow gobject-introspection to find geany functions at runtime (through g_module_symbol()) in the future. - new API functions for registering keybindings (PR#376). The current API functions do not allow context information to be stored and passed to the key handler function. This makes it very hard for non-C plugins to use these function. So what's needed are key handlers that get the necessary context information. This allows interprepted language plugins to register keybindings. - A new plugin loader mechanism (a thread about this is already running on the devel list): Similarly to the keybindings, the plugin_* functions implemented by plugins do not carry any context information, making it hard for non-C plugins to implement them properly. Therefore a new loader mechaism is needed so that the context information can be passed. The loader works such that an API function is called to register a function pointer table. This is crucial to possibly support plugins that register other plugins (so called pluxies) which is simply not possible with the current mechaism. The current loader is kept for backwards compatibility (but will not receive new features). - 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()) Once this is in place in the core, my roadmap contains the following items, which are implemented (at least initially) in a plugin, so no further changes to the cure should be necessary. - Modify geanypy to use the new pluxy APIs. This will finally enable geanypy to show the python plugins in the normal PM dialog and support keybindings - Create a new pluxy that supports libpeas-based plugins (codename: peasy). Peasy will use libpeas to load plugins and their metadata. - Part of the peasy work is also work on creating vala and gobject-introspection bindings for Geany's API functions, so that we can support python, javascript and lua out of the box. This is my roadmap so far. It changed quite a bit since I started this non-C-plugins effort a year ago, but I hope it will be good for everyone. Please share your opinions on this or ask questions. Best regards. ___ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-bin/mailman/listinfo/devel
Re: [Geany-Devel] New plugin loader mechanisms
Hello, based on the discussion I refined my proposal (see below). Additionally I have implemented all of this, including updating demoplugin.c, see [1]. And last but not least, I have a fully working implementation of proxy plugins aka pluxies (in fact, I simply updated my year-old branch to use the new hooks) plus a real-world pluxy for libpeas-based plugins, see [2], [3]. I also formally suggest this work for merging. I havent done a pull request yet, though, because it depends on the linkage-cleanup work, which should be merged first. I do target the 1.25 release still, and I'd absolutely love to if we can make this happen. The changes since my initial proposal summed up: - geany_plugin_register() now additionally takes the API version the plugin is compiled against (in addition to the minimum API it needs and the ABI version). This gives Geany full insight of what the plugin can be expected to work with. - set_info() is removed from the hooks. version_check() is obviously obsolete (the checks are performed within geany_plugin_register()). The plugin is expected to full plugin->info before calling geany_plugin_register() which makes set_info() superfluous - The conceptual role of geany_load_module() is extended: It should also check for plugin-specific runtime dependencies, and return FALSE if such checks fail (as a result the plugin will be hidden from the PM dialog). Otherwise call geany_plugin_register() appropriately. - geany_load_module() passes Geany's API version, sos that plugins can perform their own specific checks based on the API of the currently running Geany instance (this can very well be != the plugins GEANY_API_VERSION) - The GeanyData pointer is now part of GeanyPlugin structure for plugins to access (not passed to init anymore). Actually it was this way in my first version too, but I didn't explicitly mention it. - PluginHooks is renamed to GeanyPluginHooks Now to the (updated) proposal: Please see my initial mail [4] about the motivation and advantages of this work. gboolean geany_load_module(GeanyPlugin *plugin, GModule *module, gint geany_api_version); gboolean geany_plugin_register(GeanyPlugin *plugin, gint api_version, gint min_api_version, gint abi_version, GeanyPluginHooks *hooks, gpointer pdata); typedef struct _GeanyPluginHooks { /** Array of plugin-provided signal handlers (@see PluginCallback) */ PluginCallback *callbacks; /** Called when the plugin is enabled by the user */ void(*init) (GeanyPlugin *plugin, gpointer pdata); /** plugins configure dialog, optional (can be @c NULL) */ GtkWidget* (*configure) (GeanyPlugin *plugin, GtkDialog *dialog, gpointer pdata); /** Called when the plugin should show some help, optional (can be @c NULL) */ void(*help) (GeanyPlugin *plugin, gpointer pdata); /** Called when the plugin is disabled or when Geany exits */ void(*cleanup) (GeanyPlugin *plugin, gpointer pdata); } GeanyPluginHooks; Plugins from now on define a single global function, geany_load_module(), which is called by Geany via pointer obtained from g_module_symbol(). In this function the plugin should perform the following steps: - Test against the passed geany_api_version if it can function under the current Geany. - Test for any additional runtime dependencies - Call geany_plugin_register() appropate and test the return value If any of the above steps fail FALSE should be returned, else TRUE. The plugin shall pass a statically allocated instance of GeanyPluginHooks as part of the geany_plugin_register() call. The function pointers should point to function that are semantically the same as the current plugin_{init,configure,help,cleanup}. Except these function get other parameters and can make use of them. This proposal does not implement pluxies by itself, however I have done the work to implement pluxies on top of the new loader. I will post another mail about this when we finalized the new loader. [1] https://github.com/kugel-/geany/tree/new_hooks [2] https://github.com/kugel-/geany/tree/pluxy [3] https://github.com/kugel-/peasy [4] http://lists.geany.org/pipermail/devel/2015-March/009299.html Please reply with your options or other ideas. Best regards ___ Devel mailing list Devel@lists.geany.org https://lists.geany.org/cgi-bin/mailman/listinfo/devel