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-2011 Frank Lanitz <frank(at)frank(dot)uvena(dot)de>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 * This file contains additional plugin documentation like the signal system and a small howto.
26 * It is best viewed when filetype is set to C or C++.
32 * @mainpage Geany Plugin API Documentation
34 * @author Enrico Tröger, Nick Treleaven, Frank Lanitz
38 * This is the Geany API documentation. It should be considered work in progress.
39 * We will try to document as many functions and structs as possible.
41 * @warning Do not use any symbol not in the documentation - it may change.
43 * @section pluginsupport Plugin Support
44 * - @link howto Plugin HowTo @endlink - get started
45 * - @link pluginsymbols.c Plugin Symbols @endlink
46 * - @link plugindata.h Plugin Datatypes and Macros @endlink
47 * - @link pluginsignals.c Plugin Signals @endlink
48 * - @link pluginutils.h Plugin Utility Functions @endlink
49 * - @link guidelines Plugin Writing Guidelines @endlink
50 * - <b>plugins/demoplugin.c</b> - in Geany's source, bigger than the howto example
52 * @section common Common API files
53 * - @link dialogs.h @endlink
54 * - @link document.h @endlink
55 * - @link editor.h @endlink
56 * - @link filetypes.h @endlink
57 * - @link keybindings.h @endlink
58 * - @link msgwindow.h @endlink
59 * - @link project.h @endlink
60 * - @link sciwrappers.h Scintilla Wrapper Functions @endlink
61 * - @link stash.h Stash Pref/Setting Functions @endlink
62 * - @link utils.h General Utility Functions @endlink
63 * - @link ui_utils.h Widget Utility Functions @endlink
66 * - All API functions and types - see <b>Files</b> link at the top
67 * - Deprecated symbols - see <b>Related Pages</b> link at the top
69 * @note See the HACKING file for information about developing the plugin API and
74 * @page guidelines Plugin Writing Guidelines
76 * @section intro Introduction
78 * The following hints and guidelines are only recommendations. Nobody is forced to follow
81 * @section general General notes
83 * @subsection ideas Getting a plugin idea
85 * If you want to write a plugin but don't know yet what it should do, have a look at
86 * http://www.geany.org/Support/PluginWishlist to get an idea about what users wish.
88 * @subsection code Managing the source code
90 * For authors of plugins for Geany, we created a dedicated @a geany-plugins project at
91 * Sourceforge to ease development of plugins and help new authors.
92 * Project website: http://sourceforge.net/projects/geany-plugins
94 * Each plugin author is welcome to use these services. To do so, you need an account at
95 * Sourceforge. You can easily register at (http://sourceforge.net/account/registration/).
96 * After you successfully created an account,
97 * tell your account name Enrico or Nick and you will write access to the SVN repository
98 * (http://geany-plugins.svn.sourceforge.net/viewvc/geany-plugins/).
99 * Then you can use the repository for your own plugin.
101 * Authors using this service should subscribe to the
102 * geany-plugins-commits at uvena.de and geany-plugins-tracker at uvena.de
103 * mailing lists(see my previous post) to stay up to date with changes.
104 * General plugin discussion can happen on the normal geany at uvena.de or
105 * geany-devel at uvena.de lists.
107 * At time of writing, there are some plugins already available in the
108 * repository. Feel free to use any of these plugins as a start for your own,
109 * maybe by copying the directory structure and the autotools files
110 * (Makefile.am, configure.in, ...). Most of the available plugins are also ready for
111 * i18n support, just for reference.
113 * New plugins should be imported into a new directory inside the trunk/
114 * directory. There are also the common branches and tags directories, use
115 * them as needed, use always a subdirectory for your own plugin.
117 * We encourage authors using this service to only commit changes to their
118 * own plugin and not to others' plugins. Instead just send patches to
119 * geany-devel at uvena.de or the plugin author directly.
121 * (the full announcement of this service can be found at
122 * http://lists.uvena.de/geany/2008-April/003225.html)
125 * @section paths Installation paths
127 * - The plugin binary (@c pluginname.so) should be installed in Geany's libdir. This is
128 * necessary so that Geany can find the plugin.
129 * An easy way to retrieve Geany's libdir is to use the pkg-config tool, e.g. @code
130 * `$PKG_CONFIG --variable=libdir geany`/ geany
132 * - If your plugin creates other binary files like helper programs or helper libraries,
133 * they should go into @c $prefix/bin (for programs, ideally prefixed with @a geany),
134 * additional libraries should be installed in Geany's libdir, maybe in a subdirectory.
135 * - Plugins should install their documentation files (README, NEWS, ChangeLog, licences and
136 * other documentation files) into the common documentation directory
137 * @c $prefix/share/doc/geany-plugins/$pluginname/
138 * - Translation files should be installed normally into @c $prefix/share/locale. There is no
139 * need to use Geany's translation directory. To set up translation support properly and
140 * for additional information, see main_locale_init().
141 * - Do @a never install anything into a user's home directory like installing
142 * the plugin binary in @c ~/.config/geany/plugins/.
145 * @page howto Plugin HowTo
147 * @section intro Introduction
149 * Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
150 * add new features. This document gives a brief overview about how to add new
151 * plugins by writing a simple "Hello World" plugin in C.
154 * @section buildenv Build environment
156 * To be able to write plugins for Geany, you need the source code and some development
157 * packages for GTK and its dependencies. The following will only describe the way to compile and
158 * build plugins on Unix-like systems [1].
159 * If you already have the Geany source code and compiled it from them, you can skip the
162 * First you need to have Geany installed. Then install the development files for GTK
163 * and its dependencies. The easiest way to do this is to use your distribution's package
164 * management system, e.g. on Debian and Ubuntu systems you can use
165 * @code apt-get install libgtk2.0-dev intltool @endcode
166 * This will install all necessary files to be able to compile plugins for Geany. On other
167 * distributions, the package names and commands to use may differ.
169 * Basically, you are done at this point and could continue with writing the plugin code.
171 * [1] For Windows, it is basically the same but you might have some more work on setting up
172 * the general build environment(compiler, GTK development files, ...). This is described on
173 * Geany's website at http://www.geany.org/Support/BuildingOnWin32.
175 * @section helloworld "Hello World"
177 * When writing a plugin, you will find a couple of functions or macros which are mandatory
178 * and some which are free to use for implementing some useful feature once your plugin
179 * becomes more powerful like including a configuration or help dialog.
181 * You should start your plugin with including some of the needed C header files and defining
182 * some basic global variables which will help you to access all needed functions of the plugin
183 * API in a more comfortable way.
185 * Let's start with the very basic headers and add more later if necessary.
187 #include "geanyplugin.h"
190 * @a geanyplugin.h includes all of the Geany API and also the necessary GTK header files,
191 * so there is no need to include @a gtk/gtk.h yourself.
194 * @a plugindata.h contains the biggest part of the plugin API and provides some basic macros.
195 * @a geanyfunctions.h provides some macros for convenient access to plugin API functions.
197 * The you should define three basic variables which will give access to data fields and
198 * functions provided by the plugin API.
200 GeanyPlugin *geany_plugin;
201 GeanyData *geany_data;
202 GeanyFunctions *geany_functions;
205 * Now you can go on and write your first lines for your new plugin. As mentioned before,
206 * you will need to implement and fill out a couple of functions/macros to make the plugin work.
207 * So let's start with PLUGIN_VERSION_CHECK().
209 * PLUGIN_VERSION_CHECK() is a convenient way to tell Geany which version of Geany's plugin API
210 * is needed at minimum to run your plugin. The value is defined in
211 * @a plugindata.h by @a GEANY_API_VERSION. In most cases this should be your minimum.
212 * Nevertheless when setting this value, you should choose the lowest possible version here to
213 * make the plugin compatible with a bigger number of versions of Geany.
215 * For the next step, you will need to tell Geany some basic information about your plugin
216 * which will be shown in the plugin manager dialog.
218 * For doing this, you should use PLUGIN_SET_INFO() which expects 4 values:
220 * - Short description
224 * Based on this, the line could look like:
226 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
227 "1.0", "John Doe <john.doe@example.org>");
230 * Once this is done, you will need to implement the function which will be executed when the
231 * plugin is loaded. Part of that function could be adding and removing of an item to
232 * Geany's Tools menu, setting up keybindings or registering some callbacks. Also you will
233 * need to implement the function that is called when your plugin is unloaded.
234 * These functions are called plugin_init() and plugin_cleanup(). Let's see how it could look like:
236 PLUGIN_VERSION_CHECK(147)
238 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
239 "1.0", "Joe Doe <joe.doe@example.org>");
241 void plugin_init(GeanyData *data)
245 void plugin_cleanup(void)
250 * If you think this plugin seems not to implement any functionality right now and only wastes
251 * some memory, you are right. But it should compile and load/unload in Geany nicely.
252 * Now you have the very basic layout of a new plugin. Great, isn't it?
254 * @section building Building
256 * First make plugin.o:
258 * @code gcc -c plugin.c -fPIC `pkg-config --cflags geany` @endcode
260 * Then make the plugin library plugin.so (or plugin.dll on Windows):
262 * @code gcc plugin.o -o plugin.so -shared `pkg-config --libs geany` @endcode
264 * If all went OK, put the library into one of the paths Geany looks for plugins,
265 * e.g. $prefix/lib/geany. See @ref paths "Installation paths" for details.
267 * @section realfunc Adding functionality
269 * Let's go on and implement some real functionality.
271 * As mentioned before, plugin_init() will be called when the plugin is loaded in Geany.
272 * So it should implement everything that needs to be done during startup. In this case,
273 * we'd like to add a menu item to Geany's Tools menu which runs a dialog printing "Hello World".
275 void plugin_init(GeanyData *data)
277 GtkWidget *main_menu_item;
279 // Create a new menu item and show it
280 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
281 gtk_widget_show(main_menu_item);
283 // Attach the new menu item to the Tools menu
284 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
287 // Connect the menu item with a callback function
288 // which is called when the item is clicked
289 g_signal_connect(main_menu_item, "activate",
290 G_CALLBACK(item_activate_cb), NULL);
294 * This will add an item to the Tools menu and connect this item to a function which implements
295 * what should be done when the menu item is activated by the user.
296 * This is done by g_signal_connect(). The Tools menu can be accessed with
297 * geany->main_widgets->tools_menu. The structure @a main_widgets contains pointers to the
298 * main GUI elements in Geany.
300 * Geany has a simple API for showing message dialogs. So our function contains
303 void item_activate_cb(GtkMenuItem *menuitem, gpointer user_data)
305 dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
309 * For the moment you don't need to worry about the parameters of that function.
311 * Now we need to clean up properly when the plugin is unloaded.
313 * To remove the menu item from the Tools menu, you can use gtk_widget_destroy().
314 * gtk_widget_destroy() expects a pointer to a GtkWidget object.
316 * First you should add gtk_widget_destroy() to your plugin_cleanup() function.
317 * The argument for gtk_widget_destroy() is the widget object you created earlier in
318 * plugin_init(). To be able to access this pointer in plugin_cleanup(), you need to move
319 * its definition from plugin_init() into the global context so its visibility will increase
320 * and it can be accessed in all functions.
322 static GtkWidget *main_menu_item = NULL;
325 void plugin_init(GeanyData *data)
327 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
328 gtk_widget_show(main_menu_item);
332 void plugin_cleanup(void)
334 gtk_widget_destroy(main_menu_item);
338 * This will ensure your menu item is removed from the Tools menu as well as from
339 * memory once your plugin is unloaded, so you don't leave any memory leaks.
340 * Once this is done, your first plugin is ready. Congratulations!
342 * @section listing Complete listing (without comments)
345 #include "geanyplugin.h"
347 GeanyPlugin *geany_plugin;
348 GeanyData *geany_data;
349 GeanyFunctions *geany_functions;
351 PLUGIN_VERSION_CHECK(147)
353 PLUGIN_SET_INFO("HelloWorld", "Just another tool to say hello world",
354 "1.0", "John Doe <john.doe@example.org>");
357 static GtkWidget *main_menu_item = NULL;
359 static void item_activate_cb(GtkMenuItem *menuitem, gpointer gdata)
361 dialogs_show_msgbox(GTK_MESSAGE_INFO, "Hello World");
364 void plugin_init(GeanyData *data)
366 main_menu_item = gtk_menu_item_new_with_mnemonic("Hello World");
367 gtk_widget_show(main_menu_item);
368 gtk_container_add(GTK_CONTAINER(geany->main_widgets->tools_menu),
370 g_signal_connect(main_menu_item, "activate",
371 G_CALLBACK(item_activate_cb), NULL);
374 void plugin_cleanup(void)
376 gtk_widget_destroy(main_menu_item);
381 * Now you might like to look at Geany's source code for core plugins such as
382 * @a plugins/demoplugin.c.