Remove struct/macro/funcptr linkage control for plugin API
[geany-mirror.git] / doc / plugins.dox
blob1e46d4bba1d5ee8c389183e6112753bf5ebabc4b
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  *
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.
13  *
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.
18  *
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.
22  *
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++.
25  */
28 /**
30 @mainpage Geany Plugin API Documentation
32 @author Enrico Tröger, Nick Treleaven, Frank Lanitz, Matthew Brush
34 @section Intro
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
62 @section More
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
67 other useful notes.
69 @page guidelines Plugin Writing Guidelines
71 @section intro Introduction
73 The following hints and guidelines are only recommendations. Nobody is forced to follow
74 them at all.
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
101 comments.
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
126   @endcode
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
155 following.
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.
181 @code
182 #include <geanyplugin.h>
183 @endcode
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.
188 @note
189 @a plugindata.h contains the biggest part of the plugin API and provides some basic macros.
191 Then you should define two basic variables which will give access to data fields
192 provided by the plugin API.
193 @code
194 GeanyPlugin                     *geany_plugin;
195 GeanyData                       *geany_data;
196 @endcode
198 Now you can go on and write your first lines for your new plugin. As mentioned before,
199 you will need to implement and fill out a couple of functions/macros to make the plugin work.
200 So let's start with PLUGIN_VERSION_CHECK().
202 PLUGIN_VERSION_CHECK() is a convenient way to tell Geany which version of Geany's plugin API
203 is needed at minimum to run your plugin. The value is defined in
204 @a plugindata.h by @a GEANY_API_VERSION. In most cases this should be your minimum.
205 Nevertheless when setting this value, you should choose the lowest possible version here to
206 make the plugin compatible with a bigger number of versions of Geany.
208 For the next step, you will need to tell Geany some basic information about your plugin
209 which will be shown in the plugin manager dialog.
211 To do this you should use the PLUGIN_SET_INFO() macro, which expects 4 parameters:
212 - Plugin name
213 - Short description
214 - Version
215 - Author
217 Based on this, the line could look like:
218 @code
219 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
220                                 "1.0", "John Doe <john.doe@example.org>");
221 @endcode
223 Once this is done, you will need to implement the function which will be executed when the
224 plugin is loaded. Part of that function could be adding and removing of an item to
225 Geany's Tools menu, setting up keybindings or registering some callbacks. Also you will
226 need to implement the function that is called when your plugin is unloaded.
227 These functions are called plugin_init() and plugin_cleanup(). Let's see what this
228 looks like:
229 @code
230 PLUGIN_VERSION_CHECK(211)
232 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
233                                 "1.0", "Joe Doe <joe.doe@example.org>");
235 void plugin_init(GeanyData *data)
239 void plugin_cleanup(void)
242 @endcode
244 If you think this plugin seems not to implement any functionality right now and only wastes
245 some memory, you are right. But it should compile and load/unload in Geany nicely.
246 Now you have the very basic layout of a new plugin. Great, isn't it?
248 @note
250 If you would rather write the plugin in C++, you can do that by marking the
251 plugin functions that it implements as @c extern @c "C", for example:
253 @code
255 extern "C" void plugin_init(GeanyData *data)
259 extern "C" void plugin_cleanup(void)
262 @endcode
264 @section building Building
266 First make plugin.o:
268 @code gcc -c plugin.c -fPIC `pkg-config --cflags geany` @endcode
270 Then make the plugin library plugin.so (or plugin.dll on Windows):
272 @code gcc plugin.o -o plugin.so -shared `pkg-config --libs geany` @endcode
274 If all went OK, put the library into one of the paths Geany looks for plugins,
275 e.g. $prefix/lib/geany. See @ref paths "Installation paths" for details.
277 @note
279 If you are writing the plugin in C++, then you will need to use your C++
280 compiler here, for example @c g++.
282 @section realfunc Adding functionality
284 Let's go on and implement some real functionality.
286 As mentioned before, plugin_init() will be called when the plugin is loaded in Geany.
287 So it should implement everything that needs to be done during startup. In this case,
288 we'd like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
289 @code
290 void plugin_init(GeanyData *data)
292         GtkWidget *main_menu_item;
294         // Create a new menu item and show it
295         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
296         gtk_widget_show(main_menu_item);
298         // Attach the new menu item to the Tools menu
299         gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
300                 main_menu_item);
302         // Connect the menu item with a callback function
303         // which is called when the item is clicked
304         g_signal_connect(main_menu_item, "activate",
305                 G_CALLBACK(item_activate_cb), NULL);
307 @endcode
309 This will add an item to the Tools menu and connect this item to a function which implements
310 what should be done when the menu item is activated by the user.
311 This is done by g_signal_connect(). The Tools menu can be accessed with
312 geany->main_widgets->tools_menu. The structure @a main_widgets contains pointers to the
313 main GUI elements in Geany.
315 Geany has a simple API for showing message dialogs. So our function contains
316 only a few lines:
317 @code
318 void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
320         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
322 @endcode
324 For the moment you don't need to worry about the parameters of that function.
326 Now we need to clean up properly when the plugin is unloaded.
328 To remove the menu item from the Tools menu, you can use gtk_widget_destroy().
329 gtk_widget_destroy() expects a pointer to a GtkWidget object.
331 First you should add gtk_widget_destroy() to your plugin_cleanup() function.
332 The argument for gtk_widget_destroy() is the widget object you created earlier in
333 plugin_init(). To be able to access this pointer in plugin_cleanup(), you need to move
334 its definition from plugin_init() into the global context so its visibility will increase
335 and it can be accessed in all functions.
336 @code
337 static GtkWidget *main_menu_item = NULL;
339 // ...
340 void plugin_init(GeanyData *data)
342         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
343         gtk_widget_show(main_menu_item);
344 // ...
347 void plugin_cleanup(void)
349         gtk_widget_destroy(main_menu_item);
351 @endcode
353 This will ensure your menu item is removed from the Tools menu as well as from
354 memory once your plugin is unloaded, so you don't leave any memory leaks.
355 Once this is done, your first plugin is ready. Congratulations!
357 @section listing Complete listing (without comments)
359 @code
360 #include <geanyplugin.h>
362 GeanyPlugin             *geany_plugin;
363 GeanyData               *geany_data;
365 PLUGIN_VERSION_CHECK(211)
367 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
368                                 "1.0", "John Doe <john.doe@example.org>");
371 static GtkWidget *main_menu_item = NULL;
373 static void item_activate_cb(GtkMenuItem *menuitem, gpointer gdata)
375         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
378 void plugin_init(GeanyData *data)
380         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
381         gtk_widget_show(main_menu_item);
382         gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
383                 main_menu_item);
384         g_signal_connect(main_menu_item, "activate",
385                 G_CALLBACK(item_activate_cb), NULL);
388 void plugin_cleanup(void)
390         gtk_widget_destroy(main_menu_item);
392  @endcode
395 Now you might like to look at Geany's source code for core plugins such as
396 @a plugins/demoplugin.c.
398 @section furtherimprovements Furter Improvements and next steps
399 @subsection translatable_plugin_information Translatable plugin information
401 After having written our first plugin, there is still room for improvement.
403 By default, PLUGIN_SET_INFO() does not allow translation of the basic plugin
404 information for plugins which are not shipped with Geany's core distribution.
405 Since most plugins are not shipped with Geany's core, it makes sense to
406 enable translation when the plugin is loaded so that it gets translated
407 inside Geany's Plugin Manager.  As of Geany 0.19, the plugin API contains
408 the PLUGIN_SET_TRANSLATABLE_INFO() macro which enables translation of the
409 basic plugin details passed to PLUGIN_SET_INFO() when the plugin is loaded.
411 PLUGIN_SET_TRANSLATABLE_INFO() takes two more parameters than PLUGIN_SET_INFO(),
412 for a total of six parameters.
414  - Localedir
415  - Gettextpackage
416  - Plugin name
417  - Short description
418  - Version
419  - Author
421 The @a Localdir and the @a Gettextpackage parameters are usually set inside
422 the build system.  If this has been done, the call for example HelloWorld
423 plugin could look like:
425 @code
426 PLUGIN_SET_TRANSLATABLE_INFO(
427         LOCALEDIR, GETTEXT_PACKAGE, _("Hello World"),
428         _("Just another tool to say hello world"),
429         "1.0", "John Doe <john.doe@example.org>");
430 @endcode
432 When using this macro, you should use the gettext macro @a _() to mark
433 the strings like name and the short description as translatable as well. You
434 can see how this is done in the above example.
436 As you can see the author's information is not marked as translatable in
437 this example.  The community has agreed that the best practice here is to
438 use, if possible, the latin version of the author's name followed by the
439 native spelling inside parenthesis, where applicable.
441 @subsection plugin_i18n Using i18n/l10n inside Plugin
444 You can (and should) also mark other strings beside the plugin's meta
445 information as translatable.  Strings used in menu entries, information
446 boxes or configuration dialogs should also be translatable as well.  Geany
447 offers a way to enable this in the plugin's code using the main_locale_init()
448 function provided by the plugin API. This function takes the same two
449 parameters discussed in the previous section; @a GETTEXT_PACKAGE and
450 @a LOCALEDIR.
452 The main_locale_init() function is best called during initialization in the
453 plugin's plugin_init() function.  Adding this to the HelloWorld example could
454 look like:
455 @code
456 void plugin_init(GeanyData *data)
458         main_locale_init(LOCALEDIR, GETTEXT_PACKAGE);
459         main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
460         gtk_widget_show(main_menu_item);
461         gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
462                 main_menu_item);
463         g_signal_connect(main_menu_item, "activate",
464                 G_CALLBACK(item_activate_cb), NULL);
466 @endcode
468 @note If you've previously called the PLUGIN_SET_TRANSLATABLE_INFO() you do not
469 need to call main_locale_init() yourself, as this has been already been
470 done for you.