Превод:
-
Иван Пешић (<ivan.pesic@gmail.com>), 2021.
Ово упутство описује WeeChat чет клијент и део је програма WeeChat.
Последња верзија овог документа може да се пронађе на овој страници ↗.
1. Увод
WeeChat (Wee Enhanced Environment for Chat) је бесплатни чет клијент, једноставан и брз, дизајниран за многе оперативне системе.
Ово упутство описује интерно функционисање програма WeeChat:
-
репозиторијуми
-
правила за писање кода
-
интерне ствари језгра
-
интерне ствари додатака
-
како дати допринос програму WeeChat.
2. Репозиторијуми
WeeChat репозиторијуми се налазе на GitHub организацији weechat ↗.
Листа репозиторијума:
- weechat
-
репозиторијум језгра са изворним кодом и документацијом
- scripts
-
званичне скрипте које су предате на weechat.org
- weechat.org
-
изворни кôд WeeChat вебсајта ↗
- weercd
-
IRC сервер за тестирање
- qweechat
-
Qt даљински ГКИ за WeeChat.
Ово упутство документује само weechat репозиторијум.
2.1. Преглед
Ово су главни WeeChat директоријуми:
Директоријум | Опис |
---|---|
|
Корен извора. |
|
Функције језгра: улазна тачка, интерне структуре. |
|
Функције кука. |
|
Функције за бафере, прозоре, … (користе их сви интерфејси). |
|
Curses интерфејс. |
|
Режим без интерфејса. |
|
Curses интерфејс. |
|
API за додатке и скриптовање. |
|
Alias додатак. |
|
Buflist додатак. |
|
Charset додатак. |
|
Exec додатак. |
|
Fifo додатак (FIFO пајп се користи за удаљено слање команди програму WeeChat). |
|
Fset (Fast Set) додатак. |
|
API за Guile (scheme) скриптовање. |
|
IRC (Internet Relay Chat) додатак. |
|
API за JavaScript скриптовање. |
|
Logger додатак (уписивање порука које се приказују у фајл). |
|
API за Lua скриптовање. |
|
API за Perl скриптовање. |
|
API за PHP скриптовање. |
|
API за Python скриптовање. |
|
Relay plugin (irc прокси + релеј за удаљене интерфејсе). |
|
API за Ruby скриптовање. |
|
Скрипт менаџер. |
|
Spell додатак. |
|
API за Tcl скриптовање. |
|
Trigger додатак. |
|
Typing додатак. |
|
Xfer додатак (IRC DCC фајл/разговор). |
|
Тестови. |
|
Тестови за API скриптовања. |
|
Python скрипте за генерисање и покретање тестова за API скриптовања. |
|
Unit тестови. |
|
Unit тестови за функције језгра. |
|
Unit тестови за функције интерфејса. |
|
Unit тестови за додатке. |
|
Unit тестови за IRC додатак. |
|
Документација. |
|
Фајлови превода (gettext). |
|
Debian паковање. |
2.2. Извори
Језгро
WeeChat „језгро” се налази у следећим директоријумима:
-
src/core/: функције језгра (за манипулацију подацима)
-
src/gui/: функције у вези интерфејса (бафери, прозори, …)
Путања/фајл | Опис |
---|---|
|
Функције језгра: тачка улаза, интерне структуре. |
|
Листе низова. |
|
Испис трага након краха. |
|
Израчунавање резултата израза. |
|
WeeChat команде језгра. |
|
Подразумевана довршавања. |
|
Управљање конфигурационим фајловима. |
|
Конфигурационе опције за WeeChat језгро (фајл weechat.conf). |
|
Криптографске функције. |
|
Неке дибаг функције. |
|
Функције директоријума/фајла. |
|
Изградња фајлова за документацију. |
|
Израчунавање израза са референцама на интерне променљиве. |
|
Хеш табеле. |
|
Hdata (директни приступ подацима употребом хеш табела). |
|
Куке. |
|
Инфолисте (листе са подацима објеката). |
|
Унос команди/текста. |
|
Сортиране листе. |
|
Упис у WeeChat лог фајл (weechat.log). |
|
Мрежне функције (повезивање са серверима/проксијима). |
|
Управљање проксијима. |
|
Функције обезбеђених података. |
|
Бафер обезбеђених података. |
|
Опције обезбеђених података (фајл sec.conf). |
|
Функције над стринговима. |
|
Системске функције. |
|
Интерни систем ажурирања. |
|
Ажурирање за WeeChat језгро (бафери, линије, историја, …). |
|
URL трансфер (помоћу libcurl). |
|
UTF-8 функције. |
|
Неке друге функције. |
|
Функције за WeeChat верзију. |
|
Основне функције: опције командне линије, покретање. |
|
Функције кука. |
|
Кука "command_run". |
|
Кука "command". |
|
Кука "completion". |
|
Кука "config". |
|
Кука "connect". |
|
Кука "fd". |
|
Кука "focus". |
|
Кука "hdata". |
|
Кука "hsignal". |
|
Кука "info_hashtable". |
|
Кука "info". |
|
Кука "infolist". |
|
Кука "line". |
|
Кука "modifier". |
|
Кука "print". |
|
Кука "process". |
|
Кука "signal". |
|
Кука "timer". |
|
Кука "url". |
|
Функције за бафере, прозоре, … (користе их сви интерфејси). |
|
Ставке трака. |
|
Прозори трака. |
|
Траке. |
|
Бафери. |
|
Функције разговора (призаз поруке, …). |
|
Функције боја. |
|
Довршавање у командној линији. |
|
Курсорски режим (слободно померање курсора). |
|
Филтери. |
|
Функције у вези фокуса (за курсорски режими миша). |
|
Команде/текст сачуван у баферима. |
|
Управљање врућом листом (листа бафера у којима има активности). |
|
Функције уноса (трака уноса). |
|
Функције тастатуре. |
|
Распоред. |
|
Линије у баферу. |
|
Миш. |
|
Функције надимака. |
|
Листа надимака у баферима. |
|
Прозори. |
|
Curses интерфејс. |
|
Приказ у прозорима трака. |
|
Приказ у простору разговора (поруке). |
|
Функције боја. |
|
Функције тастатуре (подраз. тастери, читање уноса). |
|
WeeChat главна петља (чекање на догађаје тастатуре/мреже). |
|
Миш. |
|
Функције у вези терминала. |
|
Прозори. |
|
Режим без интерфејса. |
|
Тачка улаза за режим без интерфејса. |
|
Лажна ncurses библиотека. |
|
Curses интерфејс. |
|
Тачка улаза за Curses интерфејс. |
Додаци
Путања/фајл | Опис |
---|---|
|
Корен додатака. |
|
Управљање додацима (учитавање/уклањање динамичких C библиотека). |
|
Додатне функције за API додатака (омотач око WeeChat функција језгра). |
|
Додатне info/infolist функције за API додатака. |
|
Опције конфигурације додатака (фајл plugins.conf). |
|
Опште функције које користе скрипт додаци. |
|
Скрипт API функције: омотачи око неких функција API додатака. |
|
Опције конфигурације скрипт додатака (фајлови python.conf, perl.conf, …). |
|
Заглавље које треба да се дистрибуира уз WeeChat додатке, како би могли да се компајлирају. |
|
Alias додатак. |
|
Главне алијас функције. |
|
Алијас команде. |
|
Алијас довршавање. |
|
Алијас опције конфигурације (фајл alias.conf). |
|
Алијас info/infolists/hdata. |
|
Додатак за проверу правописа. |
|
Главне функције провере правописа. |
|
Провера правописа ставке траке. |
|
Провера правописа команде. |
|
Провера правописа довршавања. |
|
Провера правописа опције конфиг (фајл spell.conf). |
|
Провера правописа info/infolists/hdata. |
|
Управљање библиотекама за проверу правописа. |
|
Buflist додатак. |
|
Главне buflist функције. |
|
Buflist ставке траке. |
|
Buflist команде. |
|
Buflist довршавања. |
|
Buflist опције конфиг (фајл buflist.conf). |
|
Buflist info/infolists/hdata. |
|
Buflist акције мишем. |
|
Charset додатак. |
|
Charset функције. |
|
Exec додатак. |
|
Главне exec функције. |
|
Exec бафер. |
|
Exec команде. |
|
Exec довршавања. |
|
Exec опције конфиг (фајл exec.conf). |
|
Fifo додатак. |
|
Главне fifo функције. |
|
Fifo команде. |
|
Fifo опције конфиг (фајл fifo.conf). |
|
Fifo info/infolists/hdata. |
|
Fset додатак. |
|
Главне fset функције. |
|
Fset ставке траке. |
|
Fset бафер. |
|
Fset команде. |
|
Fset довршавања. |
|
Fset опције конфиг (фајл fset.conf). |
|
Fset info/infolists/hdata. |
|
Fset акције мишем. |
|
Fset управљање опцијама. |
|
Guile (scheme) додатак. |
|
Главне guile функције (учитавање/уклањање скрипти, извршавање guile кода). |
|
API функције guile скриптовања. |
|
IRC (Internet Relay Chat) додатак. |
|
Основне IRC функције. |
|
IRC ставке траке. |
|
IRC пакетни догађаји. |
|
IRC бафери. |
|
IRC канали. |
|
IRC боје. |
|
IRC команде. |
|
IRC довршавања. |
|
IRC опције конфиг (фајл irc.conf). |
|
IRC CTCP. |
|
IRC дибаг функције. |
|
IRC Ignore. |
|
IRC info/infolists/hdata. |
|
Унос команди/текста. |
|
Функције за листе канала којима се приступа. |
|
Бафер за одговор на /list команду. |
|
Функције за манипулисање IRC порукама. |
|
Функције у вези режима канала/надимка. |
|
Листе режима IRC канала (+b, +e, +I, …). |
|
Циљни бафер за IRC поруке. |
|
IRC надимци. |
|
IRC листе за обавештавање. |
|
IRC протокол (RFCs 1459/2810/2811/2812/2813/7194). |
|
IRC сирови бафер. |
|
Преусмеравање излаза IRC команде. |
|
SASL аутентификација са IRC сервером. |
|
У/И комуникација са IRC сервером. |
|
Функције за манипулацију ознакама IRC порука. |
|
Статус куцања. |
|
Чување/обнављање IRC података када се ажурира програм WeeChat. |
|
JavaScript додатак. |
|
Главне JavaScript функције (учитавање/уклањање скрипти, извршавање JavaScript кода). |
|
API функције JavaScript скриптовања. |
|
JavaScript v8 функције. |
|
Logger додатак. |
|
Главне logger функције. |
|
Logger backlog функције. |
|
Logger управљање листом бафера. |
|
Logger команде. |
|
Logger опције конфиг (фајл logger.conf). |
|
Logger info/infolists/hdata. |
|
Функције за враћање последњих линија фајла. |
|
Lua додатак. |
|
Главне lua функције (учитавање/уклањање скрипти, извршавање lua кода). |
|
API функције Lua скриптовања. |
|
Perl додатак. |
|
Главне perl функције (учитавање/уклањање скрипти, извршавање perl кода). |
|
API функције Perl скриптовања. |
|
PHP додатак. |
|
Главне PHP функције (учитавање/уклањање скрипти, извршавање PHP кода). |
|
API функције PHP скриптовања. |
|
Python додатак. |
|
Главне python функције (учитавање/уклањање скрипти,извршавање python кода). |
|
API функције Python скриптовања. |
|
Релеј додатак (IRC прокси и релеј за удаљене интерфејсе). |
|
Главне релеј функције. |
|
Аутентификација клијената. |
|
Релеј бафер. |
|
Клијенти релеја. |
|
Релеј команде. |
|
Релеј довршавања. |
|
Релеј опције конфиг (фајл relay.conf). |
|
HTTP функције. |
|
Релеј info/infolists/hdata. |
|
Мрежне функције за релеј. |
|
Релеј сирови бафер. |
|
Релеј удаљених. |
|
Релеј сервер. |
|
Чување/обнављање података релеја када се ажурира WeeChat. |
|
WebSocket сервер функције (RFC 6455). |
|
Релеј за удаљене интерфејсе (користећи HTTP REST API). |
|
Главне API функције за HTTP REST API. |
|
Слање JSON порука клијентима. |
|
HTTP REST API протокол. |
|
Функције прослеђивања удаљених, специфичне за API. |
|
Обрада догађаја који се приме од релеја удаљених. |
|
Мрежне функције за релеј удаљених. |
|
IRC прокси. |
|
Главне IRC прокси функције. |
|
Релеј за удаљене интерфејсе (користећи „weechat” бинарни протокол). |
|
Релеј за удаљене интерфејсе (главне функције). |
|
Слање бинарних порука клијентима. |
|
Функције листе надимака. |
|
Читање команди од клијената. |
|
Ruby додатак. |
|
Главне ruby функције (учитавање/уклањање скрипти, извршавање ruby кода). |
|
API функције Ruby скриптовања. |
|
Управљач скриптама. |
|
Главне функције за управљача скриптама. |
|
Акције над скриптама (учитавање/уклањање, инсталација/деинсталација, …). |
|
Бафер за управљача скриптама. |
|
Команде за управљача скриптама. |
|
Довршавања за управљача скриптама. |
|
Опције конфигурације за управљача скриптама (фајл script.conf). |
|
Управљач скриптама info/infolists/hdata. |
|
Скрипт акције мишем. |
|
Преузимање и читање фајла репозиторијума. |
|
Tcl додатак. |
|
Главне tcl функције (учитавање/уклањање скрипти, извршавање tcl кода). |
|
API функције Tcl скриптовања. |
|
Окидач додатак. |
|
Главне функције окидача. |
|
Окидач бафер. |
|
Окидач функције повратног позива. |
|
Окидач команде. |
|
Окидач довршавања. |
|
Окидач опције конфиг (фајл trigger.conf). |
|
Typing додатак. |
|
Главне typing функције. |
|
Typing ставке траке. |
|
Typing конфигурационе опције (фајл typing.conf). |
|
Статус куцања порука на баферима. |
|
Xfer додатак (IRC DCC фајл/разговор). |
|
Главне xfer функције. |
|
Xfer бафер. |
|
DCC разговор. |
|
Xfer команде. |
|
Xfer довршавања. |
|
Xfer опције конфиг (фајлxfer.conf). |
|
DCC пренос фајла. |
|
Фајл функције за xfer. |
|
Xfer info/infolists/hdata. |
|
Мрежне функције за xfer. |
|
Чување/обнављање xfer података када се програм WeeChat ажурира. |
Тестови
Путања/фајл | Опис |
---|---|
|
Корен тестова. |
|
Програм који се користи за извршавање свих тестова. |
|
Бележење и претрага у приказаним порукама. |
|
Корен тестова за API скриптовања. |
|
Програм који се користи за извршавање тестова API скриптовања. |
|
Python скрипте које генеришу и покрећу тестове API скриптовања. |
|
Python скрипта која генерише скрипте на свим језицима за тестирање API скриптовања. |
|
Python скрипта са тестовима API скриптовања, користи је скрипта testapigen.py. |
|
Конверзија Python кода у остале језике, користи је скрипта testapigen.py. |
|
Корен unit тестова. |
|
Тестови: plugins. |
|
Тестови: инфо функције API додатака. |
|
Тестови: функције конфигурације додатка. |
|
Корен unit тестова језгра. |
|
Тестови: arraylists. |
|
Тестови: калкулација израза. |
|
Тестови: команде. |
|
Тестови: конфигурациони фајлови. |
|
Тестови: криптографске функције. |
|
Тестови: функције директоријума/фајла. |
|
Тестови: израчунавање израза. |
|
Тестови: hashtables. |
|
Тестови: hdata. |
|
Тестови: куке. |
|
Тестови: infolists. |
|
Тестови: листе. |
|
Тестови: мрежне функције. |
|
Тестови: обезбеђени подаци. |
|
Тестови: сигнали. |
|
Тестови: стрингови. |
|
Тестови: URL адресе. |
|
Тестови: UTF-8. |
|
Тестови: помоћне функције. |
|
Тестови: системске функције. |
|
Корен unit тестова за куке. |
|
Тестови: куке „command”. |
|
Тестови: куке „command_run”. |
|
Тестови: куке „completion”. |
|
Тестови: куке „config”. |
|
Тестови: куке „connect”. |
|
Тестови: куке „fd”. |
|
Тестови: куке „focus”. |
|
Тестови: куке „hdata”. |
|
Тестови: куке „hsignal”. |
|
Тестови: куке „info_hashtable”. |
|
Тестови: куке „info”. |
|
Тестови: куке „infolist”. |
|
Тестови: куке „line”. |
|
Тестови: куке „modifier”. |
|
Тестови: куке „print”. |
|
Тестови: куке „process”. |
|
Тестови: куке „signal”. |
|
Тестови: куке „timer”. |
|
Тестови: куке „url”. |
|
Корен unit тестова интерфејса. |
|
Тестови: функције прозора траке. |
|
Тестови: бафер функције. |
|
Тестови: чет функције. |
|
Тестови: боје. |
|
Тестови: филтери. |
|
Тестови: функције врућих листи. |
|
Тестови: улазне функције. |
|
Тестови: тастери. |
|
Тестови: линије. |
|
Тестови: надимци. |
|
Тестови: функције листе надимака. |
|
Корен unit тестова за Curses интерфејс. |
|
Тестови: миш (Curses интерфејс). |
|
Корен unit тестова додатака. |
|
Корен unit тестова IRC додатка. |
|
Тестови: IRC пакетни догађаји. |
|
Тестови: IRC бафери. |
|
Тестови: IRC канали. |
|
Тестови: IRC боје. |
|
Тестови: IRC команде. |
|
Тестови: IRC конфигурација. |
|
Тестови: IRC CTCP. |
|
Тестови: IRC игнорисања. |
|
Тестови: IRC информације. |
|
Тестови: IRC функције приступања. |
|
Тестови: IRC бафер за одговор на /list команду. |
|
Тестови: IRC поруке. |
|
Тестови: IRC режими. |
|
Тестови: IRC надимци. |
|
Тестови: IRC протокол. |
|
Тестови: SASL аутентификација са IRC протоколом. |
|
Тестови: IRC сервер. |
|
Тестови: IRC ознаке порука. |
|
Корен unit тестова за logger додатак. |
|
Тестови: logger. |
|
Тестови: logger заостатак. |
|
Тестови: logger tail функције. |
|
Корен unit тестова за окидач додатак. |
|
Тестови: окидачи. |
|
Тестови: конфигурација окидача. |
|
Корен unit тестова за typing додатак. |
|
Тестови: typing. |
|
Тестови: typing статус. |
|
Корен unit тестова за Релеј додатак. |
|
Тестови: аутентификација клијената. |
|
Тестови: HTTP функције за Релеј додатак. |
|
Тестови: функције сирових порука за Релеј додатак. |
|
Тестови: удаљене функције за Релеј додатак. |
|
Тестови: websocket функције за Релеј додатак. |
|
Корен unit тестова за Релеј „api” протокол. |
|
Тестови: Релеј „api” протокол: опште функције. |
|
Тестови: Релеј „api” протокол: поруке. |
|
Тестови: Релеј „api” протокол: протокол. |
|
Корен unit тестова за Релеј „irc” протокол. |
|
Тестови: Релеј „irc” протокол. |
|
Корен unit тестова за Xfer додатак. |
|
Тестови: фајл функције. |
|
Тестови: мрежне функције. |
2.3. Документација / преводи
Фајлови документације:
Путања/фајл | Опис |
---|---|
|
Документација. |
|
Asciidoctor стил. |
|
Документација за језик XX (језици: en, fr, de, it, …). |
|
Man страница( |
|
Водич за програмере ↗ (овај документ). |
|
|
|
|
|
|
|
Релеј „api” протокол (за удаљене интерфејсе). |
|
Релеј „weechat” протокол ↗ (за удаљене интерфејсе). |
|
|
|
|
|
Фајлови укључени у документацију. |
|
Опције командне линије (фајл се укључује у man странице и корисничко упутство). |
|
Део man страница: опције додатака, фајлови и ауторска права. |
Преводи програма WeeChat и додатака се раде помоћу програма gettext, фајлови се налазе у po/ директоријуму:
Путања/фајл | Опис |
---|---|
|
Фајлови превода (gettext). |
|
Преводи за језик XX (fr, de, it, …), базни језик је енглески. |
|
Шаблон за преводе (аутоматски изграђен). |
3. Правила за писање кода
3.1. Општа правила
-
Ваши коментари, имена променљивих, … у изворном коду морају бити написани само на енглеском језику (није дозвољена употреба ниједног другог језика).
-
Употребите заглавље ауторских права у сваком новом изворном фајлу са:
-
кратким описом фајла (једна линија)
-
датумом,
-
именом,
-
имејл адресом,
-
лиценцом.
-
Пример у језику C:
/*
* weechat.c - core functions for WeeChat
*
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
3.2. C стил
Када пишете C кôд, морате да се придржавате неких основних правила:
-
За увлачење користите 4 размака (без табулатора).
-
Покушајте да не прекорачите 80 карактера по линији, осим ако је то неопходно за читљивост.
-
Користите коментаре
/* коментар */
(а не коментаре у C99 стилу као што је// коментар
). -
Испред сваке функције додајте коментар који објашњава шта она ради (увек користите вишелинијски коментар, чак и ако је опис кратак).
Пример:
/*
* 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);
}
-
Користите експлицитна имена променљивих, на пример „nicks_count” уместо „n” или „nc”. Изузетак: у
for
петљама су променљиве као што су „i” или „n” ОК. -
Након декларације, у телу функције иницијализујте локалне променљиве, пример:
void
foo ()
{
int nick_count, buffer_count;
nick_count = 0;
buffer_count = 1;
/* ... */
}
-
Употребите заграде да експлицитно покажете како се израз израчунава, чак и када нису неопходне, на пример: write
x + (y * z)
уместоx + y * z
. -
Постављајте витичасте заграде
{ }
саме у линије, и увуците их за број размака који се користио у линији изнад отворене витичасте заграде (if
у примеру):
if (nicks_count == 1)
{
/* нешто */
}
-
За раздвајање више различитих блокова унутар функција, употребите празне линије, а ако је могуће, додајте и коментар за сваку. Овако:
/*
* 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);
}
/* ... */
}
-
Увлачите
if
услове у употребљавајте заграде око услова са оператором (није потребно само за једну логичку вредност). Овако:
if (нешто)
{
/* нешто */
}
else
{
/* нешто друго */
}
if (my_boolean1 && my_boolean2 && (i == 10)
&& ((buffer1 != buffer2) || (window1 != window2)))
{
/* нешто */
}
else
{
/* нешто друго */
}
-
Увлачите
switch
наредбе на следећи начин:
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;
}
-
Користите
typedef
за прототипе функција, али не и за структуре:
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));
-
Ако користите Emacs као текст едитор, за исправно увлачење можете у свом ~/.emacs.el употребити 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 '+)))
3.3. Python стил
Погледајте PEP 8 ↗.
4. Интерне ствари језгра
4.1. Конвенција именовања
Фајлови
Имена фајлова се састоје од слова и цртица, у формату: xxx-yyyyy.[ch], где је xxx директоријум/компонента (може бити и скраћеница), а yyyyy је име за фајл.
Главни фајл директоријума може имати исто име као и директоријум, на пример irc.c у irc додатку.
Примери:
Директоријум | Фајлови |
---|---|
|
weechat.c, core-backtrace.c, core-command.c, … |
|
gui-bar.c, gui-bar-item.c, gui-bar-window.c, … |
|
gui-curses-bar.c, gui-curses-bar-window.c, gui-curses-chat.c, … |
|
plugin.c, plugin-api.c, plugin-api-info.c, plugin-config.c, plugin-script.c, … |
|
irc.c, irc-bar-item.c, irc-buffer.c, … |
|
weechat-python.c, weechat-python-api.c, … |
Заглавља C фајлова имају сито име као и фајл, на пример core-command.h за фајл core-command.c.
Структуре
Структуре имају име t_X_Y или t_X_Y_Z:
-
X: директоријум/компонента (може бити и скраћеница)
-
Y: крај имена фајла
-
Z: име за структуру (није обавезно)
Пример: IRC надимак (из src/plugins/irc/irc-nick.h):
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 */
};
Променљиве
Глобалне променљиве (ван функција) имају име X_Y_Z:
-
X: директоријум/компонента (може бити и скраћеница)
-
Y: крај имена фајла
-
Z: име за променљиву
Изузетак су променљиве за „последњи” чвор листе, име је last_X (где је X име променљиве, користећи облик једнине).
Пример: прозори (from src/gui/gui-window.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 */
За локалне променљиве (у функцијама) нема конвенције давања имена. Једина препорука је да име буде експлицитно (не сувише кратко).
Ипак, показивачи на структуре се често именују са ptr_xxxx, на пример показивач на структуру struct t_gui_buffer * ће бити: *ptr_buffer.
Функције
Конвенција именовања функција је иста као за променљиве.
Пример: креирање новог прозора (из src/gui/gui-window.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;
}
4.2. Једна нит извршавања
Програм WeeChat се извршава у једној нити. То значи да би сваки део кода требало да се извршава веома брзо и да су позиви функција као што је sleep
стриктно забрањени (то је тачно за WeeChat језгро, али и за C додатке и скрипте).
Ако из неког разлога морате да одспавате накратко, употребите hook_timer
са функцијом повратног позива.
4.3. Двоструко уланчане листе
Већина листи у програму WeeChat су двоструко уланчане листе: сваки чвор има показивач на претходни и на следећи чвор.
Пример: листа бафера (из src/gui/gui-buffer.h):
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 */
};
Затим, сва показивача листе, на чело и на реп листе:
struct t_gui_buffer *gui_buffers = NULL; /* first buffer */
struct t_gui_buffer *last_gui_buffer = NULL; /* last buffer */
4.4. Кодови боја у стринговима
Програм WeeChat користи сопствене кодове боја у стринговима за приказ атрибута (подебљано, подвучено, …) и боја на екрану.
Испред свих атрибута/боја се налази карактер у стрингу који може бити:
-
0x19: кôд боје (иза кога следи кôд (или више њих) боје))
-
0x1A: постављање атрибута (након којег следи један карактер сировог атрибута)
-
0x1B: уклањање атрибута (након којег следи један карактер сировог атрибута)
-
0x1C: ресет (нема ништа иза)
Могуће су следеће боје:
-
стандардна боја: необавезни атрибути + двоцифрени број
-
проширена боја:
@
+ необавезни атрибути + петоцифрени број
У следећој табели се подразумева следеће:
-
СТД
: стандардна боја (2 цифре) -
(ATTR)СТД
: стандардна боја са необавезним атрибутима (атрибути + 2 цифре) -
ПРО
: проширена боја (@
+ 5 цифара) -
(ATTR)ПРО
: проширена боја са необавезним атрибутима (@
+ атрибути + 5 цифара) -
(ATTR)
: један или више карактера атрибута:-
%
: трептање -
.
: „dim” (затамњено) -
*
: подебљано -
!
: обрнуто -
/
: курзив -
_
: подвучено -
|
: задржавају се постојећи атрибути
-
-
(a)
: један сирови карактер атрибута:-
0x01: подебљано
-
0x02: обрнуто
-
0x03: курзив
-
0x04: подвучено
-
0x05: трептање
-
0x06: „dim” (затамњено)
-
У следећој табели су сажете све комбинације:
Кôд | Пример | Површине | Опис |
---|---|---|---|
19 + |
19 |
чет + траке |
Постављање атрибута и боје опцијама, погледајте табелу испод. |
19 + |
19 |
chat |
Постављање боје са ncurses паром (користи се само у |
19 + |
19 |
чет + траке |
Постављање предњег плана (WeeChat боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (проширена боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (WeeChat боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (проширена боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (WeeChat боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (проширена боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана/позадине (WeeChat боје). |
19 + |
19 |
чет + траке |
Постављање предњег плана (WeeChat боје) у позадине (проширена боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (extended color) и позадине (WeeChat color). |
19 + |
19 |
чет + траке |
Постављање предњег плана/позадине (проширене боје). |
19 + |
19 |
чет + траке |
Постављање предњег плана/позадине (WeeChat боје). |
19 + |
19 |
чет + траке |
Постављање предњег плана (WeeChat color) и позадине (проширена боја). |
19 + |
19 |
чет + траке |
Постављање предњег плана (проширена боја) и позадине (WeeChat color). |
19 + |
19 |
чет + траке |
Постављање предњег плана/позадине (проширене боје). |
19 + |
19 |
траке |
Постављање боје предњег плана траке. |
19 + |
19 |
траке |
Постављање боје граничника траке. |
19 + |
19 |
траке |
Постављање боје позадине траке. |
19 + |
19 |
трака уноса |
Почетак уноса карактера (користи се само у ставки „input_text”). |
19 + |
19 |
трака уноса |
Почетак уноса скривеног карактера (користи се само у ставки „input_text”). |
19 + |
19 |
трака уноса |
Померање курсор карактера (користи се само у ставки „input_text”). |
19 + |
19 |
траке |
Почетак ставке. |
19 + |
19 |
траке |
Почетак линије ставке. |
19 + |
19 |
чет + траке |
Наглашавање текста (WeeChat ≥ 0.4.2). |
19 + 1C |
19 1C |
чет + траке |
Ресет боје (уз задржавање атрибута). |
1A + |
1A 01 |
чет + траке |
Постављање атрибута. |
1B + |
1B 01 |
чет + траке |
Уклањање атрибута. |
1C |
1C |
чет + траке |
Ресет атрибута и боје. |
Белешка
|
(1) Као граничник се користила запета све до верзије WeeChat 2.5. У верзијама WeeChat ≥ 2.6, користи се тилда за раздвајање боје предњег плана од боје позадине. Ако развијате WeeChat релеј клијент и желите да буде компатибилан са свим WeeChat верзијама, требало би да подржава оба граничника (на пример, корисник са WeeChat ≤ 2.5 изврши /upgrade на верзију ≥ 2.6, па би у баферима оба граничника могла да се користе у исто време).
|
Кодови боја употребом опција (погледајте t_gui_color_enum, у фајлу src/gui/gui-color.h):
Кôд | Опција |
---|---|
|
weechat.color.separator |
|
weechat.color.chat |
|
weechat.color.chat_time |
|
weechat.color.chat_time_delimiters |
|
weechat.color.chat_prefix_error |
|
weechat.color.chat_prefix_network |
|
weechat.color.chat_prefix_action |
|
weechat.color.chat_prefix_join |
|
weechat.color.chat_prefix_quit |
|
weechat.color.chat_prefix_more |
|
weechat.color.chat_prefix_suffix |
|
weechat.color.chat_buffer |
|
weechat.color.chat_server |
|
weechat.color.chat_channel |
|
weechat.color.chat_nick |
|
weechat.color.chat_nick_self |
|
weechat.color.chat_nick_other |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
(од WeeChat верзије 0.3.4 се више не користи) |
|
weechat.color.chat_host |
|
weechat.color.chat_delimiters |
|
weechat.color.chat_highlight |
|
weechat.color.chat_read_marker |
|
weechat.color.chat_text_found |
|
weechat.color.chat_value |
|
weechat.color.chat_prefix_buffer |
|
weechat.color.chat_tags (WeeChat ≥ 0.3.6) |
|
weechat.color.chat_inactive_window (WeeChat ≥ 0.3.6) |
|
weechat.color.chat_inactive_buffer (WeeChat ≥ 0.3.6) |
|
weechat.color.chat_prefix_buffer_inactive_buffer (WeeChat ≥ 0.3.6) |
|
weechat.color.chat_nick_offline (WeeChat ≥ 0.3.9) |
|
weechat.color.chat_nick_offline_highlight (WeeChat ≥ 0.3.9) |
|
weechat.color.chat_nick_prefix (WeeChat ≥ 0.4.1) |
|
weechat.color.chat_nick_suffix (WeeChat ≥ 0.4.1) |
|
weechat.color.emphasized (WeeChat ≥ 0.4.2) |
|
weechat.color.chat_day_change (WeeChat ≥ 0.4.2) |
|
weechat.color.chat_value_null (WeeChat ≥ 1.4) |
|
weechat.color.chat_status_disabled (WeeChat ≥ 4.0.0) |
|
weechat.color.chat_status_enabled (WeeChat ≥ 4.0.0) |
Ово су WeeChat боје:
Кôд | Боја |
---|---|
|
Подразумевана (боја предњег плана/позадине у терминалу) |
|
Црна |
|
Тамносива |
|
Тамноцрвена |
|
Светлоцрвена |
|
Тамнозелена |
|
Светлозелена |
|
Браон |
|
Жута |
|
Тамноплава |
|
Светлоплава |
|
Тамномагента |
|
Светломагента |
|
Тамнотиркизна |
|
Светлотиркизна |
|
Сива |
|
Бела |
Примери кодова боја:
Кôд | Опис |
---|---|
19 |
Боја опције "01" (текст разговора) |
19 |
Жута на црвеном |
19 |
Наранџаста (проширена боја 214) |
19 |
Подебљана подвучена наранџаста (214) на тамноплавој (17) |
1A |
Поставља подвлачење |
1B |
Уклања подвлачење |
1C |
Ресетује атрибуте и боје |
5. Интерне ствари додатака
Фајл src/plugins/weechat-plugin.h дефинише и извози све функције које су доступне у API.
За чување информација о додатку се користи структура под именом t_weechat_plugin (име фајла, име, аутор, опис, …) и све API функције, као показивачи на WeeChat функције.
Дефинисани су и неки макрои за позивање ових функција.
На пример, функција hook_timer је дефинисана у структури t_weechat_plugin на следећи начин:
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);
А макро који се користи за позивање ове функције је:
#define weechat_hook_timer(__interval, __align_second, __max_calls, \
__callback, __data) \
weechat_plugin->hook_timer(weechat_plugin, __interval, \
__align_second, __max_calls, \
__callback, __data)
Тако да ће у додатку позив функције изгледати овако:
server->hook_timer_sasl = weechat_hook_timer (timeout * 1000,
0, 1,
&irc_server_timer_sasl_cb,
server);
6. Давање доприноса програму WeeChat
6.1. Git репозиторијум
Гит репозиторијум се налази на GitHub ↗.
Било каква закрпа бага или нова могућност мора да да се уради над мастер граном, пожељно је преко GitHub pull захтева. Закрпа такође може да се пошаље и имејлом (направљена са git diff
или git format-patch
).
Формат комит поруке је следећи (са аутоматским затварањем GitHub проблема):
компонента: исправка проблема (затвара #123)
Где је компонента једно од следећег:
Компонента | Фајлови | Опис |
---|---|---|
|
|
WeeChat језгро |
|
|
Изградња |
|
|
Непрекидна интеграција |
|
|
Debian паковање |
|
|
Тестови |
|
|
Општа ажурирања документације, на пример за изградњу |
|
|
Man странице |
|
|
Често постављана питања (ЧПП) |
|
|
Водич за брзи почетак |
|
|
Корисничко упутство |
|
|
Водич за скриптовање |
|
|
Референтни приручник API додатака |
|
|
Релеј протоколи |
|
|
Водич за програмере |
|
|
Додатак |
Нека правила која треба да поштујете:
-
Користите само енглески језик.
-
Користите глагол у инфинитиву.
-
Ако је комит у вези са GitHub проблемом, напишите га у заградама након поруке, у формату:
(issue #123)
или(closes #123)
да га затворите.
Примери комит порука:
core: add callback "nickcmp" for nick comparison in buffers core: update Japanese translations irc: add command /unquiet (closes #36) python: fix crash when unloading a script without pointer to interpreter ruby: add detection of ruby version 1.9.3 in CMake
6.2. Преводи
Gettext
Gettext фајлови се налазе у po/ директоријуму.
Ако желите да иницијализујете нови језик, употребите команду msginit
. На пример, да бисте креирали нови фајл који је спреман за превод на холандски:
cd po
msginit -i weechat.pot -l nl_NL -o nl.po
Базни језик за програм WeeChat је енглески, тако да се подразумева да перфектно разумете енглески како бисте могли да урадите превод на свој језик.
Након измена у изворним фајловима, можете да регенеришете све фајлове превода следећом командом у CMake „build” директоријуму:
make translations && make update-po
Затим можете да уређујте .po фајлове (ако можете да преводите на језик).
Када завршите, морате да проверите свој фајл са msgcheck ↗:
msgcheck.py xx.po
И након тога можете да рекомпајлирате програм WeeChat тако да користи нове преводе.
Asciidoc
Asciidoc фајлови се налазе у директоријуму doc/XX/ где је XX језик (en, fr, de, it, …).
Најпре направите копију енглеског asciidoc фајла (у директоријуму doc/en/), па затим радите на њој.
Преводи који недостају у фајловима су назначени следећим стрингом:
// TRANSLATION MISSING
Морате да преведете комплетан фајл осим линкова и специјалних кључних речи за напомене, упозорења, … Ове речи морате оставити непреведене:
[[име_линка]] <<име_линка>> [NOTE] [TIP] [IMPORTANT] [WARNING] [CAUTION]
Када након <<име_линка>>
постоји име, онда морате да га преведете:
<<име_линка,овај текст мора да се преведе>>