Merge pull request #469 from kugel-/new_hooks
[geany-mirror.git] / doc / plugins.dox
blobc58081dcb6fec36db452afba194ece2b7473214e
1 /*
2  * plugins.dox - this file is part of Geany, a fast and lightweight IDE
3  *
4  * Copyright 2008-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5  * Copyright 2008-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
6  * Copyright 2009-2012 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
7  * Copyright 2014 Matthew Brush <matt(at)geany(dot)org>
8  * Copyright 2015 Thomas Martitz <kugel(at)rockbox(dot)org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  *
24  * This file contains additional plugin documentation like the signal system
25  * and a small howto. It is best viewed when filetype is set to C or C++.
26  */
29 /**
31 @mainpage Geany Plugin API Documentation
33 @author Enrico Tröger, Nick Treleaven, Frank Lanitz, Matthew Brush
35 @section Intro
36 This is the Geany API documentation. It should be considered work in progress.
37 We will try to document as many functions and structs as possible.
39 @warning Do not use any symbol not in the documentation - it may change.
40 @warning Except for exceptions stated in the documentation for geany_load_module(), no API function
41 may be called if the plugin is not enabled (between the calls to their GeanyFuncs::init and
42 GeanyFuncs::cleanup functions).
44 @section pluginsupport Plugin Support
45 - @link howto Plugin HowTo @endlink - get started
46 - @ref legacy
47 - @link plugindata.h Plugin Datatypes and Macros @endlink
48 - @link pluginsignals.c Plugin Signals @endlink
49 - @link pluginutils.h Plugin Utility Functions @endlink
50 - @link guidelines Plugin Writing Guidelines @endlink
51 - <b>plugins/demoplugin.c</b> - in Geany's source, bigger than the howto example
53 @section common Common API files
54 - @link dialogs.h @endlink
55 - @link document.h @endlink
56 - @link editor.h @endlink
57 - @link filetypes.h @endlink
58 - @link keybindings.h @endlink
59 - @link msgwindow.h @endlink
60 - @link project.h @endlink
61 - @link sciwrappers.h Scintilla Wrapper Functions @endlink
62 - @link spawn.h Spawning programs @endlink
63 - @link stash.h Stash Pref/Setting Functions @endlink
64 - @link utils.h General Utility Functions @endlink
65 - @link ui_utils.h Widget Utility Functions @endlink
67 @section More
68 - All API functions and types - see <b>Files</b> link at the top
69 - Deprecated symbols - see <b>Related Pages</b> link at the top
71 @note See the HACKING file for information about developing the plugin API and
72 other useful notes.
74 @page guidelines Plugin Writing Guidelines
76 @section intro_guidelines Introduction
78 The following hints and guidelines are only recommendations. Nobody is forced to follow
79 them at all.
81 @section general General notes
83 @subsection ideas Getting a plugin idea
85 If you want to write a plugin but don't know yet what it should do, have a look at
86 http://www.geany.org/Support/PluginWishlist to get an idea about what users wish.
88 @subsection code Managing the source code
90 For authors of plugins for Geany, we created a dedicated @a geany-plugins project
91 on Sourceforge and GitHub to ease development of plugins and help new authors.
92 All information about this project you can find at http://plugins.geany.org/
94 To add a new plugin to this project, get in touch with the people on the
95 geany-devel-mailing list and create a fork of the geany-plugins project
96 at https://github.com/geany/geany-plugins.
97 Beside of adding a new plugin, geany-devel-mailing list is also the place where
98 to discuss development related questions.
99 However, once you have done your fork of geany-plugins you can develop
100 your plugin until you think its the right time to publish it. At this point,
101 create a pull request for adding your patch set into the master branch of the main
102 geany-plugins repository.
104 Of course, you don't need to use GitHub - any Git is fine. But GitHub
105 is making it way easier for review, merging and get in touch with you for
106 comments.
108 If you don't want your plugin to be part of the geany-plugins project it is also fine.
109 Just skip the part about forking geany-plugins and sending a pull request.
110 In this case it is of course also a good idea to post some kind of announcement
111 to geany-devel and maybe to the main geany mailing list -- it's up to you.
112 You can also ask for your plugin to be listed on the http://plugins.geany.org/
113 website as a third party plugin, helping Geany user to know about your plugin.
115 At time of writing, there are some plugins already available in the
116 repositories. Feel free to use any of these plugins as a start for your own,
117 maybe by copying the directory structure and the autotools files
118 (Makefile.am, configure.in, ...). Most of the available plugins are also ready for
119 i18n support, just for reference.
121 We encourage authors using this service to only commit changes to their
122 own plugin and not to others' plugins. Instead just send patches to
123 geany-devel at uvena.de or the plugin author directly.
125 @section paths Installation paths
127 - The plugin binary (@c pluginname.so) should be installed in Geany's libdir. This is
128   necessary so that Geany can find the plugin.
129   An easy way to retrieve Geany's libdir is to use the pkg-config tool, e.g. @code
130   `$PKG_CONFIG --variable=libdir geany`/ geany
131   @endcode
132 - If your plugin creates other binary files like helper programs or helper libraries,
133   they should go into @c $prefix/bin (for programs, ideally prefixed with @a geany),
134   additional libraries should be installed in Geany's libdir, maybe in a subdirectory.
135 - Plugins should install their documentation files (README, NEWS, ChangeLog, licences and
136   other documentation files) into the common documentation directory
137   @c $prefix/share/doc/geany-plugins/$pluginname/
138 - Translation files should be installed normally into @c $prefix/share/locale. There is no
139   need to use Geany's translation directory. To set up translation support properly and
140   for additional information, see main_locale_init().
141 - Do @a never install anything into a user's home directory like installing
142   the plugin binary in @c ~/.config/geany/plugins/.
145 @page howto Plugin HowTo
147 @section intro_howto Introduction
149 Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
150 add new features. This document gives a brief overview about how to add new
151 plugins by writing a simple "Hello World" plugin in C or C++.
154 @section buildenv Build environment
156 To be able to write plugins for Geany, you need the source code and some development
157 packages for GTK and its dependencies. The following will only describe the way to compile and
158 build plugins on Unix-like systems [1].
159 If you already have the Geany source code and compiled it from them, you can skip the
160 following.
162 First you need to have Geany installed. Then install the development files for GTK
163 and its dependencies. The easiest way to do this is to use your distribution's package
164 management system, e.g. on Debian and Ubuntu systems you can use
165 @code apt-get install libgtk2.0-dev intltool @endcode
166 This will install all necessary files to be able to compile plugins for Geany. On other
167 distributions, the package names and commands to use may differ.
169 Basically, you are done at this point and could continue with writing the plugin code.
171 [1] For Windows, it is basically the same but you might have some more work on setting up
172 the general build environment(compiler, GTK development files, ...). This is described on
173 Geany's website at http://www.geany.org/Support/BuildingOnWin32.
175 @section helloworld "Hello World"
177 @note This section describes the new entry points for plugins introduced with Geany 1.26. A short
178 summary of the legacy entry points is given at page @ref legacy but they are deprecated should not
179 be used any more.
181 When writing a plugin you will find a couple of functions which are mandatory and some which can be
182 implemented optionally for implementing some useful features once your plugin becomes more
183 powerful. For example to provide a configuration or help dialog.
185 @subsection beginning First steps for any Plugin
187 You should start your plugin with including <geanyplugin.h> and exporting a function named @a
188 geany_load_module(). In this function you must fill in basic information that Geany uses to learn
189 more about your plugin and present it to the user. You also must define some hooks that enable
190 Geany to actually execute your code.
192 Please also do not forget about license headers which are by convention at the start of source
193 files. You can use templates provided by Geany to get started. Without a proper license it will be
194 difficult for packagers to pick up and distribute your plugin.
196 As mentioned above, start with the very fundamental header that gets you all goodies of Geany's
197 plugin API. @a geanyplugin.h includes all of the Geany API and also the necessary GTK header
198 files so there is no need to include @a gtk/gtk.h yourself. In fact it includes a utility header
199 that helps supporting GTK+2 and GTK+3 in the same source.
201 @code
202 #include <geanyplugin.h>
203 @endcode
205 @note If you use autoconf then config.h must be included even before that as usual.
207 Now you can go on and write your first lines for your new plugin. As mentioned before, you will
208 need to implement a couple of functions. The first mandatory one is @a geany_load_module(). Geany
209 uses the presence fo this function to identify a library as a plugin. When Geany scans the
210 pre-defined and user-configured plugin directories, it will take a look at each shared library (or
211 DLL on Windows) to see if it exports a @a geany_load_module() symbol. Files lacking these will be
212 ignored. The second mandatory one is an initialization function that is only called when the plugin
213 becomes actually enabled (by the user or at startup).
215 @subsection register Registering a Plugin
217 Geany will always invoke this geany_load_module(), regardless of whether the user activates your
218 plugin. In fact its purpose to probe if the plugin should even be presented to the user. Therefore
219 you must use this function to register your plugin. Geany will pass a pointer to a GeanyPlugin
220 instance which acts as a unique handle to your plugin. Use this pointer for registering and later
221 API calls. It won't change for the life time of the plugin. Registering the plugin consists of a
222 number of steps:
224   1. Filling in GeanyPlugin::info with metadata that is shown to the user.
225     - @ref PluginInfo::name : The name of your plugin
226     - @ref PluginInfo::description : A brief description.
227     - @ref PluginInfo::version : The plugin's version.
228     - @ref PluginInfo::author : Your contact information, preferably in the form "Name <email>".
229     .
230     Filling in all of them is recommended to provide the best user experience, but only the name is
231     truly mandatory. Since all of the strings are shown to the user they should be human readable.
232   2. Filling in GeanyPlugin::funcs with function pointers that are called by Geany.
233     - @ref GeanyPluginFuncs::init : an initialization function
234     - @ref GeanyPluginFuncs::cleanup : a finalization function
235     - @ref GeanyPluginFuncs::configure : a function that provides configuration (optional)
236     - @ref GeanyPluginFuncs::help : a function that provides help (optional)
237     - @ref GeanyPluginFuncs::callbacks : a pointer to an array of PluginCallback (optional).
238     .
239     @a init and @a cleanup are mandatory, the other ones depend on how advanced your plugin is.
240     Furthermore, @a init is called on startup and when the user activates your plugin in the Plugin
241     Manager, and @a cleanup is called on exit and when the user deactivates it. So use these to do
242     advanced initialization and teardown as to not waste resources when the plugin is not even
243     enabled.
244   3. Actually registering by calling GEANY_PLUGIN_REGISTER() or GEANY_PLUGIN_REGISTER_FULL().
245    - Usually you should use GEANY_PLUGIN_REGISTER() to register your plugin, passing the
246     GeanyPlugin pointer that you received and filled out as above. GEANY_PLUGIN_REGISTER() also
247     takes the minimum API version number you want to support (see @ref versions for details). Please
248     also <b>check the return value</b>. Geany may refuse to load your plugin due to
249     incompatibilities, you should then abort any extra setup. GEANY_PLUGIN_REGISTER() is a macro
250     wrapping geany_plugin_register() which takes additional the API and ABI that you should not pass
251     manually.
252    - If you require a plugin-specific context or state to be passed to your GeanyPlugin::funcs then
253     use GEANY_PLUGIN_REGISTER_FULL() to register. This one takes additional parameters for adding
254     user data to your plugin. That user data pointer is subsequently passed back to your functions.
255     It allows, for example, to set instance pointer to objects in case your plugin isn't written in
256     pure C, enabling you to use member functions as plugin functions. You may also set such data
257     later on, for example in your @ref GeanyPluginFuncs::init routine to defer costly allocations
258     to when the plugin is actually activated by the user. However, you then have to call
259     geany_plugin_set_data().
262 @subsection versions On API and ABI Versions
263 As previously mentioned @a geany_plugin_register() takes a number of versions as arguments:
264   1. api_version
265   2. min_api_version
266   3. abi_version
268 These refer to Geany's versioning scheme to manage plugin compatibility. The following rules apply:
269   - Plugins are compiled against a specific Geany version on the build machine. This version of
270     Geany has specific ABI and API versions, which will be compiled into the plugin. Both are
271     managed automatically, by calling GEANY_PLUGIN_REGISTER().
272   - The Geany version that loads the plugin may be different, possibly even have different API and
273     ABI versions.
274   - The ABI version is the primary plugin compatibility criteria. The ABI version of the running
275     Geany and the one that's compiled into the plugin must match exactly (==). In case of mismatch,
276     the affected plugins need to be recompiled (generally without source code changes) against the
277     running Geany. The ABI is usually stable even across multiple releases of Geany.
278   - The API version is secondary. It doesn't have to match exactly, however a plugin can report
279     a minimum API version that it requires to run. Geany will check if its own API is larger than
280     that (>=) and will otherwise refuse to load the plugin. The API version is incremented when
281     functions or variables are added to the API which often happens more than once within a release
282     cycle.
283   - The API version the plugin is compiled against is still relevant for enabling compatibility
284     code inside Geany (for cases where incrementing the ABI version could be avoided).
286 Instead of calling geany_plugin_register() directly it is very highly recommended to use
287 GEANY_PLUGIN_REGISTER(). This is a convenient way to pass Geany's current API and ABI versions
288 without requiring future code changes whenever either one changes. In fact, the promise that
289 plugins need to be just recompiled on ABI change can hold if the plugins use this macro. You still
290 want to pass the API version needed at minimum to run your plugin. The value is defined in
291 plugindata.h by @ref GEANY_API_VERSION. In most cases this should be your minimum. Nevertheless when
292 setting this value, you should choose the lowest possible version here to make the plugin
293 compatible with a bigger number of versions of Geany. The absolute minimum is 225 which introduced
294 the new plugin entry points.
296 To increase your flexibility the API version of the running Geany is passed to geany_load_module().
297 You can use this information to toggle API-specific code. This comes handy, for example to enable
298 optional code that requires a recent API version without raising your minimum required API version.
299 This enables running the plugin against more Geany versions, although perhaps at reduced
300 functionality.
302 @subsection example Example
304 Going back to our "Hello World" plugin here is example code that properly adds the HelloWorld
305 plugin to Geany.
307 @code
308 /* License blob */
310 #include <geanyplugin.h>
313 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
315         printf("Hello World from plugin!\n");
317         /* Perform advanced set up here */
319         return TRUE;
323 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
325         printf("Bye World :-(\n");
329 G_MODULE_EXPORT
330 void geany_load_module(GeanyPlugin *plugin)
332         /* Step 1: Set metadata */
333         plugin->info->name = "HelloWorld";
334         plugin->info->description = "Just another tool to say hello world";
335         plugin->info->version = "1.0";
336         plugin->info->author = "John Doe <john.doe@example.org>";
338         /* Step 2: Set functions */
339         plugin->funcs->init = hello_init;
340         plugin->funcs->cleanup = hello_cleanup;
342         /* Step 3: Register! */
343         if (GEANY_PLUGIN_REGISTER(plugin, 225))
344                 return;
345         /* alternatively:
346         GEANY_PLUGIN_REGISTER_FULL(plugin, 225, data, free_func); */
348 @endcode
350 If you think this plugin seems not to implement any functionality right now and only wastes
351 some memory, you are right. But it should compile and load/unload in Geany nicely.
352 Now you have the very basic layout of a new plugin. Great, isn't it?
354 If you would rather write the plugin in C++, you can do that by marking @a geany_load_module()
355 as <c> extern "C" </c>, for example:
357 @code
359 extern "C" void geany_load_module(GeanyPlugin *plugin)
363 @endcode
365 You can also create an instance of a class and set that as data pointer (with
366 GEANY_PLUGIN_REGISTER_FULL()). With small wrappers that shuffle the parameters you can even use
367 member functions for @ref GeanyPlugin::funcs etc.
369 @section building Building
371 First make plugin.o:
373 @code gcc -c plugin.c -fPIC `pkg-config --cflags geany` @endcode
375 Then make the plugin library plugin.so (or plugin.dll on Windows):
377 @code gcc plugin.o -o plugin.so -shared `pkg-config --libs geany` @endcode
379 If all went OK, put the library into one of the paths Geany looks for plugins,
380 e.g. $prefix/lib/geany. See @ref paths "Installation paths" for details.
382 If you are writing the plugin in C++, then you will need to use your C++
383 compiler here, for example @c g++.
385 @section realfunc Adding functionality
387 Let's go on and implement some real functionality.
389 As mentioned before, GeanyPluginFuncs::init() will be called when the plugin is activated by
390 Geany. So it should implement everything that needs to be done during startup. In this case, we'd
391 like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
393 @code
394 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
396         GtkWidget *main_menu_item;
398         // Create a new menu item and show it
399         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
400         gtk_widget_show(main_menu_item);
402         // Attach the new menu item to the Tools menu
403         gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu),
404                 main_menu_item);
406         // Connect the menu item with a callback function
407         // which is called when the item is clicked
408         g_signal_connect(main_menu_item, "activate",
409                 G_CALLBACK(item_activate_cb), NULL);
411         return TRUE;
413 @endcode
415 This will add an item to the Tools menu and connect this item to a function which implements what
416 should be done when the menu item is activated by the user. This is done by g_signal_connect(). The
417 Tools menu can be accessed with plugin->geany_data->main_widgets->tools_menu. The structure
418 GeanyMainWidgets contains pointers to all main GUI elements in Geany.
420 Geany has a simple API for showing message dialogs. So our function contains
421 only a few lines:
422 @code
423 static void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
425         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
427 @endcode
429 For the moment you don't need to worry about the parameters of that function.
431 Now we need to clean up properly when the plugin is unloaded.
433 To remove the menu item from the Tools menu you can use gtk_widget_destroy().
435 First you should add gtk_widget_destroy() to your GeanyPluginFuncs::cleanup() function. The
436 argument for gtk_widget_destroy() is the widget object you created earlier in
437 GeanyPluginFuncs::init(). To be able to access this pointer in GeanyPluginFuncs::cleanup() you can
438 use geany_plugin_set_data() to set plugin-defined data pointer to the widget. Alternatively, you
439 can store the pointer in some global variable so its visibility will increase and it can be
440 accessed in all functions.
442 @code
443 /* alternative: global variable:
444 static GtkWidget *main_menu_item;
446 // ...
447 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
449         GtkWidget *main_menu_item;
451         // Create a new menu item and show it
452         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
453         gtk_widget_show(main_menu_item);
454 // ...
455         geany_plugin_set_data(plugin, main_menu_item, NULL);
456         return TRUE;
459 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
461         GtkWidget *main_menu_item = (GtkWidget *) pdata;
462 // ...
463         gtk_widget_destroy(main_menu_item);
465 @endcode
467 This will ensure your menu item is removed from the Tools menu as well as from
468 memory once your plugin is unloaded, so you don't leave any memory leaks.
469 Once this is done, your first plugin is ready. Congratulations!
471 @section listing Complete listing (without comments)
473 @code
475 #include <geanyplugin.h>
477 static void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
479         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
483 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
485         GtkWidget *main_menu_item;
487         // Create a new menu item and show it
488         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
489         gtk_widget_show(main_menu_item);
490         gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu),
491                         main_menu_item);
492         g_signal_connect(main_menu_item, "activate",
493                         G_CALLBACK(item_activate_cb), NULL);
495         geany_plugin_set_data(plugin, main_menu_item, NULL);
496         return TRUE;
500 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
502         GtkWidget *main_menu_item = (GtkWidget *) pdata;
504         gtk_widget_destroy(main_menu_item);
508 G_MODULE_EXPORT
509 void geany_load_module(GeanyPlugin *plugin)
511         plugin->info->name = "HelloWorld";
512         plugin->info->description = "Just another tool to say hello world";
513         plugin->info->version = "1.0";
514         plugin->info->author = "John Doe <john.doe@example.org>";
516         plugin->funcs->init = hello_init;
517         plugin->funcs->cleanup = hello_cleanup;
519         GEANY_PLUGIN_REGISTER(plugin, 225);
521 @endcode
524 Now you might like to look at Geany's source code for core plugins such as
525 @a plugins/demoplugin.c.
527 @section furtherimprovements Further Improvements and next steps
528 @subsection translatable_plugin_information Translatable plugin information
530 After having written our first plugin, there is still room for improvement.
532 By default, @ref geany_load_module() is not prepared to allow translation of the basic plugin
533 information, except plugins which are shipped with Geany's core distribution, because custom
534 gettext catalogs are not setup. Since most plugins are not shipped with Geany's core, it makes
535 sense to setup gettext when the plugin is loaded so that it gets translated inside Geany's Plugin
536 Manager. The solution is to call the API function main_locale_init() inside @ref
537 geany_load_module() and then use gettext's _() as usual.
539 The invocation will most probably look similar to this:
540 @code
541 // ...
542         main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
543         plugin->info->name = _("HelloWorld");
544         plugin->info->description = _("Just another tool to say hello world");
545         plugin->info->version = "1.0";
546         plugin->info->author = "John Doe <john.doe@example.org>";
547 @endcode
549 The @a LOCALEDIR and the @a GETTEXT_PACKAGE parameters are usually set inside the build system.
551 As you can see the author's information is not marked as translatable in
552 this example.  The community has agreed that the best practice here is to
553 use, if possible, the latin version of the author's name followed by the
554 native spelling inside parenthesis, where applicable.
556 @subsection plugin_i18n Using i18n/l10n inside Plugin
559 You can (and should) also mark other strings beside the plugin's meta information as translatable.
560 Strings used in menu entries, information boxes or configuration dialogs should be translatable as
561 well.
563 @code
564 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
566         main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
567         main_menu_item = gtk_menu_item_new_with_mnemonic(_("Hello World"));
568 // ...
570 @endcode
572 @page legacy Porting guide from legacy entry points to the current ones
574 @section intro_legacy Introduction
576 This page briefly describes the deprecated, legacy plugin entry points. These have been in place
577 prior to Geany 1.26 and are still loadable and working for the time being. However, do not create
578 new plugins against these. For this reason, the actual description here is rather minimalistic and
579 concentrates on porting legacy plugins to the new interface. Basically it's main purpose
580 is to give newcomers an idea of what they are looking at if they come across a legacy plugin.
582 @section overview Overview
584 The legacy entry points consist of a number of pre-defined symbols (functions and variables)
585 exported by plugins. There is no active registration procedure. It is implicit simply by exporting
586 the mandatory symbols. The entirety of the symbols is described at the page @link pluginsymbols.c
587 Plugin Symbols @endlink.
589 At the very least plugins must define the functions @a plugin_init(GeanyData *) and @a
590 plugin_version_check(gint). Additionally, an instance of the struct PluginInfo named plugin_info
591 must be exported as well, this contains the same metadata already known from GeanyPlugin::info. The
592 functions plugin_cleanup(), plugin_help(), plugin_configure(GtkDialog *) and
593 plugin_configure_single(GtkWidget *) are optional, however Geany prints a warning if
594 plugin_cleanup() is missing and only one of plugin_configure(GtkDialog *) and
595 plugin_configure_single(GtkWidget *) is used for any single plugin.
597 By convention, plugin_version_check() is implicitely defined through the use of PLUGIN_VERSION_CHECK(),
598 and similarly plugin_info is defined through PLUGIN_SET_INFO() or PLUGIN_SET_TRANSLATABLE_INFO().
600 The functions should generally perform the same tasks as their eqivalents in GeanyPlugin::funcs.
602 Geany also recognized numerous variable fields if the plugin exported them globally, and actually
603 set a few of them inside the plugins data section.
605 @section porting Porting a Legacy Plugin
607 Given a legacy plugin it can be modified to use the new entry points without much effort. This
608 section gives a basic recipe that should work for most existing plugins. The transition should
609 be easy and painless so it is recommended that you adapt your plugin as soon as possible.
611 @note This guide is intentionally minimalistic (in terms of suggested code changes) in order to
612 allow adaption to the current entry points as quickly as possible and without a lot effort. It
613 should also work even for rather complex plugins comprising multiple source files. On the other hand
614 it does not make use of new features such as geany_plugin_set_data().
616 @subsection functions Functions
618 Probably the biggest hurdle is the dropped support of the long-deprecated
619 plugin_configure_single(). This means you first have to port the configuration dialog (if any) to
620 the combined plugin dialog. While you previously created a custom dialog you now attach the main
621 widget of that dialog to the combined plugin dialog simply by returning it from
622 GeanyPluginFuncs::configure. You don't actually add it, Geany will do that for you. The pointer to
623 the dialog is passed to @a configure simply to allow you to connect to its "response" or "close"
624 signals.
626 The following lists the function mapping of previous @a plugin_* functions to the new @a
627 GeanyPlugin::funcs. They are semantically the same, however the new functions receive more
628 parameters which you may use or not.
630   - plugin_init() => GeanyPlugin->funcs->init
631   - plugin_cleanup() => GeanyPlugin->funcs->cleanup
632   - plugin_help() => GeanyPlugin->funcs->help
633   - plugin_configure() => GeanyPlugin->funcs->configure
635 @note @ref GeanyPluginFuncs::init() should return a boolean value: whether or not the plugin loaded
636 succesfully. Since legacy plugins couldn't fail in plugin_init() you should return @c TRUE
637 unconditionally.
639 @note Again, plugin_configure_single() is not supported anymore.
641 @subsection Variables
643 Exported global variables are not recognized anymore. They are replaced in the following ways:
645 @ref plugin_info is simply removed. Instead, you have to assign the values to GeanyPlugin::info
646 yourself, and it must be done inside your @a geany_load_module().
648 Example:
650 @code
651 PLUGIN_SET_INFO(
652         "HelloWorld",
653         "Just another tool to say hello world",
654         "1.0", "John Doe <john.doe@example.org>");
655 @endcode
657 becomes
659 @code
660 G_MODULE_EXPORT
661 void geany_load_module(GeanyPlugin *plugin)
663 // ...
664         plugin->info->name = "HelloWorld";
665         plugin->info->description = "Just another tool to say hello world";
666         plugin->info->version = "1.0";
667         plugin->info->author = "John Doe <john.doe@example.org>";
668 // ...
670 @endcode
671 @note Refer to @ref translatable_plugin_information for i18n support for the metadata.
674 The @ref plugin_callbacks array is supported by assigning the GeanyPluginFuncs::callbacks to
675 the array.
677 @ref plugin_fields is not supported anymore. Use ui_add_document_sensitive() instead.
678 @ref PLUGIN_KEY_GROUP and @ref plugin_key_group are also not supported anymore. Use
679 plugin_set_key_group() and keybindings_set_item() respectively.
681 Additionally, Geany traditionally set a few variables. This is not the case anymore. @ref
682 geany_functions has been removed in 1.25 and since then existed only for compatibility and has been
683 empty. You can simply remove its declaration from your source code. @ref geany_plugin is passed to
684 each @ref GeanyPluginFuncs function. You need to store it yourself somewhere if you need it
685 elsewhere. @ref geany_data is now available as a member of GeanyPlugin.
687 @code
688 GeanyPlugin *geany_plugin;
689 GeanyData *geany_data;
691 static gboolean my_init(GeanyPlugin *plugin, gpointer pdata)
693 // ...
694         geany_plugin = plugin;
695         geany_data = plugin->geany_data;
696         return TRUE;
698 @endcode
700 @ref geany_plugin is now also passed by default to the PluginCallback signal handlers as data
701 pointer if it's set to NULL.
703 @code
704 static PluginCallback plugin_callbacks[] = {
705         { "editor-notify", (GCallback) &on_editor_notify_cb, FALSE, NULL },
706 // ...
709 static gboolean on_editor_notify_cb(GObject *object, GeanyEditor *editor,
710                                                                         SCNotification *nt, gpointer data)
712         GeanyPlugin *plugin = data;
713 //...
717 G_MODULE_EXPORT
718 void geany_load_module(GeanyPlugin *plugin)
720 // ...
721         plugin->funcs->callbacks = plugin_callbacks;
722 // ...
725 @endcode