Start to make it easier to compile the core in isolation
[geany-mirror.git] / doc / plugins.dox
blob5e7acd11045a9ee9d08818dd36a94349623aa87c
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.
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.
194 @code
195 GeanyPlugin                     *geany_plugin;
196 GeanyData                       *geany_data;
197 GeanyFunctions          *geany_functions;
198 @endcode
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:
214 - Plugin name
215 - Short description
216 - Version
217 - Author
219 Based on this, the line could look like:
220 @code
221 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
222                                 "1.0", "John Doe <john.doe@example.org>");
223 @endcode
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
230 looks like:
231 @code
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)
244 @endcode
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?
250 @note
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:
255 @code
257 extern "C" void plugin_init(GeanyData *data)
261 extern "C" void plugin_cleanup(void)
264 @endcode
266 @section building Building
268 First make plugin.o:
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.
279 @note
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".
291 @code
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),
302                 main_menu_item);
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);
309 @endcode
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
318 only a few lines:
319 @code
320 void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
322         dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
324 @endcode
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.
338 @code
339 static GtkWidget *main_menu_item = NULL;
341 // ...
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);
346 // ...
349 void plugin_cleanup(void)
351         gtk_widget_destroy(main_menu_item);
353 @endcode
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)
361 @code
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),
386                 main_menu_item);
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);
395  @endcode
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.
417  - Localedir
418  - Gettextpackage
419  - Plugin name
420  - Short description
421  - Version
422  - Author
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:
428 @code
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>");
433 @endcode
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
453 @a LOCALEDIR.
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
457 look like:
458 @code
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),
465                 main_menu_item);
466         g_signal_connect(main_menu_item, "activate",
467                 G_CALLBACK(item_activate_cb), NULL);
469 @endcode
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
473 done for you.