========================
Hacking on Geany-Plugins
========================
.. contents::

General
=======

About this file
---------------
This file contains some useful information for any plugin developer, and
especially for new plugin developers. A lot of information inside
`Geany's HACKING file <http://geany.org/manual/hacking.html>` is useful
as well, so it's recommended you give it a read.


Building your plugin
--------------------
You should first read `README` to understand how to build the plugins in
general.


Autotools Build System
^^^^^^^^^^^^^^^^^^^^^^
The Autotools build system automatically enables some code checking
utilities, meant to ease tracking of common programming mistakes, or simply
to help making everyone's plugin code better.
They currently are:

* C compiler warnings (can be disabled with the ``--disable-extra-c-warnings``
  configuration flag) -- this test is (obviouly) run during build;
* Static code analysis using ``cppcheck`` (can be disabled with the
  ``--disable-cppcheck`` configuration flag) -- this test is run during
  ``make check``.

These features are only here to help you writing better code: they
are not necessarily and always right -- though they try. However
it's highly recommended to make usage of them and fix maybe occuring
issues before submitting a patch. If you think they reports wrong
problems, please file a report on the appropriate place (either the
mailing lists or the geany-plugins bug tracker).


Documentation
-------------

README
^^^^^^

Each plugin folder should contain at least a `README` file for
documentation.


Markup language
###############

The `README` is intended to be written in `Restructured Text
<http://sphinx.pocoo.org/rest.html>`_ (as this document is) and
therefore should work with ``rst2html`` or similar tools. The reason
for this is that this information is used to generate the content of
the `Plugins Website <http://plugins.geany.org>`.


Recommended contents
####################

The documentation should include a detailed description on features
offered by the plugins and usage of those features. It should also
include some basic information to make it easier for users to get in
touch with the developer(s) or to find further help in case of any
issues.  You can use some of the other `README` files to get a
general idea of what should be in the file, but generally it should
contain:

* author(s) of plugin and their mail addresses
* external web site (if any)
* known issues
* bug tracker
* dependencies


Committing
----------

General
^^^^^^^

* Commit one thing at a time, do small commits. Commits should be
  meaningful and not too big when possible; multiple small commits are
  good if there is no good reason to group them.
* Use meaningful name and email in the Author and Committer fields.
  This helps knowing who did what and allows to contact the author if
  there is a good reason to do so (unlikely, but can happen). Using
  the email address associated with your GitHub account will allows
  for better integration with the website's hyperlinking to accounts
  features.
* When working on a new feature, create a new branch for it. When
  merging it, use the --no-ff option to make sure a merge commit will
  be created to better track what happened. However, if the feature
  only took one commit you might merge it fast-forward since there is
  not history to keep together.

Writing
^^^^^^^
* Please use "Geany" as it is not just a noun, but a name.

Commit messages
^^^^^^^^^^^^^^^

Follow the standard Git formatting:

* No line should use more than about 80 characters (around 72 is best).
* The first line is the commit's summary and is followed by an empty
  line. This summary should be one line and one line only, thus less
  than 80 characters. This summary should not include any punctuation
  unless really needed. See it as the subject of an email: keep it
  concise and as precise as you can, but not tool long.
* If you're working on a specific plugin, prefix the summary line
  with the lower case name of the plugin (same as the directory name)
  to make it easier to know which commit affected which plugin without
  having to thoroughly examine the commit diff itself.  No prefix is
  needed if the commit is non-plugin specific or affects only files
  outside of the plugins' directories.
* Following lines are optional detailed commit information, with
  paragraphs separated by blank lines. This part should be as long as
  needed to describe the commit in depth, should use proper
  punctuation and should include any useful information, like the
  motivation for the patch and/or any valuable details the diff itself
  doesn't provide or make clear. Make it as complete as you think
  it makes sense, but don't include an information that is better
  explained by the commit's diff.

  It is OK to use ASCII formatting like bullet list using "*" or "-",
  etc. if useful, but emphasis (bold, italic, underline) should be
  avoided.

Example::

    myfancyplugin: Ask the user if spawn fails in utils_open_browser()

    Ask the user to configure a valid browser command if spawning it
    fails rather than falling back to some arbitrary hardcoded defaults.

    This avoids spawning an unexpected browser when the configured one
    is wrong, and gives the user a chance to fix the preference.


Coding and Plugin structure
===========================

Structure of a plugin
---------------------

Your plugin shall be structured like this:

- yourplugin
    - src/
    - data/
    - doc/

Where you put all your source code inside the src-folder, all
additional data like scripts should be put into a seperate
data-folder and content for plugin documentation fit into the folder
doc.

Adding a new plugin to autotools build system
---------------------------------------------

configure.ac
^^^^^^^^^^^^

Add an entry into configure.ac for your plugin. The entry should look like
``GP_CHECK_YOURFANCYPLUGINNAME``.  This is a custom macro that will be
discussed in the `build sub-folder`_ section below.

Root Makefile.am
^^^^^^^^^^^^^^^^

Add an entry into the root Makefile.am where to find the sources of your
plugin.  This entry shall look like this::

 if ENABLE_YOURFANCYPLUGINNAME
 SUBDIRS += yourfancyplugin
 endif


`build` sub-folder
^^^^^^^^^^^^^^^^^^

