6d4068f7b3
Add 'make hacking-doc' target to generate hacking.html. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3029 ea778897-0a13-0410-b9d1-a72fbfd435f5
320 lines
12 KiB
Plaintext
320 lines
12 KiB
Plaintext
=============
|
|
Hacking Geany
|
|
=============
|
|
.. contents::
|
|
|
|
General
|
|
=======
|
|
|
|
About this file
|
|
---------------
|
|
This file contains information for anyone wanting to work on the Geany
|
|
codebase. You should be aware of the open source licenses used - see
|
|
the README file or the documentation. It is reStructuredText; the
|
|
source file is HACKING. You can generate hacking.html by running ``make
|
|
hacking-doc`` from the doc/ subdirectory.
|
|
|
|
Writing plugins
|
|
---------------
|
|
* src/plugindata.h contains the plugin API data types.
|
|
* See plugins/demoplugin.c for a very basic example plugin.
|
|
* src/plugins.c loads and unloads plugins (you shouldn't need to read
|
|
this really).
|
|
|
|
You should generate and read the plugin API documentation, see below.
|
|
|
|
Plugin API documentation
|
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
|
You can generate documentation for the plugin API using the doxygen
|
|
tool. Run ``make api-doc`` in the doc subdirectory. The documentation
|
|
will be output to doc/reference/index.html.
|
|
|
|
Patches
|
|
-------
|
|
We are happy to receive patches, but it's best to check with us by email
|
|
or mailing list whether a new feature is appropriate, and whether someone
|
|
is already working on similar code.
|
|
|
|
In general it's best to work from the current SVN, but we accept patches
|
|
against other releases::
|
|
|
|
$ svn diff > fix-some-bug.patch
|
|
|
|
If you're not using SVN, you can use the diff command::
|
|
|
|
$ diff -u originalpath modifiedpath > new-feature.patch
|
|
|
|
Please make sure patches follow the style of existing code - In
|
|
particular, use tabs for indentation. See `Style`_ and `Coding`_.
|
|
|
|
For Windows:
|
|
Subversion (SVN): http://subversion.tigris.org/
|
|
diff, grep, etc: http://mingw.org/ or http://unxutils.sourceforge.net/.
|
|
See also the 'Building on Windows' document on the website.
|
|
|
|
File organization
|
|
-----------------
|
|
callbacks.c is just for Glade callbacks.
|
|
Avoid adding code to geany.h if it will fit better elsewhere.
|
|
See the top of each ``src/*.c`` file for a brief description of what
|
|
it's for.
|
|
|
|
Keeping the plugin ABI stable
|
|
-----------------------------
|
|
Please be aware that anything with a doc-comment (a comment with an
|
|
extra asterix: ``/**``) is something in the plugin API. Things like
|
|
enums and structs can usually still be appended to, ensuring that all
|
|
the existing elements stay in place - this will keep the ABI stable.
|
|
|
|
.. warning::
|
|
|
|
Some structs like GeanyKeyGroup and GeanyCallback cannot be
|
|
appended to without breaking the ABI because they are used to declare
|
|
structs by plugins, not just for accessing struct members through
|
|
a pointer.
|
|
|
|
Before the 1.0 release series, the ABI can change when necessary, and
|
|
even the API can change. An ABI change just means that all plugins will
|
|
not load and they must be rebuilt. An API change means that some plugins
|
|
might not build correctly.
|
|
|
|
When reordering or changing existing elements of structs that are
|
|
used as part of the plugin API, you should increment GEANY_ABI_VERSION
|
|
in plugindata.h. This is usually not needed if you're just appending
|
|
fields to structs. The GEANY_API_VERSION value should be incremented
|
|
for any changes to the plugin API, including appending elements.
|
|
|
|
If you're in any doubt when making changes to plugin API code, just ask us.
|
|
|
|
Glade
|
|
-----
|
|
Use the code generation features of Glade instead of editing interface.c
|
|
or support.c. Glade 2.10 is recommended as long as we support GTK+ 2.6,
|
|
because later versions of Glade are not 100% compatible with GTK+ 2.6
|
|
(e.g. they may use functions added in GTK+ 2.8).
|
|
|
|
You can build Glade 2.10 and run the binary in place, without installing
|
|
it - this should work fine even if you have another version of Glade
|
|
installed on the system.
|
|
|
|
GTK API documentation
|
|
---------------------
|
|
The official GTK 2.6 API documentation is not available online anymore,
|
|
so we put them on http://www.geany.org/manual/gtk/.
|
|
There is also a tarball with all available files for download and use
|
|
with devhelp.
|
|
|
|
Using the 2.6 API documentation of the GTK libs (including GLib, GDK and
|
|
Pango) has the advantages that you don't get confused by any newer API
|
|
additions and you don't have to take care about whether you can use
|
|
them or not.
|
|
This is because Geany depends on GTK 2.6. API symbols from newer
|
|
GTK/GLib versions should be avoided to keep the source code building
|
|
against GTK 2.6.
|
|
|
|
Coding
|
|
------
|
|
* Don't write long functions with a lot of variables and/or scopes - break
|
|
them down into smaller static functions where possible. This makes code
|
|
much easier to read and maintain.
|
|
* Use GLib types and functions - e.g. g_free instead of free.
|
|
* Your code should build against GLib 2.6 and GTK 2.6. At least for the
|
|
moment, we want to keep the minimum requirement for GTK at 2.6 (of
|
|
course, you can use the GTK_CHECK_VERSION macro to protect code using
|
|
later versions).
|
|
* We currently try to support the old GCC 2.9.x compiler,
|
|
so we always declare variables before statements. You can use
|
|
-Wdeclaration-after-statement in your ./configure CFLAGS to warn about
|
|
this.
|
|
* You should also try to write ISO C90 code for portability, so always
|
|
use C ``/* */`` comments and function_name(void) instead of
|
|
function_name(). This is for compatibility with various Unix-like
|
|
compilers. You can use -ansi in your CFLAGS to help check this.
|
|
|
|
Style
|
|
-----
|
|
* We use a tab width of 4 and indent completely with tabs not spaces.
|
|
* Use the multiline comment ``/* */`` to comment small blocks of code,
|
|
functions descriptions or longer explanations of code, etc. C++ single
|
|
line comments will cause portability issues. The more comments are in
|
|
your code the better.
|
|
* Lines should not be longer than about 100 characters and after 100
|
|
characters the lines should be wrapped and more indented than the first
|
|
line to highlight that the line is continued.
|
|
* We don't put spaces between function names and the opening brace for
|
|
argument lists.
|
|
* Try to fit in with the existing code brace indenting style, comments,
|
|
operator spacing etc. It's not required but it makes our lives easier
|
|
;-)
|
|
|
|
Libraries
|
|
---------
|
|
We prefer to use an unmodified version of Scintilla - any changes should
|
|
be passed on to the maintainers at http://scintilla.org.
|
|
|
|
Tagmanager was originally taken from Anjuta 1.2.2, and parts of it
|
|
(notably c.c) have been merged from later versions of Anjuta and
|
|
CTags. The independent Tagmanager library itself ceased development
|
|
before Geany was started. It's source code parsing is mostly taken from
|
|
Exuberant CTags (see http://ctags.sf.net).
|
|
|
|
|
|
Notes
|
|
=====
|
|
Some of these notes below are brief (or maybe incomplete) - please
|
|
contact the geany-devel mailing list for more information.
|
|
|
|
Using pre-defined autotools values
|
|
----------------------------------
|
|
When you are use macros supplied by the autotools like GEANY_PREFIX,
|
|
GEANY_LIBDIR, GEANY_DATADIR and GEANY_LOCALEDIR be aware that these
|
|
might not be static strings when Geany is configured with
|
|
--enable-binreloc. Then these macros will be replaced by function calls
|
|
(in src/prefix.h). So, don't use anything like
|
|
printf("Prefix: " GEANY_PREFIX); but instead use
|
|
printf("Prefix: %s", GEANY_PREFIX);
|
|
|
|
Adding a source file foo.[hc] in src/ or plugins/
|
|
-------------------------------------------------
|
|
* Add foo.c, foo.h to SRCS in path/Makefile.am.
|
|
* Add foo.o to OBJS in path/makefile.win32.
|
|
* Add path/foo.c to po/POTFILES.in (for string translation).
|
|
|
|
Adding a filetype
|
|
-----------------
|
|
You can add a filetype without syntax highlighting or tag parsing, but
|
|
check to see if those features have been written in other projects first.
|
|
|
|
* Add GEANY_FILETYPES_FOO to filetypes.h.
|
|
* Initialize GEANY_FILETYPES_FOO in init_builtin_filetypes() of
|
|
filetypes.c.
|
|
* Rebuild Geany.
|
|
* From your geany/ directory, run::
|
|
|
|
src/geany --generate-data-files
|
|
|
|
(The src/ prefix may be different, depending on where the binary is
|
|
generated.)
|
|
This will update data/filetype_extensions.conf. Note that
|
|
you need GEANY_DEBUG to be defined when building Geany for the
|
|
--generate-data-files argument to work - this is always defined in the
|
|
SVN version. Alternatively, edit the file by hand.
|
|
|
|
filetypes.* configuration file
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
All languages need a data/filetypes.foo configuration file. See
|
|
data/filetypes.c for an example.
|
|
|
|
Programming languages should have:
|
|
|
|
* [keywords] if the lexer supports it.
|
|
* [settings] mostly for comment settings.
|
|
* [build_settings] for commands to run.
|
|
|
|
For languages with a Scintilla lexer, there should be a [styling] section,
|
|
to correspond to the styles used in styleset_foo() in highlighting.c -
|
|
see below.
|
|
|
|
Syntax highlighting
|
|
^^^^^^^^^^^^^^^^^^^
|
|
It may be possible to use an existing Scintilla lexer in the scintilla/
|
|
subdirectory - if not, you will need to find (or write) one,
|
|
LexFoo.cxx. Try the Scintilla project first. When adding a lexer, update:
|
|
|
|
* scintilla/Makefile.am
|
|
* scintilla/makefile.win32
|
|
* scintilla/KeyWords.cxx - add a LINK_LEXER command *manually*
|
|
|
|
For syntax highlighting, you will need to edit highlighting.c and add
|
|
the following things:
|
|
|
|
1. Write styleset_foo_init() to setup default styles and load style
|
|
settings from the filetypes.foo configuration file. You should probably
|
|
start by copying and adapting another filetype's initialization, such
|
|
as styleset_asm_init().
|
|
2. Write styleset_foo() to apply styles when a new scintilla widget
|
|
is created. Again you could copy and adapt a function like styleset_asm().
|
|
3. In highlighting_init_styles(), add
|
|
``init_styleset_case(GEANY_FILETYPES_FOO, foo);``.
|
|
4. In highlighting_set_styles(), add
|
|
``styleset_case(GEANY_FILETYPES_FOO, foo);``.
|
|
|
|
Please try to make your styles fit in with the other filetypes' default
|
|
colors.
|
|
|
|
Error message parsing
|
|
^^^^^^^^^^^^^^^^^^^^^
|
|
New-style error message parsing is done with an extended GNU-style regex
|
|
stored in the filetypes.foo file - see the [build_settings] information
|
|
in the manual for details.
|
|
|
|
Old-style error message parsing is done in
|
|
msgwin_parse_compiler_error_line() of msgwindow.c - see the ParseData
|
|
typedef for more information.
|
|
|
|
Other features
|
|
^^^^^^^^^^^^^^
|
|
For brace indentation, update lexer_has_braces() in editor.c;
|
|
indentation after ':' is done from on_new_line_added().
|
|
|
|
If the lexer has comment styles, you should add them in is_comment_style()
|
|
in editor.c. You should also update is_string_style() for string/character
|
|
styles. For now, this prevents calltips and autocompletion when typing
|
|
in a comment (but it can still be forced by the user).
|
|
|
|
If the Scintilla lexer supports user type keyword highlighting (e.g.
|
|
SCLEX_CPP), update editor_lexer_get_type_keyword_idx() in editor.c.
|
|
|
|
Adding a TagManager parser
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
This assumes the filetype for Geany already exists.
|
|
|
|
First write or find a CTags compatible parser, foo.c. Note that there
|
|
are some language patches for CTags at:
|
|
http://sf.net/projects/ctags - see the tracker.
|
|
|
|
(You can also try the Anjuta project's tagmanager codebase.)
|
|
|
|
* Add foo.c to SRCS in Makefile.am.
|
|
* Add foo.o to OBJS in makefile.win32.
|
|
* Add Foo to parsers.h & fill in comment with parser number for foo.
|
|
|
|
In foo.c:
|
|
Edit FooKinds 3rd column to match a s_tag_type_names string in tm_tag.c.
|
|
|
|
In filetypes.c, init_builtin_filetypes():
|
|
Set filetypes[GEANY_FILETYPES_FOO].lang = foo's parser number.
|
|
|
|
In symbols.c:
|
|
Update init_tag_list() for foo, listing the tm_tag_* types corresponding
|
|
to the s_tag_type_names strings used in foo.c for FooKinds.
|
|
|
|
|
|
Loading a plugin from GDB
|
|
-------------------------
|
|
This is useful so you can load plugins without installing them first.
|
|
Alternatively you can use a symlink in ~/.geany/plugins or
|
|
$prefix/lib/geany (where $prefix is /usr/local by default).
|
|
|
|
The gdb session below was run from the toplevel Geany source directory.
|
|
Start normally with e.g. "gdb src/geany".
|
|
Type 'r' to run.
|
|
Press Ctrl-C from the gdb window to interrupt program execution.
|
|
|
|
Example::
|
|
|
|
Program received signal SIGINT, Interrupt.
|
|
0x00d16402 in __kernel_vsyscall ()
|
|
(gdb) call plugin_new("./plugins/.libs/demoplugin.so")
|
|
** INFO: Loaded: ./plugins/.libs/demoplugin.so (Demo)
|
|
$1 = (Plugin *) 0x905a890
|
|
(gdb) c
|
|
Continuing.
|
|
|
|
Program received signal SIGINT, Interrupt.
|
|
0x00d16402 in __kernel_vsyscall ()
|
|
(gdb) call plugin_free(0x905a890)
|
|
** INFO: Unloaded: ./plugins/.libs/demoplugin.so
|
|
(gdb) c
|
|
Continuing.
|