summaryrefslogtreecommitdiff
path: root/doc/en/weechat_dev.en.asciidoc
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2014-05-25 12:25:58 +0200
committerSébastien Helleu <flashcode@flashtux.org>2014-05-25 12:47:24 +0200
commitdc0229617ada67fd02815bbc94b245871248b9db (patch)
tree0af7418d7f3ebf8082408fa2ee9e73f5a572360f /doc/en/weechat_dev.en.asciidoc
parent76a066c9cca620e1204815f63abbfa8b09f162c6 (diff)
downloadweechat-dc0229617ada67fd02815bbc94b245871248b9db.zip
doc: use .asciidoc extension instead of .txt for doc files
Diffstat (limited to 'doc/en/weechat_dev.en.asciidoc')
-rw-r--r--doc/en/weechat_dev.en.asciidoc1050
1 files changed, 1050 insertions, 0 deletions
diff --git a/doc/en/weechat_dev.en.asciidoc b/doc/en/weechat_dev.en.asciidoc
new file mode 100644
index 000000000..eb150b2ee
--- /dev/null
+++ b/doc/en/weechat_dev.en.asciidoc
@@ -0,0 +1,1050 @@
+= WeeChat developer's guide
+:author: Sébastien Helleu
+:email: flashcode@flashtux.org
+:lang: en
+:toc:
+:toclevels: 4
+
+
+This manual documents WeeChat chat client, it is part of WeeChat.
+
+Latest version of this document can be found on this page:
+http://weechat.org/doc
+
+
+[[introduction]]
+== Introduction
+
+WeeChat (Wee Enhanced Environment for Chat) is a free chat client, fast and
+light, designed for many operating systems.
+
+This manual documents WeeChat internals:
+
+* repository (sources, doc, ...)
+* coding rules
+* core internals
+* plugin internals
+* how to contribute to WeeChat.
+
+[[repository]]
+== Repository
+
+WeeChat has two main repositories:
+
+* core repository: it contains source code and documentation,
+ URL is: https://github.com/weechat/weechat
+* scripts: the 'official' scripts submitted on weechat.org,
+ URL is: https://github.com/weechat/scripts
+
+This manual documents only core repository.
+
+[[overview]]
+=== Overview
+
+The main WeeChat directories are:
+
+[width="100%",cols="1v,5",options="header"]
+|===
+| Directory | Description
+| src/ | Root of sources
+| core/ | Core functions: entry point, internal structures
+| gui/ | Functions for buffers, windows, ... (used by all interfaces)
+| curses/ | Curses interface
+| plugins/ | Plugin and scripting API
+| alias/ | Alias plugin
+| aspell/ | Aspell plugin
+| charset/ | Charset plugin
+| exec/ | Exec plugin
+| fifo/ | Fifo plugin (FIFO pipe used to remotely send commands to WeeChat)
+| irc/ | IRC (Internet Relay Chat) plugin
+| logger/ | Logger plugin (write messages displayed to files)
+| relay/ | Relay plugin (irc proxy + relay for remote interfaces)
+| script/ | Scripts manager
+| python/ | Python scripting API
+| perl/ | Perl scripting API
+| ruby/ | Ruby scripting API
+| lua/ | Lua scripting API
+| tcl/ | Tcl scripting API
+| guile/ | Guile (scheme) scripting API
+| trigger/ | Trigger plugin
+| xfer/ | Xfer plugin (IRC DCC file/chat)
+| doc/ | Documentation
+| po/ | Translations files (gettext)
+| test/ | Tools/files to test WeeChat (like Weercd, an IRC server)
+| debian/ | Debian packaging
+|===
+
+[[sources]]
+=== Sources
+
+[[sources_core]]
+==== Core
+
+WeeChat "core" is located in following directories:
+
+* 'src/core/': core functions (for data manipulation)
+* 'src/gui/': functions about interface (buffers, windows, ...)
+
+[width="100%",cols="1v,5",options="header"]
+|===
+| Path/file | Description
+| core/ | Core functions: entry point, internal structures
+| weechat.c | Entry point, command line options, main functions, startup
+| wee-backtrace.c | Display a backtrace after a crash
+| wee-command.c | WeeChat core commands
+| wee-completion.c | Default completions
+| wee-config-file.c | Configuration file management
+| wee-config.c | Configuration options for WeeChat core (file weechat.conf)
+| wee-debug.c | Some debug functions
+| wee-eval.c | Evaluation of expressions with references to internal vars
+| wee-hashtable.c | Hashtables
+| wee-hdata.c | Hdata (direct access to data using hashtables)
+| wee-hook.c | Hooks
+| wee-infolist.c | Infolists (lists with objects data)
+| wee-input.c | Input of commands/text
+| wee-list.c | Sorted lists
+| wee-log.c | Write to WeeChat log file (weechat.log)
+| wee-network.c | Network functions (connection to servers/proxies)
+| wee-proxy.c | Proxy management
+| wee-secure.c | Secured data options (file sec.conf)
+| wee-string.c | Functions on strings
+| wee-upgrade-file.c | Internal upgrade system
+| wee-upgrade.c | Upgrade for WeeChat core (buffers, lines, history, ...)
+| wee-url.c | URL transfer (using libcurl)
+| wee-utf8.c | UTF-8 functions
+| wee-util.c | Some other functions
+| wee-version.c | Functions for WeeChat version
+| gui/ | Functions for buffers, windows, ... (used by all interfaces)
+| gui-bar-item.c | Bar items
+| gui-bar-window.c | Bar windows
+| gui-bar.c | Bars
+| gui-buffer.c | Buffers
+| gui-chat.c | Chat functions (display message, ...)
+| gui-color.c | Color functions
+| gui-completion.c | Completion on command line
+| gui-cursor.c | Cursor mode (free movement of cursor)
+| gui-filter.c | Filters
+| gui-focus.c | Functions about focus (for cursor mode and mouse)
+| gui-history.c | Commands/text saved in buffers
+| gui-hotlist.c | Hotlist management (list of buffers with activity)
+| gui-input.c | Input functions (input bar)
+| gui-key.c | Keyboard functions
+| gui-layout.c | Layout
+| gui-line.c | Lines in buffers
+| gui-mouse.c | Mouse
+| gui-nicklist.c | Nicklist in buffers
+| gui-window.c | Windows
+| curses/ | Curses interface
+| gui-curses-bar-window.c | Display in bar windows
+| gui-curses-chat.c | Display in chat area (messages)
+| gui-curses-color.c | Color functions
+| gui-curses-key.c | Keyboard functions (default keys, read of input)
+| gui-curses-main.c | WeeChat main loop (waiting for keyboard/network events)
+| gui-curses-mouse.c | Mouse
+| gui-curses-term.c | Functions about terminal
+| gui-curses-window.c | Windows
+|===
+
+[[sources_plugins]]
+==== Plugins
+
+[width="100%",cols="1v,5",options="header"]
+|===
+| Path/file | Description
+| plugins/ | Root of plugins
+| plugin.c | Plugins management (load/unload dynamic C libraries)
+| plugin-api.c | Extra functions for plugin API (wrapper around WeeChat core functions)
+| plugin-config.c | Plugin configuration options (file plugins.conf)
+| plugin-script.c | Common functions used by script plugins
+| plugin-script-api.c | Script API functions: wrappers around some plugin API functions
+| plugin-script-callback.c | Callback management for scripts
+| weechat-plugin.h | Header designed to be distributed with WeeChat plugins, in order to compile them
+| alias/ | Alias plugin
+| alias.c | Main alias functions
+| alias-config.c | Alias config options (file alias.conf)
+| alias-info.c | Alias info/infolists/hdata
+| aspell/ | Aspell plugin
+| weechat-aspell.c | Main aspell functions
+| weechat-aspell-bar-item.c | Aspell bar items
+| weechat-aspell-command.c | Aspell commands
+| weechat-aspell-completion.c | Aspell completions
+| weechat-aspell-config.c | Aspell config options (file aspell.conf)
+| weechat-aspell-info.c | Aspell info/infolists/hdata
+| weechat-aspell-speller.c | Spellers management
+| charset/ | Charset plugin
+| charset.c | Charset functions
+| exec/ | Exec plugin
+| exec.c | Main exec functions
+| exec-buffer.c | Exec buffer
+| exec-command.c | Exec commands
+| exec-completion.c | Exec completions
+| exec-config.c | Exec config options (file exec.conf)
+| fifo/ | Fifo plugin
+| fifo.c | Main fifo functions
+| fifo-info.c | Fifo info/infolists/hdata
+| guile/ | Guile (scheme) plugin
+| weechat-guile.c | Main guile functions (load/unload scripts, execute guile code)
+| weechat-guile-api.c | Guile scripting API functions
+| irc/ | IRC (Internet Relay Chat) plugin
+| irc.c | Main IRC functions
+| irc-bar-item.c | IRC bar items
+| irc-buffer.c | IRC buffers
+| irc-channel.c | IRC channels
+| irc-color.c | IRC colors
+| irc-command.c | IRC commands
+| irc-completion.c | IRC completions
+| irc-config.c | IRC config options (file irc.conf)
+| irc-ctcp.c | IRC CTCP
+| irc-debug.c | IRC debug functions
+| irc-ignore.c | IRC Ignore
+| irc-info.c | IRC info/infolists/hdata
+| irc-input.c | Input of commands/text
+| irc-message.c | Functions to manipulate IRC messages
+| irc-mode.c | Functions about channel/nick modes
+| irc-msgbuffer.c | Target buffer for IRC messages
+| irc-nick.c | IRC nicks
+| irc-notify.c | IRC notify lists
+| irc-protocol.c | IRC protocol (RFCs 1459/2810/2811/2812/2813)
+| irc-raw.c | IRC raw buffer
+| irc-redirect.c | Redirection of IRC command output
+| irc-sasl.c | SASL authentication with IRC server
+| irc-server.c | I/O communication with IRC server
+| irc-upgrade.c | Save/restore of IRC data when upgrading WeeChat
+| logger/ | Logger plugin
+| logger.c | Main logger functions
+| logger-buffer.c | Logger buffer list management
+| logger-config.c | Logger config options (file logger.conf)
+| logger-info.c | Logger info/infolists/hdata
+| logger-tail.c | Functions to get last lines of a file
+| lua/ | Lua plugin
+| weechat-lua.c | Main lua functions (load/unload scripts, execute lua code)
+| weechat-lua-api.c | Lua scripting API functions
+| perl/ | Perl plugin
+| weechat-perl.c | Main perl functions (load/unload scripts, execute perl code)
+| weechat-perl-api.c | Perl scripting API functions
+| python/ | Python plugin
+| weechat-python.c | Main python functions (load/unload scripts, execute python code)
+| weechat-python-api.c | Python scripting API functions
+| relay/ | Relay plugin (IRC proxy and relay for remote interfaces)
+| relay.c | Main relay functions
+| relay-buffer.c | Relay buffer
+| relay-client.c | Clients of relay
+| relay-command.c | Relay commands
+| relay-completion.c | Relay completions
+| relay-config.c | Relay config options (file relay.conf)
+| relay-info.c | Relay info/infolists/hdata
+| relay-network.c | Network functions for relay
+| relay-raw.c | Relay raw buffer
+| relay-server.c | Relay server
+| relay-upgrade.c | Save/restore of relay data when upgrading WeeChat
+| relay-websocket.c | WebSocket server functions (RFC 6455)
+| irc/ | IRC proxy
+| relay-irc.c | Main IRC proxy functions
+| weechat/ | Relay for remote interfaces
+| relay-weechat.c | Relay for remote interfaces (main functions)
+| relay-weechat-msg.c | Send binary messages to clients
+| relay-weechat-nicklist.c | Nicklist functions
+| relay-weechat-protocol.c | Read commands from clients
+| ruby/ | Ruby plugin
+| weechat-ruby.c | Main ruby functions (load/unload scripts, execute ruby code)
+| weechat-ruby-api.c | Ruby scripting API functions
+| script/ | Scripts manager
+| script.c | Main functions for scripts manager
+| script-action.c | Actions on scripts (load/unload, install/remove, ...)
+| script-buffer.c | Buffer for scripts manager
+| script-command.c | Commands for scripts manager
+| script-completion.c | Completions for scripts manager
+| script-config.c | Config options for scripts manager (file script.conf)
+| script-info.c | Script manager info/infolists/hdata
+| script-repo.c | Download and read repository file
+| tcl/ | Tcl plugin
+| weechat-tcl.c | Main tcl functions (load/unload scripts, execute tcl code)
+| weechat-tcl-api.c | Tcl scripting API functions
+| trigger/ | Trigger plugin
+| trigger.c | Main trigger functions
+| trigger-buffer.c | Trigger buffer
+| trigger-callback.c | Trigger callbacks
+| trigger-command.c | Trigger commands
+| trigger-completion.c | Trigger completions
+| trigger-config.c | Trigger config options (file trigger.conf)
+| xfer/ | Xfer plugin (IRC DCC file/chat)
+| xfer.c | Main xfer functions
+| xfer-buffer.c | Xfer buffer
+| xfer-chat.c | DCC chat
+| xfer-command.c | Xfer commands
+| xfer-completion.c | Xfer completions
+| xfer-config.c | Xfer config options (file xfer.conf)
+| xfer-dcc.c | DCC file transfer
+| xfer-file.c | File functions for xfer
+| xfer-info.c | Xfer info/infolists/hdata
+| xfer-network.c | Network functions for xfer
+| xfer-upgrade.c | Save/restore of xfer data when upgrading WeeChat
+|===
+
+[[documentation_translations]]
+=== Documentation / translations
+
+Documentation files:
+
+[width="100%",cols="1v,5",options="header"]
+|===
+| Path/file | Description
+| doc/ | Documentation
+| asciidoc.conf | Asciidoc configuration file (some macros)
+| asciidoc.css | Asciidoc style
+| docgen.py | Python script to build files in 'autogen/' directory (see below)
+| XX/ | Documentation for language XX (languages: en, fr, de, it, ...)
+| weechat.1.XX.asciidoc | Man page (`man weechat`)
+| weechat_quickstart.XX.asciidoc | Quickstart guide
+| weechat_user.XX.asciidoc | User's guide
+| weechat_faq.XX.asciidoc | FAQ
+| weechat_plugin_api.XX.asciidoc | Plugin API reference
+| weechat_scripting.XX.asciidoc | Scripting guide
+| weechat_tester.XX.asciidoc | Tester's guide
+| weechat_dev.XX.asciidoc | Developer's guide (this document)
+| weechat_relay_protocol.XX.asciidoc | Relay protocol (for remote interfaces)
+| cmdline_options.XX.asciidoc | Command-line options (file included in man page and user's guide)
+| autogen/ | Files auto-built with script docgen.py
+| user/ | Files auto-built for user's guide (do *NEVER* update manually!)
+| plugin_api/ | Files auto-built for plugin API (do *NEVER* update manually!)
+|===
+
+Translations for WeeChat and plugins are done with gettext, files are in 'po/'
+directory:
+
+[width="100%",cols="1v,5",options="header"]
+|===
+| Path/file | Description
+| po/ | Translation files (gettext)
+| XX.po | Translations for language XX (fr, de, it, ...), base language is English
+| weechat.pot | Template for translations (auto-built)
+|===
+
+[[coding_rules]]
+== Coding rules
+
+[[coding_general_rules]]
+=== General rules
+
+* In source code, your comments, variable names, .. must be written in English
+ *only* (no other language is allowed).
+* Use a copyright header in each new source file with:
+** short description of file (one line),
+** date,
+** name,
+** e-mail,
+** license.
+
+Example in C:
+
+[source,C]
+----
+/*
+ * weechat.c - core functions for WeeChat
+ *
+ * Copyright (C) 2014 Your Name <your@email.com>
+ *
+ * This file is part of WeeChat, the extensible chat client.
+ *
+ * WeeChat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * WeeChat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
+ */
+----
+
+[[coding_c_style]]
+=== C style
+
+Some basic rules you *must* follow when you write C code:
+
+* Use 4 spaces for indentation. Don't use tabs, they are evil.
+* Try to not exceed 80 chars by line, except if this is needed to increase
+ readability.
+* Use comments `/* comment */` (not C99-style comments like `// comment`).
+* Add a comment before any function, to explain what it does (always use a
+ multi-line comment, even if description is very short).
+
+Example:
+
+[source,C]
+----
+/*
+ * Checks if a string with boolean value is valid.
+ *
+ * Returns:
+ * 1: boolean value is valid
+ * 0: boolean value is NOT valid
+ */
+
+int
+foo ()
+{
+ int i;
+
+ /* one line comment */
+ i = 1;
+
+ /*
+ * multi-line comment: this is a very long description about next block
+ * of code
+ */
+ i = 2;
+ printf ("%d\n", i);
+}
+----
+
+* Use explicit variable names, for example "nicks_count" instead of "n" or "nc".
+ Exception: in `for` loops, where variables like "i" or "n" are OK.
+* Initialize local variables after declaration, in body of function, example:
+
+[source,C]
+----
+void
+foo ()
+{
+ int nick_count, buffer_count;
+
+ nick_count = 0;
+ buffer_count = 1;
+ /* ... */
+}
+----
+
+* Use parentheses to explicitly show how expression is evaluated, even if
+ they are not required, for example: write `x + (y * z)` instead of `x + y * z`.
+* Place curly brackets `{ }` alone on lines, and indent them with number of
+ spaces used for line above opening curly bracket (the `if` in example):
+
+[source,C]
+----
+if (nicks_count == 1)
+{
+ /* something */
+}
+----
+
+* Use empty lines to separate many different blocks inside functions, and if
+ possible add a comment for each one, like this:
+
+[source,C]
+----
+/*
+ * Sends a message from out queue.
+ */
+
+void
+irc_server_outqueue_send (struct t_irc_server *server)
+{
+ /* ... */
+
+ /* send signal with command that will be sent to server */
+ irc_server_send_signal (server, "irc_out",
+ server->outqueue[priority]->command,
+ server->outqueue[priority]->message_after_mod,
+ NULL);
+ tags_to_send = irc_server_get_tags_to_send (server->outqueue[priority]->tags);
+ irc_server_send_signal (server, "irc_outtags",
+ server->outqueue[priority]->command,
+ server->outqueue[priority]->message_after_mod,
+ (tags_to_send) ? tags_to_send : "");
+ if (tags_to_send)
+ free (tags_to_send);
+
+ /* send command */
+ irc_server_send (server, server->outqueue[priority]->message_after_mod,
+ strlen (server->outqueue[priority]->message_after_mod));
+ server->last_user_message = time_now;
+
+ /* start redirection if redirect is set */
+ if (server->outqueue[priority]->redirect)
+ {
+ irc_redirect_init_command (server->outqueue[priority]->redirect,
+ server->outqueue[priority]->message_after_mod);
+ }
+
+ /* ... */
+}
+----
+
+* Indent the `if` conditions, and use parentheses around conditions with an
+ operator (not needed for single boolean), like this:
+
+[source,C]
+----
+if (something)
+{
+ /* something */
+}
+else
+{
+ /* something else */
+}
+
+if (my_boolean1 && my_boolean2 && (i == 10)
+ && ((buffer1 != buffer2) || (window1 != window2)))
+{
+ /* something */
+}
+else
+{
+ /* something else */
+}
+----
+
+* Indent the `switch` statements like this:
+
+[source,C]
+----
+switch (string[0])
+{
+ case 'A': /* first case */
+ foo ("abc", "def");
+ break;
+ case 'B': /* second case */
+ bar (1, 2, 3);
+ break;
+ default: /* other cases */
+ baz ();
+ break;
+}
+----
+
+* Use `typedef` for function prototypes but not for structures:
+
+[source,C]
+----
+typedef int (t_hook_callback_fd)(void *data, int fd);
+
+struct t_hook_fd
+{
+ t_hook_callback_fd *callback; /* fd callback */
+ int fd; /* socket or file descriptor */
+ int flags; /* fd flags (read,write,..) */
+ int error; /* contains errno if error occurred */
+ /* with fd */
+};
+
+/* ... */
+
+struct t_hook_fd *new_hook_fd;
+
+new_hook_fd = malloc (sizeof (*new_hook_fd));
+----
+
+* This Lisp code can be used in your '~/.emacs.el' to indent properly if you are
+ using Emacs as text editor:
+
+[source,lisp]
+----
+(add-hook 'c-mode-common-hook '(lambda ()
+ (c-toggle-hungry-state t)
+ (c-set-style "k&r")
+ (setq c-basic-offset 4
+ c-tab-always-indent t)
+ (c-set-offset 'case-label '+)))
+----
+
+[[coding_python_style]]
+=== Python style
+
+See http://www.python.org/dev/peps/pep-0008/
+
+[[core_internals]]
+== Core internals
+
+[[naming_convention]]
+=== Naming convention
+
+[[naming_convention_files]]
+==== Files
+
+File names are composed by letters and hyphens, with format: 'xxx-yyyyy.[ch]',
+where 'xxx' is directory/component (can be abbreviation) and 'yyyyy' a name for
+the file.
+
+The main file of a directory may have same name as directory, for example
+'irc.c' in irc plugin.
+
+Examples:
+
+[width="100%",cols="1l,5",options="header"]
+|===
+| Directory | Files
+| src/core/ | weechat.c, wee-backtrace.c, wee-command.c, ...
+| src/gui/ | gui-bar.c, gui-bar-item.c, gui-bar-window.c, ...
+| src/gui/curses/ | gui-curses-bar.c, gui-curses-bar-window.c, gui-curses-chat.c, ...
+| src/plugins/ | plugin.c, plugin-api.c, plugin-config.c, plugin-script.c, ...
+| src/plugins/irc/ | irc.c, irc-bar-item.c, irc-buffer.c, ...
+| src/plugins/python/ | weechat-python.c, weechat-python-api.c, ...
+|===
+
+The headers of C files have same name as file, for example 'wee-command.h' for
+file 'wee-command.c'.
+
+[[naming_convention_structures]]
+==== Structures
+
+Structures have name 't_X_Y' or 't_X_Y_Z':
+
+* 'X': directory/component (can be abbreviation)
+* 'Y': end of file name
+* 'Z': name for structure (optional)
+
+Example: an IRC nick (from 'src/plugins/irc/irc-nick.h'):
+
+[source,C]
+----
+struct t_irc_nick
+{
+ char *name; /* nickname */
+ char *host; /* full hostname */
+ char *prefixes; /* string with prefixes enabled for nick */
+ char prefix[2]; /* current prefix (higher prefix set in */
+ /* prefixes) */
+ int away; /* 1 if nick is away */
+ char *color; /* color for nickname in chat window */
+ struct t_irc_nick *prev_nick; /* link to previous nick on channel */
+ struct t_irc_nick *next_nick; /* link to next nick on channel */
+};
+----
+
+[[naming_convention_variables]]
+==== Variables
+
+Global variables (outside functions) have name 'X_Y_Z':
+
+* 'X': directory/component (can be abbreviation)
+* 'Y': end of file name
+* 'Z': name for variable
+
+Exception are variables for "last" node of a list, name is 'last_X' (where
+'X' is name of variable, using singular form).
+
+Example: windows (from 'src/gui/gui-window.c'):
+
+[source,C]
+----
+struct t_gui_window *gui_windows = NULL; /* first window */
+struct t_gui_window *last_gui_window = NULL; /* last window */
+struct t_gui_window *gui_current_window = NULL; /* current window */
+----
+
+There is no naming convention for local variables (in functions). The only
+recommendation is that name is explicit (not too short). +
+Nevertheless, pointers to structures are often named 'ptr_xxxx', for example a
+pointer on a 'struct t_gui_buffer *' will be: '*ptr_buffer'.
+
+[[naming_convention_functions]]
+==== Functions
+
+Naming convention for functions is the same as
+<<naming_convention_variables,variables>>.
+
+Example: creation of a new window (from 'src/gui/gui-window.c'):
+
+[source,C]
+----
+/*
+ * Creates a new window.
+ *
+ * Returns pointer to new window, NULL if error.
+ */
+
+struct t_gui_window *
+gui_window_new (struct t_gui_window *parent_window, struct t_gui_buffer *buffer,
+ int x, int y, int width, int height,
+ int width_pct, int height_pct)
+{
+ /* ... */
+
+ return new_window;
+}
+----
+
+[[single_thread]]
+=== Single thread
+
+WeeChat is single threaded. That means every part of code should execute very
+fast, and that calls to functions like `sleep` are *strictly forbidden* (it is
+true for WeeChat core, but also C plugins and scripts).
+
+If for some reasons you have to sleep a while, use `hook_timer` with a callback.
+
+[[doubly_linked_lists]]
+=== Doubly linked lists
+
+Most of WeeChat linked lists are doubly linked lists: each node has pointer to
+previous and next node.
+
+Example: list of buffers (from 'src/gui/gui-buffer.h'):
+
+[source,C]
+----
+struct t_gui_buffer
+{
+ /* data */
+
+ /* ... */
+
+ struct t_gui_buffer *prev_buffer; /* link to previous buffer */
+ struct t_gui_buffer *next_buffer; /* link to next buffer */
+};
+----
+
+Then the two list pointers, to the head and tail of list:
+
+[source,C]
+----
+struct t_gui_buffer *gui_buffers = NULL; /* first buffer */
+struct t_gui_buffer *last_gui_buffer = NULL; /* last buffer */
+----
+
+[[color_codes_in_strings]]
+=== Color codes in strings
+
+WeeChat uses own color codes in strings to display attributes (bold,
+underline, ...) and colors on screen.
+
+All attributes/colors are prefixed with a char in string, which can be:
+
+* '0x19': color code (followed by color code(s))
+* '0x1A': set attribute (followed by attribute on one char)
+* '0x1B': remove attribute (followed by attribute on one char)
+* '0x1C': reset (nothing after)
+
+Allowed attributes are (one or more chars):
+
+* `*`: bold
+* `!`: reverse
+* `/`: italic
+* `_`: underline
+* `|`: keep attributes
+
+Possible colors are:
+
+* standard color: optional attributes + number on 2 digits
+* extended color: `@` + optional attributes + number on 5 digits
+
+In following table, these conventions are used:
+
+* `STD`: standard color (2 digits)
+* `(A)STD`: standard color with optional attributes (attributes + 2 digits)
+* `EXT`: extended color (`@` + 5 digits)
+* `(A)EXT`: extended color with optional attributes (`@` + attributes + 5 digits)
+* `ATTR`: one attribute char (`*`, `!`, `/`, `_` or `|`)
+
+All combinations are summarized in this table:
+
+[width="100%",cols="4,2,2,8",options="header"]
+|===
+| Code | Example | Areas | Description
+| hex[19] + STD | hex[19]`01` | chat + bars | Set attributes and color using option, see table below
+| hex[19] + EXT | hex[19]`@00001` | chat | Set color with a ncurses pair (used only on `/color` buffer)
+| hex[19] + "F" + (A)STD | hex[19]`F*05` | chat + bars | Set foreground (WeeChat color)
+| hex[19] + "F" + (A)EXT | hex[19]`F@00214` | chat + bars | Set foreground (extended color)
+| hex[19] + "B" + STD | hex[19]`B05` | chat + bars | Set background (WeeChat color)
+| hex[19] + "B" + EXT | hex[19]`B@00124` | chat + bars | Set background (extended color)
+| hex[19] + "*" + (A)STD | hex[19]`*05` | chat + bars | Set foreground (WeeChat color)
+| hex[19] + "*" + (A)EXT | hex[19]`*@00214` | chat + bars | Set foreground (extended color)
+| hex[19] + "*" + (A)STD + "," + STD | hex[19]`*08,05` | chat + bars | Set foreground/background (WeeChat colors)
+| hex[19] + "*" + (A)STD + "," + EXT | hex[19]`*01,@00214` | chat + bars | Set foreground (WeeChat color) and background (extended color)
+| hex[19] + "*" + (A)EXT + "," + STD | hex[19]`*@00214,05` | chat + bars | Set foreground (extended color) and background (WeeChat color)
+| hex[19] + "*" + (A)EXT + "," + EXT | hex[19]`*@00214,@00017` | chat + bars | Set foreground/background (extended colors)
+| hex[19] + "b" + "F" | hex[19]`bF` | bars | Set bar foreground color
+| hex[19] + "b" + "D" | hex[19]`bD` | bars | Set bar delimiter color
+| hex[19] + "b" + "B" | hex[19]`bB` | bars | Set bar background color
+| hex[19] + "b" + "_" | hex[19]`b_` | input bar | Start input char (used only in item "input_text")
+| hex[19] + "b" + "-" | hex[19]`b-` | input bar | Start input hidden char (used only in item "input_text")
+| hex[19] + "b" + "#" | hex[19]`b#` | input bar | Move cursor char (used only in item "input_text")
+| hex[19] + "b" + "i" | hex[19]`bi` | bars | Start item
+| hex[19] + "b" + "l" (lower L) | hex[19]`bl` | bars | Start line item
+| hex[19] + "E" | hex[19]`E` | chat + bars | Emphasize text _(WeeChat ≥ 0.4.2)_
+| hex[19] + hex[1C] | hex[19]hex[1C] | chat + bars | Reset color (keep attributes)
+| hex[1A] + ATTR | hex[1A]`*` | chat + bars | Set attribute
+| hex[1B] + ATTR | hex[1B]`*` | chat + bars | Remove attribute
+| hex[1C] | hex[1C] | chat + bars | Reset attributes and color
+|===
+
+Color codes using options (see 't_gui_color_enum', in file
+'src/gui/gui-color.h'):
+
+[width="70%",cols="^1m,10",options="header"]
+|===
+| Code | Option
+| 00 | weechat.color.separator
+| 01 | weechat.color.chat
+| 02 | weechat.color.chat_time
+| 03 | weechat.color.chat_time_delimiters
+| 04 | weechat.color.chat_prefix_error
+| 05 | weechat.color.chat_prefix_network
+| 06 | weechat.color.chat_prefix_action
+| 07 | weechat.color.chat_prefix_join
+| 08 | weechat.color.chat_prefix_quit
+| 09 | weechat.color.chat_prefix_more
+| 10 | weechat.color.chat_prefix_suffix
+| 11 | weechat.color.chat_buffer
+| 12 | weechat.color.chat_server
+| 13 | weechat.color.chat_channel
+| 14 | weechat.color.chat_nick
+| 15 | weechat.color.chat_nick_self
+| 16 | weechat.color.chat_nick_other
+| 17 | _(not used any more since WeeChat 0.3.4)_
+| 18 | _(not used any more since WeeChat 0.3.4)_
+| 19 | _(not used any more since WeeChat 0.3.4)_
+| 20 | _(not used any more since WeeChat 0.3.4)_
+| 21 | _(not used any more since WeeChat 0.3.4)_
+| 22 | _(not used any more since WeeChat 0.3.4)_
+| 23 | _(not used any more since WeeChat 0.3.4)_
+| 24 | _(not used any more since WeeChat 0.3.4)_
+| 25 | _(not used any more since WeeChat 0.3.4)_
+| 26 | _(not used any more since WeeChat 0.3.4)_
+| 27 | weechat.color.chat_host
+| 28 | weechat.color.chat_delimiters
+| 29 | weechat.color.chat_highlight
+| 30 | weechat.color.chat_read_marker
+| 31 | weechat.color.chat_text_found
+| 32 | weechat.color.chat_value
+| 33 | weechat.color.chat_prefix_buffer
+| 34 | weechat.color.chat_tags _(WeeChat ≥ 0.3.6)_
+| 35 | weechat.color.chat_inactive_window _(WeeChat ≥ 0.3.6)_
+| 36 | weechat.color.chat_inactive_buffer _(WeeChat ≥ 0.3.6)_
+| 37 | weechat.color.chat_prefix_buffer_inactive_buffer _(WeeChat ≥ 0.3.6)_
+| 38 | weechat.color.chat_nick_offline _(WeeChat ≥ 0.3.9)_
+| 39 | weechat.color.chat_nick_offline_highlight _(WeeChat ≥ 0.3.9)_
+| 40 | weechat.color.chat_nick_prefix _(WeeChat ≥ 0.4.1)_
+| 41 | weechat.color.chat_nick_suffix _(WeeChat ≥ 0.4.1)_
+| 42 | weechat.color.emphasis _(WeeChat ≥ 0.4.2)_
+| 43 | weechat.color.chat_day_change _(WeeChat ≥ 0.4.2)_
+|===
+
+WeeChat colors are:
+
+[width="70%",cols="^1m,6",options="header"]
+|===
+| Code | Color
+| 00 | Default (terminal foreground/background)
+| 01 | Black
+| 02 | Dark gray
+| 03 | Dark red
+| 04 | Light red
+| 05 | Dark green
+| 06 | Light green
+| 07 | Brown
+| 08 | Yellow
+| 09 | Dark blue
+| 10 | Light blue
+| 11 | Dark magenta
+| 12 | Light magenta
+| 13 | Dark cyan
+| 14 | Light cyan
+| 15 | Gray
+| 16 | White
+|===
+
+Examples of color codes:
+
+[width="70%",cols="1,2",options="header"]
+|===
+| Code | Description
+| hex[19]`01` | Color of option "01" (chat text)
+| hex[19]`*08,03` | Yellow on red
+| hex[19]`*@00214` | Orange (extended color 214)
+| hex[19]`*@*_00214,@00017` | Bold underlined orange (214) on dark blue (17)
+| hex[1A]`_` | Set underline
+| hex[1B]`_` | Remove underline
+| hex[1C] | Reset attributes and color
+|===
+
+[[plugin_internals]]
+== Plugin internals
+
+The file 'src/plugins/weechat-plugin.h' defines and exports all functions
+available in the API.
+
+A structure called 't_weechat_plugin' is used to store info about plugin
+(filename, name, author, description, ...) and all API functions, as pointers
+to WeeChat functions.
+
+Then some macros are defined to call these functions.
+
+For example, function 'hook_timer' is defined in structure 't_weechat_plugin'
+like this:
+
+[source,C]
+----
+struct t_hook *(*hook_timer) (struct t_weechat_plugin *plugin,
+ long interval,
+ int align_second,
+ int max_calls,
+ int (*callback)(void *data,
+ int remaining_calls),
+ void *callback_data);
+----
+
+And the macro used to call this function is:
+
+[source,C]
+----
+#define weechat_hook_timer(__interval, __align_second, __max_calls, \
+ __callback, __data) \
+ weechat_plugin->hook_timer(weechat_plugin, __interval, \
+ __align_second, __max_calls, \
+ __callback, __data)
+----
+
+So in a plugin, the call to function will be for example:
+
+[source,C]
+----
+server->hook_timer_sasl = weechat_hook_timer (timeout * 1000,
+ 0, 1,
+ &irc_server_timer_sasl_cb,
+ server);
+----
+
+[[contribute]]
+== Contribute to WeeChat
+
+[[git_repository]]
+=== Git repository
+
+Git repository is at this URL: https://github.com/weechat/weechat
+
+Any patch for bug or new feature must be done on master branch, preferred way is
+a Github pull request. A patch can also be sent by e-mail (made with `git diff`
+or `git format-patch`).
+
+Format of commit message is the following (to close a GitHub issue):
+
+----
+component: fix a problem (closes #123)
+----
+
+For a Savannah bug:
+
+----
+component: fix a problem (bug #12345)
+----
+
+Where 'component' is one of following:
+
+* WeeChat core: 'core' (files in root directory, 'po/' and 'src/',
+ except 'src/plugins/')
+* documentation files: 'doc' (files in directory 'doc/')
+* name of a plugin: 'irc', 'python', 'relay', ... (files in directory
+ 'src/plugins/')
+
+Some rules to follow:
+
+* use only English
+* use infinitive form of verb
+* if commit is related to something in tracker, write it in parenthesis after
+ the message, with this format:
+** GitHub: closes #123
+** Savannah: bug #12345, task #12345, patch #12345
+
+Examples of commit messages:
+
+----
+irc: add command /unquiet (closes #36)
+core: add callback "nickcmp" for nick comparison in buffers
+irc: fix freeze when reading on socket with SSL enabled (bug #35097)
+ruby: add detection of ruby version 1.9.3 in cmake
+python: fix crash when unloading a script without pointer to interpreter
+core: update Japanese translations (patch #7783)
+----
+
+[[translations]]
+=== Translations
+
+[[gettext]]
+==== Gettext
+
+Gettext files are in directory 'po/'.
+
+If you want to initialize a new language, use command `msginit`. For example to
+create a file which is ready to translate to Dutch:
+
+----
+$ cd po
+$ msginit -i weechat.pot -l nl_NL -o nl.po
+----
+
+Base language for WeeChat is English, so you must of course perfectly understand
+English in order to translate to your language.
+
+When done, you *have* to check your file with script 'msgcheck.py'
+(https://github.com/flashcode/msgcheck):
+
+----
+$ msgcheck.py xx.po
+----
+
+[[build_autogen_files]]
+===== Build auto-generated files
+
+Files in directory 'doc/XX/autogen/' are auto-generated by script 'doc/docgen.py'.
+
+Copy this python script to your python directory (for example '~/.weechat/python').
+Then you can load this script in your WeeChat, and setup path to your '/doc' directory:
+
+----
+/python load docgen.py
+/set plugins.var.python.docgen.path "~/src/weechat/doc"
+----
+
+Then create this alias to build files:
+
+----
+/alias doc /perl unload; /python unload; /ruby unload; /lua unload; /tcl unload; /guile unload; /python load docgen.py; /wait 1ms /docgen
+----
+
+And use command `/doc` to build all files, for all languages.
+
+[IMPORTANT]
+When using command `/doc`, be sure all C plugins (irc, charset, ...) are loaded,
+because files are built using data currently in memory.
+
+[[asciidoc]]
+==== Asciidoc
+
+Asciidoc files are in directory 'doc/XX/' where 'XX' is language (en, fr, de,
+it, ...).
+
+First make a copy of an English asciidoc file (in directory 'doc/en/'), then
+work on it.
+
+The translations missing in files are indicated by this string:
+
+----
+// TRANSLATION MISSING
+----
+
+You must translate whole file except links and special keywords for notes,
+warnings, ... These words must be kept unchanged:
+
+----
+[[link_name]]
+<<link_name>>
+
+[NOTE]
+[TIP]
+[IMPORTANT]
+[WARNING]
+[CAUTION]
+----
+
+When there is a name after `<<link_name>>`, then you must translate it:
+
+----
+<<link_name,this text must be translated>>
+----