1069 lines
41 KiB
Plaintext
1069 lines
41 KiB
Plaintext
WeeChat Developer's Guide
|
|
=========================
|
|
Sébastien Helleu <flashcode@flashtux.org>
|
|
|
|
|
|
This manual documents WeeChat chat client, it is part of WeeChat.
|
|
|
|
Latest version of this document can be found on this page:
|
|
http://www.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: http://git.savannah.gnu.org/gitweb/?p=weechat.git
|
|
* scripts: the 'official' scripts submitted on weechat.org,
|
|
URL is: http://git.savannah.gnu.org/gitweb/?p=weechat/scripts.git;a=summary
|
|
|
|
This manual documents only core repository.
|
|
|
|
[[overview]]
|
|
Overview
|
|
~~~~~~~~
|
|
|
|
The main WeeChat directories are:
|
|
|
|
[width="100%",cols="1l,5",options="header"]
|
|
|========================================
|
|
| Directory | Description
|
|
| debian/ | Debian packaging
|
|
| src/ | Root of sources
|
|
| core/ | Core functions: entry point, internal structures
|
|
| gui/ | Functions for buffers, windows, ... (used by all interfaces)
|
|
| curses/ | Curses interface
|
|
| gtk/ | Gtk interface (not working)
|
|
| plugins/ | Plugin API
|
|
| alias/ | Alias plugin
|
|
| aspell/ | Aspell plugin
|
|
| charset/ | Charset plugin
|
|
| demo/ | Demo plugin
|
|
| fifo/ | Fifo plugin (FIFO pipe used to remotely send commands to WeeChat)
|
|
| irc/ | IRC plugin
|
|
| logger/ | Logger plugin (write messages displayed to files)
|
|
| relay/ | Relay plugin (irc proxy + relay for remote interfaces)
|
|
| rmodifier/ | Rmodifier plugin (alter modifier strings with regular expressions)
|
|
| 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
|
|
| xfer/ | Xfer (IRC DCC file/chat)
|
|
| doc/ | Documentation
|
|
| po/ | Translations files (gettext)
|
|
| test/ | Weercd: WeeChat flood irc server, written in Python
|
|
|========================================
|
|
|
|
[[sources]]
|
|
Sources
|
|
~~~~~~~
|
|
|
|
[[sources_core]]
|
|
Core
|
|
^^^^
|
|
|
|
WeeChat "core" reside in following directories:
|
|
|
|
* 'src/core/': core functions (for data manipulation)
|
|
* 'src/gui/': functions about interface (buffers, windows, ...)
|
|
|
|
[width="100%",cols="1l,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 backtrace after a segfault
|
|
| wee-command.c | WeeChat core commands
|
|
| wee-completion.c | Completion on command line
|
|
| wee-config-file.c | Configuration file management
|
|
| wee-config.c | Configuration options for WeeChat core (options weechat.*)
|
|
| wee-debug.c | Some debug functions
|
|
| wee-hashtable.c | Hashtables
|
|
| wee-hdata.c | Hdata (direct access to data using hashtables)
|
|
| wee-hook.c | Hooks
|
|
| wee-infolist.c | Infolists (lists built with data about objects)
|
|
| 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, proxy)
|
|
| wee-proxy.c | Proxy management
|
|
| 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
|
|
| 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 | Default completions
|
|
| 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
|
|
| gtk/ | Gtk interface (not working)
|
|
| gui-gtk-bar-window.c | Display in bar windows
|
|
| gui-gtk-chat.c | Display in chat area (messages)
|
|
| gui-gtk-color.c | Color functions
|
|
| gui-gtk-key.c | Keyboard functions
|
|
| gui-gtk-main.c | WeeChat main loop (waiting for keyboard/network events)
|
|
| gui-gtk-mouse.c | Mouse
|
|
| gui-gtk-term.c | Functions about terminal
|
|
| gui-gtk-window.c | Windows
|
|
|========================================
|
|
|
|
[[sources_plugins]]
|
|
Plugins
|
|
^^^^^^^
|
|
|
|
[width="100%",cols="1l,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
|
|
| alias-info.c | Info and infolists from alias plugin
|
|
| aspell/ | Aspell plugin
|
|
| weechat-aspell.c | Main aspell functions
|
|
| weechat-aspell-config.c | Aspell config options
|
|
| weechat-aspell-speller.c | Spellers management
|
|
| charset/ | Charset plugin
|
|
| charset.c | Charset functions
|
|
| demo/ | Demo plugin
|
|
| demo.c | Demo functions
|
|
| fifo/ | Fifo plugin
|
|
| fifo.c | Main fifo functions
|
|
| fifo-info.c | Info and infolists from fifo plugin
|
|
| 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 | Color functions
|
|
| irc-command.c | IRC commands
|
|
| irc-completion.c | IRC completions
|
|
| irc-config.c | IRC config options
|
|
| irc-ctcp.c | IRC CTCP
|
|
| irc-debug.c | IRC debug functions
|
|
| irc-display.c | IRC display functions
|
|
| irc-ignore.c | IRC Ignore
|
|
| irc-info.c | Info and infolists from IRC plugin
|
|
| 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
|
|
| 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 servers
|
|
| irc-upgrade.c | Save/restore 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
|
|
| logger-info.c | Info and infolists from logger plugin
|
|
| logger-tail.c | Return 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
|
|
| relay-info.c | Info and infolists from relay plugin
|
|
| relay-network.c | Network functions for relay
|
|
| relay-raw.c | Relay raw buffer
|
|
| relay-server.c | Relay server
|
|
| relay-upgrade.c | Save/restore relay data when upgrading WeeChat
|
|
| irc/ | IRC proxy
|
|
| relay-irc.c | Main IRC proxy functions
|
|
| weechat/ | Relay for remote interface
|
|
| relay-weechat.c | Relay for remote interface (main functions)
|
|
| relay-weechat-msg.c | Send binary messages to clients
|
|
| relay-weechat-protocol.c | Read commands from clients
|
|
| rmodifier/ | Rmodifier plugin
|
|
| rmodifier.c | Main rmodifier functions
|
|
| rmodifier-command.c | Rmodifier commands
|
|
| rmodifier-completion.c | Rmodifier completions
|
|
| rmodifier-config.c | Rmodifier config options
|
|
| rmodifier-debug.c | Rmodifier debug functions
|
|
| rmodifier-info.c | Info and infolists from rmodifier plugin
|
|
| ruby/ | Ruby plugin
|
|
| weechat-ruby.c | Main ruby functions (load/unload scripts, execute ruby code)
|
|
| weechat-ruby-api.c | Ruby scripting API functions
|
|
| tcl/ | Tcl plugin
|
|
| weechat-tcl.c | Main tcl functions (load/unload scripts, execute tcl code)
|
|
| weechat-tcl-api.c | Tcl scripting API functions
|
|
| xfer/ | Xfer plugin (IRC DCC file/chat)
|
|
| xfer.c | Main xfer functions
|
|
| xfer-buffer.c | Xfer buffer
|
|
| xfer-chat.c | Xfer DCC chat
|
|
| xfer-command.c | Xfer commands
|
|
| xfer-completion.c | Xfer completions
|
|
| xfer-config.c | Xfer config options
|
|
| xfer-dcc.c | Xfer DCC file
|
|
| xfer-file.c | File functions for xfer
|
|
| xfer-info.c | Info and infolists from xfer plugin
|
|
| xfer-network.c | Network functions for xfer
|
|
| xfer-upgrade.c | Save/restore xfer data when upgrading WeeChat
|
|
|========================================
|
|
|
|
[[documentation_translations]]
|
|
Documentation / translations
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Documentation files:
|
|
|
|
[width="100%",cols="1l,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)
|
|
| weechat-curses.1 | Weechat man page
|
|
| XX/ | Documentation for language XX (languages: en, fr, de, it, ...)
|
|
| weechat_quickstart.XX.txt | Quickstart guide
|
|
| weechat_user.XX.txt | User's guide
|
|
| weechat_faq.XX.txt | FAQ
|
|
| weechat_plugin_api.XX.txt | Plugin API reference
|
|
| weechat_scripting.XX.txt | Scripting guide
|
|
| weechat_tester.XX.txt | Tester's guide
|
|
| weechat_dev.XX.txt | Developer's guide (this document)
|
|
| weechat_relay_protocol.en.txt | Relay protocol
|
|
| autogen/ | Files auto-built with script docgen.py (do *NEVER* update manually!)
|
|
| user/ | Files auto-built for user's guide
|
|
| plugin_api/ | Files auto-built for plugin API
|
|
|========================================
|
|
|
|
Translations for WeeChat and plugins are done with gettext, files are in 'po/' directory:
|
|
|
|
[width="100%",cols="1l,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 date, name, e-mail,
|
|
license and below that a short description of file. Example in C:
|
|
|
|
[source,C]
|
|
----------------------------------------
|
|
/*
|
|
* Copyright (C) 2012 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/>.
|
|
*/
|
|
|
|
/*
|
|
* weechat.c: core functions for WeeChat
|
|
*/
|
|
----------------------------------------
|
|
|
|
[[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`), and
|
|
format them like this:
|
|
|
|
[source,C]
|
|
----------------------------------------
|
|
/*
|
|
* foo: this is the description of the function
|
|
*/
|
|
|
|
void
|
|
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 explicitely 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 */
|
|
}
|
|
----------------------------------------
|
|
|
|
* Add a comment before any function, to explain what does the function, and
|
|
indent it like this (note that return type of function is on a line alone):
|
|
|
|
[source,C]
|
|
----------------------------------------
|
|
/*
|
|
* foo: this is the description of the function
|
|
*/
|
|
|
|
void
|
|
foo ()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 10; i++)
|
|
{
|
|
bar (i);
|
|
}
|
|
}
|
|
----------------------------------------
|
|
|
|
* Use empty lines to separate many different blocks inside functions, and if
|
|
possible add a comment for each one, like this:
|
|
|
|
[source,C]
|
|
----------------------------------------
|
|
/*
|
|
* irc_server_outqueue_send: send a message from outqueue
|
|
*/
|
|
|
|
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 booleans), 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, not 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) where the file is, and
|
|
'yyyyy' a name for the file, which shows the purpose of 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]
|
|
----------------------------------------
|
|
/*
|
|
* gui_window_new: create a new window
|
|
*/
|
|
|
|
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="3,2,1,5",options="header"]
|
|
|========================================
|
|
| Code | Example | Areas | Description
|
|
| @h(19) + STD | @h(19)`01` | chat + bars | Set attributes and color using option, see table below
|
|
| @h(19) + EXT | @h(19)`@00001` | chat | Set color with a ncurses pair (used only on `/color` buffer)
|
|
| @h(19) + "F" + (A)STD | @h(19)`F*05` | chat + bars | Set foreground (WeeChat color)
|
|
| @h(19) + "F" + (A)EXT | @h(19)`F@00214` | chat + bars | Set foreground (extended color)
|
|
| @h(19) + "B" + STD | @h(19)`B05` | chat + bars | Set background (WeeChat color)
|
|
| @h(19) + "B" + EXT | @h(19)`B@00124` | chat + bars | Set background (extended color)
|
|
| @h(19) + "*" + (A)STD | @h(19)`*05` | chat + bars | Set foreground (WeeChat color)
|
|
| @h(19) + "*" + (A)EXT | @h(19)`*@00214` | chat + bars | Set foreground (extended color)
|
|
| @h(19) + "*" + (A)STD + "," + (A)STD | @h(19)`*08,05` | chat + bars | Set foreground/background (WeeChat colors)
|
|
| @h(19) + "*" + (A)STD + "," + (A)EXT | @h(19)`*01,@00214` | chat + bars | Set foreground (WeeChat color) and background (extended color)
|
|
| @h(19) + "*" + (A)EXT + "," + (A)STD | @h(19)`*@00214,05` | chat + bars | Set foreground (extended color) and background (WeeChat color)
|
|
| @h(19) + "*" + (A)EXT + "," + (A)EXT | @h(19)`*@00214,@00017` | chat + bars | Set foreground/background (extended colors)
|
|
| @h(19) + "b" + "F" | @h(19)`bF` | bars | Set bar foreground color
|
|
| @h(19) + "b" + "D" | @h(19)`bD` | bars | Set bar delimiter color
|
|
| @h(19) + "b" + "B" | @h(19)`bB` | bars | Set bar background color
|
|
| @h(19) + "b" + "_" | @h(19)`b_` | input bar | Start input char (used only in item "input_text")
|
|
| @h(19) + "b" + "-" | @h(19)`b-` | input bar | Start input hidden char (used only in item "input_text")
|
|
| @h(19) + "b" + "#" | @h(19)`b#` | input bar | Move cursor char char (used only in item "input_text")
|
|
| @h(19) + "b" + "i" | @h(19)`bi` | bars | Start item
|
|
| @h(19) + "b" + "l" (lower L) | @h(19)`bl` | bars | Start line item
|
|
| @h(19) + @h(1C) | @h(19)@h(1C) | chat + bars | Reset color (keep attributes)
|
|
| @h(1A) + ATTR | @h(1A)`*` | chat + bars | Set attribute
|
|
| @h(1B) + ATTR | @h(1B)`*` | chat + bars | Remove attribute
|
|
| @h(1C) | @h(1C) | chat + bars | Reset attributes and color
|
|
|========================================
|
|
|
|
Color codes using options (see 't_gui_color_enum', in file 'src/gui/gui-color.h'):
|
|
|
|
[width="60%",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 _(new in version 0.3.6)_
|
|
| 35 | weechat.color.chat_inactive_window _(new in version 0.3.6)_
|
|
| 36 | weechat.color.chat_inactive_buffer _(new in version 0.3.6)_
|
|
| 37 | weechat.color.chat_prefix_buffer_inactive_buffer _(new in version 0.3.6)_
|
|
| 38 | weechat.color.chat_nick_offline _(new in version 0.3.9)_
|
|
| 39 | weechat.color.chat_nick_offline_highlight _(new in version 0.3.9)_
|
|
|========================================
|
|
|
|
WeeChat colors are:
|
|
|
|
[width="40%",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="50%",cols="1,2",options="header"]
|
|
|========================================
|
|
| Code | Description
|
|
| @h(19)`01` | color of option "01" (chat text)
|
|
| @h(19)`*08,03` | yellow on red
|
|
| @h(19)`*@00214` | orange (extended color 214)
|
|
| @h(19)`*@*_00214,@00017` | bold underlined orange (214) on dark blue (17)
|
|
| @h(1A)`_` | set underline
|
|
| @h(1B)`_` | remove underline
|
|
| @h(1C)`bD` | reset attributes and color
|
|
|========================================
|
|
|
|
[[plugin_internals]]
|
|
Plugin internals
|
|
----------------
|
|
|
|
The file 'src/plugins/weechat-plugin.h' defines and exports all functions
|
|
available for 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 in an easier way.
|
|
|
|
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: http://git.savannah.gnu.org/gitweb/?p=weechat.git
|
|
|
|
Any patch for bug or new feature must be done on master branch, preferred format
|
|
is a patch made with `git diff` or `git format-patch`, sent by e-mail.
|
|
|
|
Format of commit message is the following:
|
|
|
|
----------------------------------------
|
|
component: fix a problem (bug #12345)
|
|
----------------------------------------
|
|
|
|
Where 'component' is one of following:
|
|
|
|
* WeeChat core: 'core' (files in directory 'src/' except doc and 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 (bug, task, patch), write it
|
|
in parenthesis after the message (format: bug #12345, task #12345, patch #12345)
|
|
|
|
Examples of commit messages:
|
|
|
|
----------------------------------------
|
|
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 dutch empty file:
|
|
|
|
----------------------------------------
|
|
$ cd po
|
|
$ msginit -i weechat.pot -l nl_NL -o nl.po
|
|
----------------------------------------
|
|
|
|
Base language for WeeChat is english, so you must of course understand english
|
|
in order to translate to your language.
|
|
|
|
When done, you *have* to check your file with two commands:
|
|
|
|
----------------------------------------
|
|
$ msgfmt -o /dev/null -c xx.po
|
|
$ msg_check_lines.py xx.po
|
|
----------------------------------------
|
|
|
|
The `msgfmt` will perform checks on message catalog and display errors, like bad
|
|
use of format specifiers in strings.
|
|
|
|
The script msg_check_lines.py (http://www.weechat.org/files/temp/po/msg_check_lines.py)
|
|
will check number of lines in translated strings (which must be the same as
|
|
string in english).
|
|
|
|
[[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 auto-generated files (for all languages).
|
|
|
|
[IMPORTANT]
|
|
When using command `/doc`, be sure all C plugins (irc, charset, ...) are loaded,
|
|
because files are built using options 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>>
|
|
----------------------------------------
|
|
|
|
Please make sure special chars below titles are exactly same length as title
|
|
(not too short or too long):
|
|
|
|
----------------------------------------
|
|
This is a correct title
|
|
=======================
|
|
|
|
This is a wrong title
|
|
============
|
|
|
|
This is a wrong title
|
|
=============================
|
|
----------------------------------------
|