To build your plugin you will also need to add an M4 script inside
the ``build`` sub-folder of the geany-plugin sources. The file should
be called ``yourfancypluginname.m4`` and contain the definition of the M4
macro that checks for your plugin's dependencies and generates its
build files, which macro is called from configure.ac::

 AC_DEFUN([GP_CHECK_YOURFANCYPLUGINNAME],
 [
     GP_ARG_DISABLE([yourfancypluginname], [auto])
     GP_COMMIT_PLUGIN_STATUS([yourfancypluginname])
     AC_CONFIG_FILES([
         yourplugin/Makefile
         yourplugin/src/Makefile
     ])
 ])

You may add checks for dependencies of your plugin between the
``GP_ARG_DISABLE`` and ``GP_COMMIT_PLUGIN_STATUS`` calls.  Note that you
must respect the ``$enable_yourfancypluginname`` (lowercase) variable
and try to avoid performing checks if it is set to ``no``, and never
abort unless it is set to ``yes``.  If a required dependency is not met
and ``$enable_yourfancypluginname`` is not set to ``yes``, you should
update ``enable_yourfancypluginname`` and set it to ``no`` to disable
building of your plugin.

To ease checking for modules using *pkg-config*, the
``GP_CHECK_PLUGIN_DEPS`` macro is provided, which wraps
``PKG_CHECK_MODULES`` and follows the above rules about plugin
enabling/disabling.

While we recommend plugins to work with both GTK 2 and 3, you can use
the ``GP_CHECK_PLUGIN_GTK2_ONLY`` or ``GP_CHECK_PLUGIN_GTK3_ONLY``
macros if your plugin only works with one version.

You may also check which GTK version is used for the build using either
the ``$GP_GTK_VERSION`` or ``$GP_GTK_PACKAGE`` variables, or the
``GP_CHECK_GTK3`` macro.  For example, if your plugin works with both
GTK 2 and 3 but you want to check for a minimal GTK2 version, you may
use ``$GP_GTK_PACKAGE >= 2.XX`` in a ``GP_CHECK_PLUGIN_DEPS`` call.


Makefiles inside your plugin folder
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The Makefiles inside your plugin folder can be separated at least
into two parts: The first part is located inside the root folder of
your plugin, whereas the second one is located inside ``src/`` of your
plugin.


Plugin root
###########

The file should be called ``Makefile.am`` and contains the entry
point for really building your plugin. The easiest version could look
similar to this::

    include $(top_srcdir)/build/vars.auxfiles.mk
    SUBDIRS = src
    plugin = yourfancypluginname


`src` folder
############

The ``Makefile.am`` inside the ``src`` folder declares how to build the
sources. An example could look like::

    include $(top_srcdir)/build/vars.build.mk

    yourfancypluginname_LTLIBRARIES = yourfancypluginname.la

    yourfancypluginname_la_SOURCES = yourfancypluginname.c
    yourfancypluginname_la_LIBADD = $(COMMONLIBS)

    include $(top_srcdir)/build/cppcheck.mk

If you checked for additional dependencies in ``yourfancypluginname.m4``
(besides Geany, GLib and GTK, which are included in ``$(COMMONLIBS)``),
you will need to use the various flags they might require.

For a library checked with ``GP_CHECK_PLUGIN_DEPS`` you will have to add
``$(PREFIX_CFLAGS)`` to ``yourfancypluginname_la_CFLAGS`` and
``$(PREFIX_LIBS)`` to ``yourfancypluginname_la_LIBADD`` (where
``PREFIX`` is the name you chose to store the results in the
``GP_CHECK_PLUGIN_DEPS`` call).  Note that if you set
``yourfancypluginname_la_CFLAGS`` you will need to explicitly mention
``$(AM_CFLAGS)`` in it.

For example, if you checked for the hypothetical library ``foo`` and
used the ``FOO`` prefix to store the results, you should alter the
Makefile.am to references them::

    yourfancypluginname_la_CFLAGS = $(AM_CFLAGS) $(FOO_CFLAGS)
    yourfancypluginname_la_LIBADD = $(COMMONLIBS) $(FOO_LIBS)



Additional things to do for a new plugin
----------------------------------------

Adding yourself to MAINTAINERS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As you might want to keep on maintaining your newly added plugin, we
recommend to put your contact data to file MAINTAINERS which is
located inside geany-plugins root folder. The entry should contain
your plugin name as well as some of the important data. An example
could look like::

	myfancyplugin
	P: Jon Doe <jon@example.org>
	M: Jon Doe <jon@example.org>
	W: http://example.org/myfancyplugin
	S: Maintained

The flags can be compiled like this:

* P: Person
* M: Mail patches to: FullName <address@domain>
* W: Web-page with status/info
* S: Status of plugin

Once you have a look onto MAINTAINERS you will see a lot of examples
as well as some more detailed information.


Adding your plugin-files to po/POTFILES.in
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you want to have your plugin translated into different languages
you will have to add your plugin to file po/POTFILES.in. This
contains a list of all translateable files for each plugin. An
example could look like::

	#myfancyplugin
	yourfancypluginname/src/yourfancypluginname.c


I18n/l10n
---------

Geany-Plugins is supporting localisation of your plugin. To make
usage of it, there needs to be done:

* Mark each string which should be translatable with the gettext macro
  ``_()`` or ``N_()`` for static strings. As an example the string
  ``"Hello World"`` might become ``_("Hello World")``.
* Add files with translateable strings into ``po/POTFILES.in``. You
  should group them for your plugin as done for the other. Each files
  needs to be put into one line with complete relative	 path from
  plugin root directory. E.g. ``myplugin/src/myplugin.c``
