2 * plugins.dox - this file is part of Geany, a fast and lightweight IDE
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>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * This file contains additional plugin documentation like the signal system
24 * and a small howto. It is best viewed when filetype is set to C or C++.
30 @mainpage Geany Plugin API Documentation
32 @author Enrico Tröger, Nick Treleaven, Frank Lanitz, Matthew Brush
35 This is the Geany API documentation. It should be considered work in progress.
36 We will try to document as many functions and structs as possible.
38 @warning Do not use any symbol not in the documentation - it may change.
40 @section pluginsupport Plugin Support
41 - @link howto Plugin HowTo @endlink - get started
42 - @link pluginsymbols.c Plugin Symbols @endlink
43 - @link plugindata.h Plugin Datatypes and Macros @endlink
44 - @link pluginsignals.c Plugin Signals @endlink
45 - @link pluginutils.h Plugin Utility Functions @endlink
46 - @link guidelines Plugin Writing Guidelines @endlink
47 - <b>plugins/demoplugin.c</b> - in Geany's source, bigger than the howto example
49 @section common Common API files
50 - @link dialogs.h @endlink
51 - @link document.h @endlink
52 - @link editor.h @endlink
53 - @link filetypes.h @endlink
54 - @link keybindings.h @endlink
55 - @link msgwindow.h @endlink
56 - @link project.h @endlink
57 - @link sciwrappers.h Scintilla Wrapper Functions @endlink
58 - @link stash.h Stash Pref/Setting Functions @endlink
59 - @link utils.h General Utility Functions @endlink
60 - @link ui_utils.h Widget Utility Functions @endlink
63 - All API functions and types - see <b>Files</b> link at the top
64 - Deprecated symbols - see <b>Related Pages</b> link at the top
66 @note See the HACKING file for information about developing the plugin API and
69 @page guidelines Plugin Writing Guidelines
71 @section intro Introduction
73 The following hints and guidelines are only recommendations. Nobody is forced to follow
76 @section general General notes
78 @subsection ideas Getting a plugin idea
80 If you want to write a plugin but don't know yet what it should do, have a look at
81 http://www.geany.org/Support/PluginWishlist to get an idea about what users wish.
83 @subsection code Managing the source code
85 For authors of plugins for Geany, we created a dedicated @a geany-plugins project
86 on Sourceforge and GitHub to ease development of plugins and help new authors.
87 All information about this project you can find at http://plugins.geany.org/
89 To add a new plugin to this project, get in touch with the people on the
90 geany-devel-mailing list and create a fork of the geany-plugins project
91 at https://github.com/geany/geany-plugins.
92 Beside of adding a new plugin, geany-devel-mailing list is also the place where
93 to discuss development related questions.
94 However, once you have done your fork of geany-plugins you can develop
95 your plugin until you think its the right time to publish it. At this point,
96 create a pull request for adding your patch set into the master branch of the main
97 geany-plugins repository.
99 Of course, you don't need to use GitHub - any Git is fine. But GitHub
100 is making it way easier for review, merging and get in touch with you for
103 If you don't want your plugin to be part of the geany-plugins project it is also fine.
104 Just skip the part about forking geany-plugins and sending a pull request.
105 In this case it is of course also a good idea to post some kind of announcement
106 to geany-devel and maybe to the main geany mailing list -- it's up to you.
107 You can also ask for your plugin to be listed on the http://plugins.geany.org/
108 website as a third party plugin, helping Geany user to know about your plugin.
110 At time of writing, there are some plugins already available in the
111 repositories. Feel free to use any of these plugins as a start for your own,
112 maybe by copying the directory structure and the autotools files
113 (Makefile.am, configure.in, ...). Most of the available plugins are also ready for
114 i18n support, just for reference.
116 We encourage authors using this service to only commit changes to their
117 own plugin and not to others' plugins. Instead just send patches to
118 geany-devel at uvena.de or the plugin author directly.
120 @section paths Installation paths
122 - The plugin binary (@c pluginname.so) should be installed in Geany's libdir. This is
123 necessary so that Geany can find the plugin.
124 An easy way to retrieve Geany's libdir is to use the pkg-config tool, e.g. @code
125 `$PKG_CONFIG --variable=libdir geany`/ geany
127 - If your plugin creates other binary files like helper programs or helper libraries,
128 they should go into @c $prefix/bin (for programs, ideally prefixed with @a geany),
129 additional libraries should be installed in Geany's libdir, maybe in a subdirectory.
130 - Plugins should install their documentation files (README, NEWS, ChangeLog, licences and
131 other documentation files) into the common documentation directory
132 @c $prefix/share/doc/geany-plugins/$pluginname/
133 - Translation files should be installed normally into @c $prefix/share/locale. There is no
134 need to use Geany's translation directory. To set up translation support properly and
135 for additional information, see main_locale_init().
136 - Do @a never install anything into a user's home directory like installing
137 the plugin binary in @c ~/.config/geany/plugins/.
140 @page howto Plugin HowTo
142 @section intro Introduction
144 Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
145 add new features. This document gives a brief overview about how to add new
146 plugins by writing a simple "Hello World" plugin in C or C++.
149 @section buildenv Build environment
151 To be able to write plugins for Geany, you need the source code and some development
152 packages for GTK and its dependencies. The following will only describe the way to compile and
153 build plugins on Unix-like systems [1].
154 If you already have the Geany source code and compiled it from them, you can skip the
157 First you need to have Geany installed. Then install the development files for GTK
158 and its dependencies. The easiest way to do this is to use your distribution's package
159 management system, e.g. on Debian and Ubuntu systems you can use
160 @code apt-get install libgtk2.0-dev intltool @endcode
161 This will install all necessary files to be able to compile plugins for Geany. On other
162 distributions, the package names and commands to use may differ.
164 Basically, you are done at this point and could continue with writing the plugin code.
166 [1] For Windows, it is basically the same but you might have some more work on setting up
167 the general build environment(compiler, GTK development files, ...). This is described on
168 Geany's website at http://www.geany.org/Support/BuildingOnWin32.
170 @section helloworld "Hello World"
172 When writing a plugin, you will find a couple of functions or macros which are mandatory
173 and some which are free to use for implementing some useful feature once your plugin
174 becomes more powerful like including a configuration or help dialog.
176 You should start your plugin with including some of the needed C header files and defining
177 some basic global variables which will help you to access all needed functions of the plugin
178 API in a more comfortable way.
180 Let's start with the very basic headers and add more later if necessary.
182 #include <geanyplugin.h>
185 @a geanyplugin.h includes all of the Geany API and also the necessary GTK header files,
186 so there is no need to include @a gtk/gtk.h yourself.
189 @a plugindata.h contains the biggest part of the plugin API and provides some basic macros.
190 @a geanyfunctions.h provides some macros for convenient access to plugin API functions.
192 Then you should define three basic variables which will give access to data fields and
193 functions provided by the plugin API.
195 GeanyPlugin *geany_plugin;
196 GeanyData *geany_data;
197 GeanyFunctions *geany_functions;
200 Now you can go on and write your first lines for your new plugin. As mentioned before,
201 you will need to implement and fill out a couple of functions/macros to make the plugin work.
202 So let's start with PLUGIN_VERSION_CHECK().
204 PLUGIN_VERSION_CHECK() is a convenient way to tell Geany which version of Geany's plugin API
205 is needed at minimum to run your plugin. The value is defined in
206 @a plugindata.h by @a GEANY_API_VERSION. In most cases this should be your minimum.
207 Nevertheless when setting this value, you should choose the lowest possible version here to
208 make the plugin compatible with a bigger number of versions of Geany.
210 For the next step, you will need to tell Geany some basic information about your plugin
211 which will be shown in the plugin manager dialog.
213 To do this you should use the PLUGIN_SET_INFO() macro, which expects 4 parameters:
219 Based on this, the line could look like:
221 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
222 "1.0", "John Doe <john.doe@example.org>");
225 Once this is done, you will need to implement the function which will be executed when the
226 plugin is loaded. Part of that function could be adding and removing of an item to
227 Geany's Tools menu, setting up keybindings or registering some callbacks. Also you will
228 need to implement the function that is called when your plugin is unloaded.
229 These functions are called plugin_init() and plugin_cleanup(). Let's see what this
232 PLUGIN_VERSION_CHECK(211)
234 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
235 "1.0", "Joe Doe <joe.doe@example.org>");
237 void plugin_init(GeanyData *data)
241 void plugin_cleanup(void)
246 If you think this plugin seems not to implement any functionality right now and only wastes
247 some memory, you are right. But it should compile and load/unload in Geany nicely.
248 Now you have the very basic layout of a new plugin. Great, isn't it?
252 If you would rather write the plugin in C++, you can do that by marking the
253 plugin functions that it implements as @c extern @c "C", for example:
257 extern "C" void plugin_init(GeanyData *data)
261 extern "C" void plugin_cleanup(void)
266 @section building Building
270 @code gcc -c plugin.c -fPIC `pkg-config --cflags geany` @endcode
272 Then make the plugin library plugin.so (or plugin.dll on Windows):
274 @code gcc plugin.o -o plugin.so -shared `pkg-config --libs geany` @endcode
276 If all went OK, put the library into one of the paths Geany looks for plugins,
277 e.g. $prefix/lib/geany. See @ref paths "Installation paths" for details.
281 If you are writing the plugin in C++, then you will need to use your C++
282 compiler here, for example @c g++.
284 @section realfunc Adding functionality
286 Let's go on and implement some real functionality.
288 As mentioned before, plugin_init() will be called when the plugin is loaded in Geany.
289 So it should implement everything that needs to be done during startup. In this case,
290 we'd like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
292 void plugin_init(GeanyData *data)
294 GtkWidget *main_menu_item;
296 // Create a new menu item and show it
297 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
298 gtk_widget_show(main_menu_item);
300 // Attach the new menu item to the Tools menu
301 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
304 // Connect the menu item with a callback function
305 // which is called when the item is clicked
306 g_signal_connect(main_menu_item, "activate",
307 G_CALLBACK(item_activate_cb), NULL);
311 This will add an item to the Tools menu and connect this item to a function which implements
312 what should be done when the menu item is activated by the user.
313 This is done by g_signal_connect(). The Tools menu can be accessed with
314 geany->main_widgets->tools_menu. The structure @a main_widgets contains pointers to the
315 main GUI elements in Geany.
317 Geany has a simple API for showing message dialogs. So our function contains
320 void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
322 dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
326 For the moment you don't need to worry about the parameters of that function.
328 Now we need to clean up properly when the plugin is unloaded.
330 To remove the menu item from the Tools menu, you can use gtk_widget_destroy().
331 gtk_widget_destroy() expects a pointer to a GtkWidget object.
333 First you should add gtk_widget_destroy() to your plugin_cleanup() function.
334 The argument for gtk_widget_destroy() is the widget object you created earlier in
335 plugin_init(). To be able to access this pointer in plugin_cleanup(), you need to move
336 its definition from plugin_init() into the global context so its visibility will increase
337 and it can be accessed in all functions.
339 static GtkWidget *main_menu_item = NULL;
342 void plugin_init(GeanyData *data)
344 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
345 gtk_widget_show(main_menu_item);
349 void plugin_cleanup(void)
351 gtk_widget_destroy(main_menu_item);
355 This will ensure your menu item is removed from the Tools menu as well as from
356 memory once your plugin is unloaded, so you don't leave any memory leaks.
357 Once this is done, your first plugin is ready. Congratulations!
359 @section listing Complete listing (without comments)
362 #include <geanyplugin.h>
364 GeanyPlugin *geany_plugin;
365 GeanyData *geany_data;
366 GeanyFunctions *geany_functions;
368 PLUGIN_VERSION_CHECK(211)
370 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
371 "1.0", "John Doe <john.doe@example.org>");
374 static GtkWidget *main_menu_item = NULL;
376 static void item_activate_cb(GtkMenuItem *menuitem, gpointer gdata)
378 dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
381 void plugin_init(GeanyData *data)
383 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
384 gtk_widget_show(main_menu_item);
385 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
387 g_signal_connect(main_menu_item, "activate",
388 G_CALLBACK(item_activate_cb), NULL);
391 void plugin_cleanup(void)
393 gtk_widget_destroy(main_menu_item);
398 Now you might like to look at Geany's source code for core plugins such as
399 @a plugins/demoplugin.c.
401 @section furtherimprovements Furter Improvements and next steps
402 @subsection translatable_plugin_information Translatable plugin information
404 After having written our first plugin, there is still room for improvement.
406 By default, PLUGIN_SET_INFO() does not allow translation of the basic plugin
407 information for plugins which are not shipped with Geany's core distribution.
408 Since most plugins are not shipped with Geany's core, it makes sense to
409 enable translation when the plugin is loaded so that it gets translated
410 inside Geany's Plugin Manager. As of Geany 0.19, the plugin API contains
411 the PLUGIN_SET_TRANSLATABLE_INFO() macro which enables translation of the
412 basic plugin details passed to PLUGIN_SET_INFO() when the plugin is loaded.
414 PLUGIN_SET_TRANSLATABLE_INFO() takes two more parameters than PLUGIN_SET_INFO(),
415 for a total of six parameters.
424 The @a Localdir and the @a Gettextpackage parameters are usually set inside
425 the build system. If this has been done, the call for example HelloWorld
426 plugin could look like:
429 PLUGIN_SET_TRANSLATABLE_INFO(
430 LOCALEDIR, GETTEXT_PACKAGE, _("Hello World"),
431 _("Just another tool to say hello world"),
432 "1.0", "John Doe <john.doe@example.org>");
435 When using this macro, you should use the gettext macro @a _() to mark
436 the strings like name and the short description as translatable as well. You
437 can see how this is done in the above example.
439 As you can see the author's information is not marked as translatable in
440 this example. The community has agreed that the best practice here is to
441 use, if possible, the latin version of the author's name followed by the
442 native spelling inside parenthesis, where applicable.
444 @subsection plugin_i18n Using i18n/l10n inside Plugin
447 You can (and should) also mark other strings beside the plugin's meta
448 information as translatable. Strings used in menu entries, information
449 boxes or configuration dialogs should also be translatable as well. Geany
450 offers a way to enable this in the plugin's code using the main_locale_init()
451 function provided by the plugin API. This function takes the same two
452 parameters discussed in the previous section; @a GETTEXT_PACKAGE and
455 The main_locale_init() function is best called during initialization in the
456 plugin's plugin_init() function. Adding this to the HelloWorld example could
459 void plugin_init(GeanyData *data)
461 main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
462 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
463 gtk_widget_show(main_menu_item);
464 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
466 g_signal_connect(main_menu_item, "activate",
467 G_CALLBACK(item_activate_cb), NULL);
471 @note If you've previously called the PLUGIN_SET_TRANSLATABLE_INFO() you do not
472 need to call main_locale_init() yourself, as this has been already been