Rename append_to_temp_file() to combine_include_files()
[geany-mirror.git] / doc / plugins.dox
blob7bc1fa06c7a4c11aba9aa04856ceb323ee85ad1b
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 proxy
47 - @ref legacy
48 - @link plugindata.h Plugin Datatypes and Macros @endlink
49 - @link pluginsignals.c Plugin Signals @endlink
50 - @link pluginutils.h Plugin Utility Functions @endlink
51 - @link guidelines Plugin Writing Guidelines @endlink
52 - <b>plugins/demoplugin.c</b> - in Geany's source, bigger than the howto example
54 @section common Common API files
55 - @link dialogs.h @endlink
56 - @link document.h @endlink
57 - @link editor.h @endlink
58 - @link filetypes.h @endlink
59 - @link keybindings.h @endlink
60 - @link msgwindow.h @endlink
61 - @link project.h @endlink
62 - @link sciwrappers.h Scintilla Wrapper Functions @endlink
63 - @link spawn.h Spawning programs @endlink
64 - @link stash.h Stash Pref/Setting Functions @endlink
65 - @link utils.h General Utility Functions @endlink
66 - @link ui_utils.h Widget Utility Functions @endlink
68 @section More
69 - All API functions and types - see <b>Files</b> link at the top
70 - Deprecated symbols - see <b>Related Pages</b> link at the top
72 @note See the HACKING file for information about developing the plugin API and
73 other useful notes.
75 @page guidelines Plugin Writing Guidelines
77 @section intro_guidelines Introduction
79 The following hints and guidelines are only recommendations. Nobody is forced to follow
80 them at all.
82 @section general General notes
84 @subsection ideas Getting a plugin idea
86 If you want to write a plugin but don't know yet what it should do, have a look at
87 http://www.geany.org/Support/PluginWishlist to get an idea about what users wish.
89 @subsection code Managing the source code
91 For authors of plugins for Geany, we created a dedicated @a geany-plugins project
92 on Sourceforge and GitHub to ease development of plugins and help new authors.
93 All information about this project you can find at http://plugins.geany.org/
95 To add a new plugin to this project, get in touch with the people on the
96 geany-devel-mailing list and create a fork of the geany-plugins project
97 at https://github.com/geany/geany-plugins.
98 Beside of adding a new plugin, geany-devel-mailing list is also the place where
99 to discuss development related questions.
100 However, once you have done your fork of geany-plugins you can develop
101 your plugin until you think its the right time to publish it. At this point,
102 create a pull request for adding your patch set into the master branch of the main
103 geany-plugins repository.
105 Of course, you don't need to use GitHub - any Git is fine. But GitHub
106 is making it way easier for review, merging and get in touch with you for
107 comments.
109 If you don't want your plugin to be part of the geany-plugins project it is also fine.
110 Just skip the part about forking geany-plugins and sending a pull request.
111 In this case it is of course also a good idea to post some kind of announcement
112 to geany-devel and maybe to the main geany mailing list -- it's up to you.
113 You can also ask for your plugin to be listed on the http://plugins.geany.org/
114 website as a third party plugin, helping Geany user to know about your plugin.
116 At time of writing, there are some plugins already available in the
117 repositories. Feel free to use any of these plugins as a start for your own,
118 maybe by copying the directory structure and the autotools files
119 (Makefile.am, configure.in, ...). Most of the available plugins are also ready for
120 i18n support, just for reference.
122 We encourage authors using this service to only commit changes to their
123 own plugin and not to others' plugins. Instead just send patches to
124 geany-devel at uvena.de or the plugin author directly.
126 @section paths Installation paths
128 - The plugin binary (@c pluginname.so) should be installed in Geany's libdir. This is
129   necessary so that Geany can find the plugin.
130   An easy way to retrieve Geany's libdir is to use the pkg-config tool, e.g. @code
131   `$PKG_CONFIG --variable=libdir geany`/ geany
132   @endcode
133 - If your plugin creates other binary files like helper programs or helper libraries,
134   they should go into @c $prefix/bin (for programs, ideally prefixed with @a geany),
135   additional libraries should be installed in Geany's libdir, maybe in a subdirectory.
136 - Plugins should install their documentation files (README, NEWS, ChangeLog, licences and
137   other documentation files) into the common documentation directory
138   @c $prefix/share/doc/geany-plugins/$pluginname/
139 - Translation files should be installed normally into @c $prefix/share/locale. There is no
140   need to use Geany's translation directory. To set up translation support properly and
141   for additional information, see main_locale_init().
142 - Do @a never install anything into a user's home directory like installing
143   the plugin binary in @c ~/.config/geany/plugins/.
146 @page howto Plugin HowTo
148 @section intro_howto Introduction
150 Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
151 add new features. This document gives a brief overview about how to add new
152 plugins by writing a simple "Hello World" plugin in C or C++.
155 @section buildenv Build environment
157 To be able to write plugins for Geany, you need the source code and some development
158 packages for GTK and its dependencies. The following will only describe the way to compile and
159 build plugins on Unix-like systems [1].
160 If you already have the Geany source code and compiled it from them, you can skip the
161 following.
163 First you need to have Geany installed. Then install the development files for GTK
164 and its dependencies. The easiest way to do this is to use your distribution's package
165 management system, e.g. on Debian and Ubuntu systems you can use
166 @code apt-get install libgtk2.0-dev intltool @endcode
167 This will install all necessary files to be able to compile plugins for Geany. On other
168 distributions, the package names and commands to use may differ.
170 Basically, you are done at this point and could continue with writing the plugin code.
172 [1] For Windows, it is basically the same but you might have some more work on setting up
173 the general build environment(compiler, GTK development files, ...). This is described on
174 Geany's website at http://www.geany.org/Support/BuildingOnWin32.
176 @section helloworld "Hello World"
178 @note This section describes the new entry points for plugins introduced with Geany 1.26. A short
179 summary of the legacy entry points is given at page @ref legacy but they are deprecated should not
180 be used any more.
182 When writing a plugin you will find a couple of functions which are mandatory and some which can be
183 implemented optionally for implementing some useful features once your plugin becomes more
184 powerful. For example to provide a configuration or help dialog.
186 @subsection beginning First steps for any Plugin
188 You should start your plugin with including <geanyplugin.h> and exporting a function named @a
189 geany_load_module(). In this function you must fill in basic information that Geany uses to learn
190 more about your plugin and present it to the user. You also must define some hooks that enable
191 Geany to actually execute your code.
193 Please also do not forget about license headers which are by convention at the start of source
194 files. You can use templates provided by Geany to get started. Without a proper license it will be
195 difficult for packagers to pick up and distribute your plugin.
197 As mentioned above, start with the very fundamental header that gets you all goodies of Geany's
198 plugin API. @a geanyplugin.h includes all of the Geany API and also the necessary GTK header
199 files so there is no need to include @a gtk/gtk.h yourself. In fact it includes a utility header
200 that helps supporting GTK+2 and GTK+3 in the same source.
202 @code
203 #include <geanyplugin.h>
204 @endcode
206 @note If you use autoconf then config.h must be included even before that as usual.
208 Now you can go on and write your first lines for your new plugin. As mentioned before, you will
209 need to implement a couple of functions. The first mandatory one is @a geany_load_module(). Geany
210 uses the presence fo this function to identify a library as a plugin. When Geany scans the
211 pre-defined and user-configured plugin directories, it will take a look at each shared library (or
212 DLL on Windows) to see if it exports a @a geany_load_module() symbol. Files lacking these will be
213 ignored. The second mandatory one is an initialization function that is only called when the plugin
214 becomes actually enabled (by the user or at startup).
216 @subsection register Registering a Plugin
218 Geany will always invoke this geany_load_module(), regardless of whether the user activates your
219 plugin. In fact its purpose to probe if the plugin should even be presented to the user. Therefore
220 you must use this function to register your plugin. Geany will pass a pointer to a GeanyPlugin
221 instance which acts as a unique handle to your plugin. Use this pointer for registering and later
222 API calls. It won't change for the life time of the plugin. Registering the plugin consists of a
223 number of steps:
225   1. Filling in GeanyPlugin::info with metadata that is shown to the user.
226     - @ref PluginInfo::name : The name of your plugin
227     - @ref PluginInfo::description : A brief description.
228     - @ref PluginInfo::version : The plugin's version.
229     - @ref PluginInfo::author : Your contact information, preferably in the form "Name <email>".
230     .
231     Filling in all of them is recommended to provide the best user experience, but only the name is
232     truly mandatory. Since all of the strings are shown to the user they should be human readable.
233   2. Filling in GeanyPlugin::funcs with function pointers that are called by Geany.
234     - @ref GeanyPluginFuncs::init : an initialization function
235     - @ref GeanyPluginFuncs::cleanup : a finalization function
236     - @ref GeanyPluginFuncs::configure : a function that provides configuration (optional)
237     - @ref GeanyPluginFuncs::help : a function that provides help (optional)
238     - @ref GeanyPluginFuncs::callbacks : a pointer to an array of PluginCallback (optional).
239     .
240     @a init and @a cleanup are mandatory, the other ones depend on how advanced your plugin is.
241     Furthermore, @a init is called on startup and when the user activates your plugin in the Plugin
242     Manager, and @a cleanup is called on exit and when the user deactivates it. So use these to do
243     advanced initialization and teardown as to not waste resources when the plugin is not even
244     enabled.
245   3. Actually registering by calling GEANY_PLUGIN_REGISTER() or GEANY_PLUGIN_REGISTER_FULL().
246    - Usually you should use GEANY_PLUGIN_REGISTER() to register your plugin, passing the
247     GeanyPlugin pointer that you received and filled out as above. GEANY_PLUGIN_REGISTER() also
248     takes the minimum API version number you want to support (see @ref versions for details). Please
249     also <b>check the return value</b>. Geany may refuse to load your plugin due to
250     incompatibilities, you should then abort any extra setup. GEANY_PLUGIN_REGISTER() is a macro
251     wrapping geany_plugin_register() which takes additional the API and ABI that you should not pass
252     manually.
253    - If you require a plugin-specific context or state to be passed to your GeanyPlugin::funcs then
254     use GEANY_PLUGIN_REGISTER_FULL() to register. This one takes additional parameters for adding
255     user data to your plugin. That user data pointer is subsequently passed back to your functions.
256     It allows, for example, to set instance pointer to objects in case your plugin isn't written in
257     pure C, enabling you to use member functions as plugin functions. You may also set such data
258     later on, for example in your @ref GeanyPluginFuncs::init routine to defer costly allocations
259     to when the plugin is actually activated by the user. However, you then have to call
260     geany_plugin_set_data().
263 @subsection versions On API and ABI Versions
264 As previously mentioned @a geany_plugin_register() takes a number of versions as arguments:
265   1. api_version
266   2. min_api_version
267   3. abi_version
269 These refer to Geany's versioning scheme to manage plugin compatibility. The following rules apply:
270   - Plugins are compiled against a specific Geany version on the build machine. This version of
271     Geany has specific ABI and API versions, which will be compiled into the plugin. Both are
272     managed automatically, by calling GEANY_PLUGIN_REGISTER().
273   - The Geany version that loads the plugin may be different, possibly even have different API and
274     ABI versions.
275   - The ABI version is the primary plugin compatibility criteria. The ABI version of the running
276     Geany and the one that's compiled into the plugin must match exactly (==). In case of mismatch,
277     the affected plugins need to be recompiled (generally without source code changes) against the
278     running Geany. The ABI is usually stable even across multiple releases of Geany.
279   - The API version is secondary. It doesn't have to match exactly, however a plugin can report
280     a minimum API version that it requires to run. Geany will check if its own API is larger than
281     that (>=) and will otherwise refuse to load the plugin. The API version is incremented when
282     functions or variables are added to the API which often happens more than once within a release
283     cycle.
284   - The API version the plugin is compiled against is still relevant for enabling compatibility
285     code inside Geany (for cases where incrementing the ABI version could be avoided).
287 Instead of calling geany_plugin_register() directly it is very highly recommended to use
288 GEANY_PLUGIN_REGISTER(). This is a convenient way to pass Geany's current API and ABI versions
289 without requiring future code changes whenever either one changes. In fact, the promise that
290 plugins need to be just recompiled on ABI change can hold if the plugins use this macro. You still
291 want to pass the API version needed at minimum to run your plugin. The value is defined in
292 plugindata.h by @ref GEANY_API_VERSION. In most cases this should be your minimum. Nevertheless when
293 setting this value, you should choose the lowest possible version here to make the plugin
294 compatible with a bigger number of versions of Geany. The absolute minimum is 225 which introduced
295 the new plugin entry points.
297 To increase your flexibility the API version of the running Geany is passed to geany_load_module().
298 You can use this information to toggle API-specific code. This comes handy, for example to enable
299 optional code that requires a recent API version without raising your minimum required API version.
300 This enables running the plugin against more Geany versions, although perhaps at reduced
301 functionality.
303 @subsection example Example
305 Going back to our "Hello World" plugin here is example code that properly adds the HelloWorld
306 plugin to Geany.
308 @code
309 /* License blob */
311 #include <geanyplugin.h>
314 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
316         printf("Hello World from plugin!\n");
318         /* Perform advanced set up here */
320         return TRUE;
324 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
326         printf("Bye World :-(\n");
330 G_MODULE_EXPORT
331 void geany_load_module(GeanyPlugin *plugin)
333         /* Step 1: Set metadata */
334         plugin->info->name = "HelloWorld";
335         plugin->info->description = "Just another tool to say hello world";
336         plugin->info->version = "1.0";
337         plugin->info->author = "John Doe <john.doe@example.org>";
339         /* Step 2: Set functions */
340         plugin->funcs->init = hello_init;
341         plugin->funcs->cleanup = hello_cleanup;
343         /* Step 3: Register! */
344         if (GEANY_PLUGIN_REGISTER(plugin, 225))
345                 return;
346         /* alternatively:
347         GEANY_PLUGIN_REGISTER_FULL(plugin, 225, data, free_func); */
349 @endcode
351 If you think this plugin seems not to implement any functionality right now and only wastes
352 some memory, you are right. But it should compile and load/unload in Geany nicely.
353 Now you have the very basic layout of a new plugin. Great, isn't it?
355 If you would rather write the plugin in C++, you can do that by marking @a geany_load_module()
356 as <c> extern "C" </c>, for example:
358 @code
360 extern "C" void geany_load_module(GeanyPlugin *plugin)
364 @endcode
366 You can also create an instance of a class and set that as data pointer (with
367 GEANY_PLUGIN_REGISTER_FULL()). With small wrappers that shuffle the parameters you can even use
368 member functions for @ref GeanyPlugin::funcs etc.
370 @section building Building
372 First make plugin.o:
374 @code gcc -c plugin.c -fPIC `pkg-config --cflags geany` @endcode
376 Then make the plugin library plugin.so (or plugin.dll on Windows):
378 @code gcc plugin.o -o plugin.so -shared `pkg-config --libs geany` @endcode
380 If all went OK, put the library into one of the paths Geany looks for plugins,
381 e.g. $prefix/lib/geany. See @ref paths "Installation paths" for details.
383 If you are writing the plugin in C++, then you will need to use your C++
384 compiler here, for example @c g++.
386 @section realfunc Adding functionality
388 Let's go on and implement some real functionality.
390 As mentioned before, GeanyPluginFuncs::init() will be called when the plugin is activated by
391 Geany. So it should implement everything that needs to be done during startup. In this case, we'd
392 like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
394 @code
395 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
397         GtkWidget *main_menu_item;
399         // Create a new menu item and show it
400         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
401         gtk_widget_show(main_menu_item);
403         // Attach the new menu item to the Tools menu
404         gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu),
405                 main_menu_item);
407         // Connect the menu item with a callback function
408         // which is called when the item is clicked
409         g_signal_connect(main_menu_item, "activate",
410                 G_CALLBACK(item_activate_cb), NULL);
412         return TRUE;
414 @endcode
416 This will add an item to the Tools menu and connect this item to a function which implements what
417 should be done when the menu item is activated by the user. This is done by g_signal_connect(). The
418 Tools menu can be accessed with plugin->geany_data->main_widgets->tools_menu. The structure
419 GeanyMainWidgets contains pointers to all main GUI elements in Geany.
421 Geany has a simple API for showing message dialogs. So our function contains
422 only a few lines:
423 @code
424 static void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
426         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
428 @endcode
430 For the moment you don't need to worry about the parameters of that function.
432 Now we need to clean up properly when the plugin is unloaded.
434 To remove the menu item from the Tools menu you can use gtk_widget_destroy().
436 First you should add gtk_widget_destroy() to your GeanyPluginFuncs::cleanup() function. The
437 argument for gtk_widget_destroy() is the widget object you created earlier in
438 GeanyPluginFuncs::init(). To be able to access this pointer in GeanyPluginFuncs::cleanup() you can
439 use geany_plugin_set_data() to set plugin-defined data pointer to the widget. Alternatively, you
440 can store the pointer in some global variable so its visibility will increase and it can be
441 accessed in all functions.
443 @code
444 /* alternative: global variable:
445 static GtkWidget *main_menu_item;
447 // ...
448 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
450         GtkWidget *main_menu_item;
452         // Create a new menu item and show it
453         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
454         gtk_widget_show(main_menu_item);
455 // ...
456         geany_plugin_set_data(plugin, main_menu_item, NULL);
457         return TRUE;
460 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
462         GtkWidget *main_menu_item = (GtkWidget *) pdata;
463 // ...
464         gtk_widget_destroy(main_menu_item);
466 @endcode
468 This will ensure your menu item is removed from the Tools menu as well as from
469 memory once your plugin is unloaded, so you don't leave any memory leaks.
470 Once this is done, your first plugin is ready. Congratulations!
472 @section listing Complete listing (without comments)
474 @code
476 #include <geanyplugin.h>
478 static void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
480         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
484 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
486         GtkWidget *main_menu_item;
488         // Create a new menu item and show it
489         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
490         gtk_widget_show(main_menu_item);
491         gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu),
492                         main_menu_item);
493         g_signal_connect(main_menu_item, "activate",
494                         G_CALLBACK(item_activate_cb), NULL);
496         geany_plugin_set_data(plugin, main_menu_item, NULL);
497         return TRUE;
501 static void hello_cleanup(GeanyPlugin *plugin, gpointer pdata)
503         GtkWidget *main_menu_item = (GtkWidget *) pdata;
505         gtk_widget_destroy(main_menu_item);
509 G_MODULE_EXPORT
510 void geany_load_module(GeanyPlugin *plugin)
512         plugin->info->name = "HelloWorld";
513         plugin->info->description = "Just another tool to say hello world";
514         plugin->info->version = "1.0";
515         plugin->info->author = "John Doe <john.doe@example.org>";
517         plugin->funcs->init = hello_init;
518         plugin->funcs->cleanup = hello_cleanup;
520         GEANY_PLUGIN_REGISTER(plugin, 225);
522 @endcode
525 Now you might like to look at Geany's source code for core plugins such as
526 @a plugins/demoplugin.c.
528 @section furtherimprovements Further Improvements and next steps
529 @subsection translatable_plugin_information Translatable plugin information
531 After having written our first plugin, there is still room for improvement.
533 By default, @ref geany_load_module() is not prepared to allow translation of the basic plugin
534 information, except plugins which are shipped with Geany's core distribution, because custom
535 gettext catalogs are not setup. Since most plugins are not shipped with Geany's core, it makes
536 sense to setup gettext when the plugin is loaded so that it gets translated inside Geany's Plugin
537 Manager. The solution is to call the API function main_locale_init() inside @ref
538 geany_load_module() and then use gettext's _() as usual.
540 The invocation will most probably look similar to this:
541 @code
542 // ...
543         main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
544         plugin->info->name = _("HelloWorld");
545         plugin->info->description = _("Just another tool to say hello world");
546         plugin->info->version = "1.0";
547         plugin->info->author = "John Doe <john.doe@example.org>";
548 @endcode
550 The @a LOCALEDIR and the @a GETTEXT_PACKAGE parameters are usually set inside the build system.
552 As you can see the author's information is not marked as translatable in
553 this example.  The community has agreed that the best practice here is to
554 use, if possible, the latin version of the author's name followed by the
555 native spelling inside parenthesis, where applicable.
557 @subsection plugin_i18n Using i18n/l10n inside Plugin
560 You can (and should) also mark other strings beside the plugin's meta information as translatable.
561 Strings used in menu entries, information boxes or configuration dialogs should be translatable as
562 well.
564 @code
565 static gboolean hello_init(GeanyPlugin *plugin, gpointer pdata)
567         main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
568         main_menu_item = gtk_menu_item_new_with_mnemonic(_("Hello World"));
569 // ...
571 @endcode
573 @page legacy Porting guide from legacy entry points to the current ones
575 @section intro_legacy Introduction
577 This page briefly describes the deprecated, legacy plugin entry points. These have been in place
578 prior to Geany 1.26 and are still loadable and working for the time being. However, do not create
579 new plugins against these. For this reason, the actual description here is rather minimalistic and
580 concentrates on porting legacy plugins to the new interface. Basically it's main purpose
581 is to give newcomers an idea of what they are looking at if they come across a legacy plugin.
583 @section overview Overview
585 The legacy entry points consist of a number of pre-defined symbols (functions and variables)
586 exported by plugins. There is no active registration procedure. It is implicit simply by exporting
587 the mandatory symbols. The entirety of the symbols is described at the page @link pluginsymbols.c
588 Plugin Symbols @endlink.
590 At the very least plugins must define the functions @a plugin_init(GeanyData *) and @a
591 plugin_version_check(gint). Additionally, an instance of the struct PluginInfo named plugin_info
592 must be exported as well, this contains the same metadata already known from GeanyPlugin::info. The
593 functions plugin_cleanup(), plugin_help(), plugin_configure(GtkDialog *) and
594 plugin_configure_single(GtkWidget *) are optional, however Geany prints a warning if
595 plugin_cleanup() is missing and only one of plugin_configure(GtkDialog *) and
596 plugin_configure_single(GtkWidget *) is used for any single plugin.
598 By convention, plugin_version_check() is implicitely defined through the use of PLUGIN_VERSION_CHECK(),
599 and similarly plugin_info is defined through PLUGIN_SET_INFO() or PLUGIN_SET_TRANSLATABLE_INFO().
601 The functions should generally perform the same tasks as their eqivalents in GeanyPlugin::funcs.
603 Geany also recognized numerous variable fields if the plugin exported them globally, and actually
604 set a few of them inside the plugins data section.
606 @section porting Porting a Legacy Plugin
608 Given a legacy plugin it can be modified to use the new entry points without much effort. This
609 section gives a basic recipe that should work for most existing plugins. The transition should
610 be easy and painless so it is recommended that you adapt your plugin as soon as possible.
612 @note This guide is intentionally minimalistic (in terms of suggested code changes) in order to
613 allow adaption to the current entry points as quickly as possible and without a lot effort. It
614 should also work even for rather complex plugins comprising multiple source files. On the other hand
615 it does not make use of new features such as geany_plugin_set_data().
617 @subsection functions Functions
619 Probably the biggest hurdle is the dropped support of the long-deprecated
620 plugin_configure_single(). This means you first have to port the configuration dialog (if any) to
621 the combined plugin dialog. While you previously created a custom dialog you now attach the main
622 widget of that dialog to the combined plugin dialog simply by returning it from
623 GeanyPluginFuncs::configure. You don't actually add it, Geany will do that for you. The pointer to
624 the dialog is passed to @a configure simply to allow you to connect to its "response" or "close"
625 signals.
627 The following lists the function mapping of previous @a plugin_* functions to the new @a
628 GeanyPlugin::funcs. They are semantically the same, however the new functions receive more
629 parameters which you may use or not.
631   - plugin_init() => GeanyPlugin->funcs->init
632   - plugin_cleanup() => GeanyPlugin->funcs->cleanup
633   - plugin_help() => GeanyPlugin->funcs->help
634   - plugin_configure() => GeanyPlugin->funcs->configure
636 @note @ref GeanyPluginFuncs::init() should return a boolean value: whether or not the plugin loaded
637 successfully. Since legacy plugins couldn't fail in plugin_init() you should return @c TRUE
638 unconditionally.
640 @note Again, plugin_configure_single() is not supported anymore.
642 @subsection Variables
644 Exported global variables are not recognized anymore. They are replaced in the following ways:
646 @ref plugin_info is simply removed. Instead, you have to assign the values to GeanyPlugin::info
647 yourself, and it must be done inside your @a geany_load_module().
649 Example:
651 @code
652 PLUGIN_SET_INFO(
653         "HelloWorld",
654         "Just another tool to say hello world",
655         "1.0", "John Doe <john.doe@example.org>");
656 @endcode
658 becomes
660 @code
661 G_MODULE_EXPORT
662 void geany_load_module(GeanyPlugin *plugin)
664 // ...
665         plugin->info->name = "HelloWorld";
666         plugin->info->description = "Just another tool to say hello world";
667         plugin->info->version = "1.0";
668         plugin->info->author = "John Doe <john.doe@example.org>";
669 // ...
671 @endcode
672 @note Refer to @ref translatable_plugin_information for i18n support for the metadata.
675 The @ref plugin_callbacks array is supported by assigning the GeanyPluginFuncs::callbacks to
676 the array.
678 @ref plugin_fields is not supported anymore. Use ui_add_document_sensitive() instead.
679 @ref PLUGIN_KEY_GROUP and @ref plugin_key_group are also not supported anymore. Use
680 plugin_set_key_group() and keybindings_set_item() respectively.
682 Additionally, Geany traditionally set a few variables. This is not the case anymore. @ref
683 geany_functions has been removed in 1.25 and since then existed only for compatibility and has been
684 empty. You can simply remove its declaration from your source code. @ref geany_plugin is passed to
685 each @ref GeanyPluginFuncs function. You need to store it yourself somewhere if you need it
686 elsewhere. @ref geany_data is now available as a member of GeanyPlugin.
688 @code
689 GeanyPlugin *geany_plugin;
690 GeanyData *geany_data;
692 static gboolean my_init(GeanyPlugin *plugin, gpointer pdata)
694 // ...
695         geany_plugin = plugin;
696         geany_data = plugin->geany_data;
697         return TRUE;
699 @endcode
701 @ref geany_plugin is now also passed by default to the PluginCallback signal handlers as data
702 pointer if it's set to NULL.
704 @code
705 static PluginCallback plugin_callbacks[] = {
706         { "editor-notify", (GCallback) &on_editor_notify_cb, FALSE, NULL },
707 // ...
710 static gboolean on_editor_notify_cb(GObject *object, GeanyEditor *editor,
711                                                                         SCNotification *nt, gpointer data)
713         GeanyPlugin *plugin = data;
714 //...
718 G_MODULE_EXPORT
719 void geany_load_module(GeanyPlugin *plugin)
721 // ...
722         plugin->funcs->callbacks = plugin_callbacks;
723 // ...
726 @endcode
729 @page proxy Proxy Plugin HowTo
731 @section proxy_intro Introduction
733 Geany has built-in support for plugins. These plugins can alter the way Geany operates in many
734 imaginable ways which leaves little to be desired.
736 However, there is one significant short-coming. Due to the infrastructure, Geany's built-in support
737 only covers plugins written in C, perhaps C++ and Vala. Basically all languages which can be
738 compiled into native shared libraries and can link GTK libraries. This excludes dynamic languages
739 such as Python.
741 Geany provides a mechanism to enable support for those languages. Native plugins can register as
742 proxy plugins by being a normal plugin to the Geany-side and by providing a bridge to write plugins
743 in another language on the other side.
745 These plugins are also called sub-plugins. This refers to the relation to their proxy.
746 To Geany they are first-class citizens.
748 @section proxy_protocol Writing a Proxy Plugin
750 The basic idea is that a proxy plugin provides methods to match, load and unload one or more
751 sub-plugin plugins in an abstract manner:
753  - Matching consists of providing a list of supported file extensions for the sub-plugins and
754    a mechanism to resolve file extension uncertainty or ambiguity. The matching makes the plugin
755    visible to the user within the Plugin Manager.
756  - Loading consists of loading the sub-plugin's file, passing the file to some form of interpreter
757    and calling GEANY_PLUGIN_REGISTER() or GEANY_PLUGIN_REGISTER_FULL() on behalf of the sub-plugin
758    at some point.
759  - Unloading simply reverses the effect of loading.
761 For providing these methods, GeanyPlugin has a field GeanyProxyFuncs which contains three function
762 pointers which must be initialized proir to calling geany_plugin_register_proxy(). This should be
763 done in the GeanyPluginFuncs::init function of the proxy plugin.
765  - In the call to geany_plugin_register_proxy() the proxy plugin passes a list of file extensions.
766    When Geany scans through its plugin directories as usual it will also look for files with
767    that extensions and consider found files as plugin candidate.
768  - GeanyProxyFuncs::probe may be implemented to probe if a plugin candidate (that has one of the
769    provided file extensions) is actually a plugin. This may depend on the plugin file itself in
770    case of ambiguity or availability of runtime dependencies or even configuration.
771    @ref PROXY_IGNORED or @ref PROXY_MATCHED should be returned, possibly in combination
772    with the @ref PROXY_NOLOAD flag. Not implementing GeanyProxyFuncs::probe at all is eqivalent to
773    always returning @ref PROXY_MATCHED.
774  - GeanyProxyFuncs::load must be implemented to actually load the plugin. It is called by Geany
775    when the user enables the sub-plugin. What "loading" means is entirely up to the proxy plugin and
776    probably depends on the interpreter of the dynamic language that shall be supported. After
777    setting everything up as necessary GEANY_PLUGIN_REGISTER() or GEANY_PLUGIN_REGISTER_FULL() must
778    be called to register the sub-plugin.
779  - GeanyProxyFuncs::unload must be implemented and is called when the user unchecks the sub-plugin
780    or when Geany exits. Here, the proxy should release any references or memory associated to the
781    sub-plugin. Note that if GeanyProxyFuncs::load didn't succeed, i.e. didn't successfully register
782    the sub-plugin, then this function won't be called.
784 GeanyProxyFuncs::load and GeanyProxyFuncs::unload receive two GeanyPlugin pointers: One that
785 corresponds to the proxy itself and another that corresponds to the sub-plugin. The sub-plugin's
786 one may be used to call various API functions on behalf of the sub-plugin, including
787 GEANY_PLUGIN_REGISTER() and GEANY_PLUGIN_REGISTER_FULL().
789 GeanyProxyFuncs::load may return a pointer that is passed back to GeanyProxyFuncs::unload. This can
790 be used to store proxy-defined but sub-plugin-specific data required for unloading. However, this
791 pointer is not passed to the sub-plugin's GeanyPluginFuncs. To arrange for that, you want to call
792 GEANY_PLUGIN_REGISTER_FULL(). This method is the key to enable proxy plugins to wrap the
793 GeanyPluginFuncs of all sub-plugins and yet multiplex between multiple sub-plugin, for example by
794 storing a per-sub-plugin interpreter context.
796 @note If the pointer returned from GeanyProxyFuncs::load is the same that is passed to
797 GEANY_PLUGIN_REGISTER_FULL() then you must pass NULL as free_func, because that would be invoked
798 prior to unloading. Insert the corresponding code into GeanyProxyFuncs::unload.
800 @section proxy_compat_guideline Guideline for Checking Compatibility
802 Determining if a plugin candidate is compatible is not a single test. There are multiple levels and
803 each should be handled differently in order to give the user a consistent feedback.
805 Consider the 5 basic cases:
807 1) A candidate comes with a suitable file extension but is not a workable plugin file at all. For
808 example, your proxy supports plugins written in a shell script (.sh) but the shebang of that script
809 points to an incompatible shell (or even lacks a shebang). You should check for this in
810 GeanyProxyFuncs::probe() and return @ref PROXY_IGNORED which hides that script from the Plugin
811 Manager and allows other enabled proxy plugins to pick it up. GeanyProxyFuncs::probe() returning
812 @ref PROXY_IGNORED is an indication that the candidate is meant for another proxy, or the user
813 placed the file by accident in one of Geany's plugin directories. In other words the candidate
814 simply doesn't correspond to your proxy. Thus any noise by debug messages for this case is
815 undesirable.
817 2) A proxy plugin provides its own, versioned API to sub-plugin. The API version of the sub-plugin
818 is not compatible with the API exposed by the proxy. GeanyProxyFuncs::probe() should never perform
819 a version check because its sole purpose is to indicate a proxy's correspondence to a given
820 candidate. It should return @ref PROXY_MATCHED instead. Later, Geany will invoke the
821 GeanyProxyFuncs::load(), and this function is the right place for a version check. If it fails then
822 you simply do not call GEANY_PLUGIN_REGISTER(), but rather print a debug message. The result is
823 that the sub-plugin is not shown in the Plugin Manager at all. This is consistent with the
824 treatment of native plugins by Geany.
826 3) The sub-plugin is also depending on Geany's API version (whether it is or not depends on the
827 design of the proxy). In this case do not do anything special but forward the API version the
828 sub-plugin is written/compiled against to GEANY_PLUGIN_REGISTER(). Here, Geany will perform its own
829 compatibility check, allowing for a consistent user feedback. The result is again that the
830 sub-plugin is hidden from the Plugin Manager, like in case 2. But Geany will print a debug message
831 so you can skip that.
834 If you have even more cases try to fit it into case 1 or 2, depending on whether other proxy
835 plugins should get a chance to load the candidate or not.
837 @section proxy_dep_guideline Guideline for Runtime Errors
839 A sub-plugin might not be able to run even if it's perfectly compatible with its proxy. This
840 includes the case when it lacks certain runtime dependencies such as programs or modules but also
841 syntactic problems or other errors.
843 There are two basic classes:
845 1) Runtime errors that can be determined at load time. For example, the shebang of a script
846 indicates a specific interpeter version but that version is not installed on the system. Your proxy
847 should respond the same way as for version-incompatible plugins: don't register the plugin at
848 all, but leave a message the user suggesting what has to be installed in order to work. Handle
849 syntax errors in the scripts of sub-plugins the same way if possible.
851 2) Runtime errors that cannot be determined without actually running the plugin. An example would
852 be missing modules in Python scripts. If your proxy has no way of foreseeing the problem the plugin
853 will be registered normally. However, you can catch runtime errors by implementing
854 GeanyPluginFuncs::init() on the plugin's behalf. This is called after user activation and allows to
855 indicate errors by returning @c FALSE. However, allowing the user to enable a plugin and then
856 disabling anyway is a poor user experience.
858 Therefore, if possible, try to fail fast and disallow registration.
860 @section Proxy Plugin Example
862 In this section a dumb example proxy plugin is shown in order to give a practical starting point.
863 The sub-plugin are not actually code but rather a ini-style description of one or more menu items
864 that are added to Geany's tools menu and a help dialog. Real world sub-plugins would contain actual
865 code, usually written in a scripting language.
867 A sub-plugin file looks like this:
869 @code{.ini}
870 #!!PROXY_MAGIC!!
872 [Init]
873 item0 = Bam
874 item1 = Foo
875 item2 = Bar
877 [Help]
878 text = I'm a simple test. Nothing to see!
880 [Info]
881 name = Demo Proxy Tester
882 description = I'm a simple test. Nothing to see!
883 version = 0.1
884 author = The Geany developer team
885 @endcode
887 The first line acts as a verification that this file is truly a sub-plugin. Within the [Init] section
888 there is the menu items for Geany's tools menu. The [Help] section declares the sub-plugins help
889 text which is shown in its help dialog (via GeanyPluginFuncs::help). The [Info] section is
890 used as-is for filling the sub-plugins PluginInfo fields.
892 That's it, this dumb format is purely declarative and contains no logic. Yet we will create plugins
893 from it.
895 We start by registering the proxy plugin to Geany. There is nothing special to it compared to
896 normal plugins. A proxy plugin must also fill its own @ref PluginInfo and @ref GeanyPluginFuncs,
897 followed by registering through GEANY_PLUGIN_REGISTER().
900 @code{.c}
902 /* Called by Geany to initialize the plugin. */
903 static gboolean demoproxy_init(GeanyPlugin *plugin, gpointer pdata)
905         // ...
909 /* Called by Geany before unloading the plugin. */
910 static void demoproxy_cleanup(GeanyPlugin *plugin, gpointer data)
912         // ...
916 G_MODULE_EXPORT
917 void geany_load_module(GeanyPlugin *plugin)
919         plugin->info->name = _("Demo Proxy");
920         plugin->info->description = _("Example Proxy.");
921         plugin->info->version = "0.1";
922         plugin->info->author = _("The Geany developer team");
924         plugin->funcs->init = demoproxy_init;
925         plugin->funcs->cleanup = demoproxy_cleanup;
927         GEANY_PLUGIN_REGISTER(plugin, 225);
930 @endcode
932 The next step is to actually register as a proxy plugin. This is done in demoproxy_init().
933 As previously mentioned, it needs a list of accepted file extensions and a set of callback
934 functions.
936 @code{.c}
937 static gboolean demoproxy_init(GeanyPlugin *plugin, gpointer pdata)
939         const gchar *extensions[] = { "ini", "px", NULL };
941         plugin->proxy_funcs->probe  = demoproxy_probe;
942         plugin->proxy_funcs->load   = demoproxy_load;
943         plugin->proxy_funcs->unload = demoproxy_unload;
945         return geany_plugin_register_proxy(plugin, extensions);
948 @endcode
950 The callback functions deserve a closer look.
952 As already mentioned the file format includes a magic first line which must be present.
953 GeanyProxyFuncs::probe() verifies that it's present and avoids showing the sub-plugin in the
954 Plugin Manager if not.
956 @code{.c}
957 static gint demoproxy_probe(GeanyPlugin *proxy, const gchar *filename, gpointer pdata)
959         /* We know the extension is right (Geany checks that). For demo purposes we perform an
960          * additional check. This is not necessary when the extension is unique enough. */
961         gboolean match = FALSE;
962         gchar linebuf[128];
963         FILE *f = fopen(filename, "r");
964         if (f != NULL)
965         {
966                 if (fgets(linebuf, sizeof(linebuf), f) != NULL)
967                         match = utils_str_equal(linebuf, "#!!PROXY_MAGIC!!\n");
968                 fclose(f);
969         }
970         return match ? PROXY_MATCHED : PROXY_IGNORED;
972 @endcode
974 GeanyProxyFuncs::load is a bit more complex. It reads the file, fills the sub-plugin's PluginInfo
975 fields and calls GEANY_PLUGIN_REGISTER_FULL(). Additionally, it creates a per-plugin context that
976 holds GKeyFile instance (a poor man's interpeter context). You can also see that it does not call
977 GEANY_PLUGIN_REGISTER_FULL() if g_key_file_load_from_file() found an error (probably a syntax
978 problem) which means the sub-plugin cannot be enabled.
980 It also installs wrapper functions for the sub-plugin's GeanyPluginFuncs as ini files aren't code.
981 It's very likely that your proxy needs something similar because you can only install function
982 pointers to native code.
984 @code{.c}
985 typedef struct {
986         GKeyFile       *file;
987         gchar          *help_text;
988         GSList         *menu_items;
990 PluginContext;
993 static gboolean proxy_init(GeanyPlugin *plugin, gpointer pdata);
994 static void proxy_help(GeanyPlugin *plugin, gpointer pdata);
995 static void proxy_cleanup(GeanyPlugin *plugin, gpointer pdata);
998 static gpointer demoproxy_load(GeanyPlugin *proxy, GeanyPlugin *plugin,
999                                const gchar *filename, gpointer pdata)
1001         GKeyFile *file;
1002         gboolean result;
1004         file = g_key_file_new();
1005         result = g_key_file_load_from_file(file, filename, 0, NULL);
1007         if (result)
1008         {
1009                 PluginContext *data = g_new0(PluginContext, 1);
1010                 data->file = file;
1012                 plugin->info->name = g_key_file_get_locale_string(data->file, "Info", "name", NULL, NULL);
1013                 plugin->info->description = g_key_file_get_locale_string(data->file, "Info", "description", NULL, NULL);
1014                 plugin->info->version = g_key_file_get_locale_string(data->file, "Info", "version", NULL, NULL);
1015                 plugin->info->author = g_key_file_get_locale_string(data->file, "Info", "author", NULL, NULL);
1017                 plugin->funcs->init = proxy_init;
1018                 plugin->funcs->help = proxy_help;
1019                 plugin->funcs->cleanup = proxy_cleanup;
1021                 /* Cannot pass g_free as free_func be Geany calls it before unloading, and since 
1022                  * demoproxy_unload() accesses the data this would be catastrophic */
1023                 GEANY_PLUGIN_REGISTER_FULL(plugin, 225, data, NULL);
1024                 return data;
1025         }
1027         g_key_file_free(file);
1028         return NULL;
1030 @endcode
1032 demoproxy_unload() simply releases all resources acquired in demoproxy_load(). It does not have to
1033 do anything else in for unloading.
1035 @code{.c}
1036 static void demoproxy_unload(GeanyPlugin *proxy, GeanyPlugin *plugin, gpointer load_data, gpointer pdata)
1038         PluginContext *data = load_data;
1040         g_free((gchar *)plugin->info->name);
1041         g_free((gchar *)plugin->info->description);
1042         g_free((gchar *)plugin->info->version);
1043         g_free((gchar *)plugin->info->author);
1045         g_key_file_free(data->file);
1046         g_free(data);
1048 @endcode
1050 Finally the demo_proxy's wrapper GeanyPluginFuncs. They are called for each possible sub-plugin and
1051 therefore have to multiplex between each using the plugin-defined data pointer. Each is called by
1052 Geany as if it were an ordinary, native plugin.
1054 proxy_init() actually reads the sub-plugin's file using GKeyFile APIs. It prepares for the help
1055 dialog and installs the menu items. proxy_help() is called when the user clicks the help button in
1056 the Plugin Manager. Consequently, this fires up a suitable dialog, although with a dummy message.
1057 proxy_cleanup() frees all memory allocated in proxy_init().
1059 @code{.c}
1060 static gboolean proxy_init(GeanyPlugin *plugin, gpointer pdata)
1062         PluginContext *data;
1063         gint i = 0;
1064         gchar *text;
1066         data = (PluginContext *) pdata;
1068         /* Normally, you would instruct the VM/interpreter to call into the actual plugin. The
1069          * plugin would be identified by pdata. Because there is no interpreter for
1070          * .ini files we do it inline, as this is just a demo */
1071         data->help_text = g_key_file_get_locale_string(data->file, "Help", "text", NULL, NULL);
1072         while (TRUE)
1073         {
1074                 GtkWidget *item;
1075                 gchar *key = g_strdup_printf("item%d", i++);
1076                 text = g_key_file_get_locale_string(data->file, "Init", key, NULL, NULL);
1077                 g_free(key);
1079                 if (!text)
1080                         break;
1082                 item = gtk_menu_item_new_with_label(text);
1083                 gtk_widget_show(item);
1084                 gtk_container_add(GTK_CONTAINER(plugin->geany_data->main_widgets->tools_menu), item);
1085                 gtk_widget_set_sensitive(item, FALSE);
1086                 data->menu_items = g_slist_prepend(data->menu_items, (gpointer) item);
1087                 g_free(text);
1088         }
1090         return TRUE;
1094 static void proxy_help(GeanyPlugin *plugin, gpointer pdata)
1096         PluginContext *data;
1097         GtkWidget *dialog;
1099         data = (PluginContext *) pdata;
1101         dialog = gtk_message_dialog_new(
1102                 GTK_WINDOW(plugin->geany_data->main_widgets->window),
1103                 GTK_DIALOG_DESTROY_WITH_PARENT,
1104                 GTK_MESSAGE_INFO,
1105                 GTK_BUTTONS_OK,
1106                 "%s", data->help_text);
1107         gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
1108                 _("(From the %s plugin)"), plugin->info->name);
1110         gtk_dialog_run(GTK_DIALOG(dialog));
1111         gtk_widget_destroy(dialog);
1115 static void proxy_cleanup(GeanyPlugin *plugin, gpointer pdata)
1117         PluginContext *data = (PluginContext *) pdata;
1119         g_slist_free_full(data->menu_items, (GDestroyNotify) gtk_widget_destroy);
1120         g_free(data->help_text);
1122 @endcode