-
-
Notifications
You must be signed in to change notification settings - Fork 1
Contributing
Contributions are welcome — bug reports, fixes, and new features alike. Please keep changes minimal and targeted; avoid unnecessary refactoring of working code.
See also AGENTS.md
in the repository for the full agent/developer reference.
git clone https://github.com/ekollof/xepher.git
cd xepher
git submodule update --init --recursivemake # build xmpp.so + run 123 doctests
make test # doctests only
make clean # remove build artifacts
make install # install to ~/.local/share/weechat/plugins/On BSD use gmake instead of make.
Distribution-style build (no .source embed — matches release packages):
make PACKAGE_BUILD=1 weechat-xmppThe compiler must support C++23 (-std=c++23). GCC 12+ or Clang 15+
(Linux/macOS); Clang 13+ on BSD.
- Follow the existing style in the file you are editing.
- C++23 throughout — use
std::string_view,std::optional,std::expected, structured bindings,std::ranges, etc. - Use
nullptr, notNULL. - RAII everywhere —
malloc/free/new/deleteare forbidden.
Isolate libstrophe reads and WeeChat output from domain logic:
| Prefer | Instead of |
|---|---|
xmpp::StanzaView (src/xmpp/stanza_view.hh) |
xmpp_stanza_get_*, manual child-pointer walks |
Fluent stanza::spec builders (src/xmpp/node.hh, XEP .inl) |
xmpp_stanza_new, xmpp_stanza_add_child
|
weechat::UiPort |
weechat_printf / direct buffer output in handlers |
weechat::BufferPort, LineStorePort, RenderEvent
|
Raw nicklist/line manipulation in domain code |
Handler slices live under src/xmpp/message_*.cpp and src/xmpp/iq_*.cpp.
Connection handlers are thin adapters. Extend these slices when adding protocol
features — do not grow monolithic .inl files with raw API calls.
Raw weechat_* and xmpp_stanza_* calls belong only in hook registration
glue and port adapter implementations.
| Pattern | What to use |
|---|---|
Strophe-allocated strings (e.g. xmpp_jid_bare) |
xmpp_string_guard |
| Heap byte buffers |
heap_buf / make_heap_buf (see src/omemo.hh) |
| LMDB key strings |
std::string + fmt::format
|
WeeChat string_dyn
|
weechat_string_dyn_free(ptr, 1) and own the raw pointer |
| Fixed-size arrays | std::make_unique<T[]>(N) |
Never let an LMDB transaction go out of scope without committing or aborting it.
- Hook/callback signatures must match WeeChat exactly.
- Use
UiPortfor user-visible output in commands and handlers. - Handler functions return
int:1= keep handler,0= remove. - Never use
weechat_buffer_merge()— it merges display history and causes unexpected behaviour. - Buffer display: use
"1"(don't auto-switch), not"auto". - Never reload the plugin — restart WeeChat after rebuilding.
-
Outbound: fluent
stanza::specbuilders only —xmpp_stanza_new()is forbidden in new code. -
Inbound:
xmpp::StanzaViewfor reads. - Pure IQ replies:
src/xmpp/iq_handlers.hh(handle_version_iq,handle_time_iq, …). - Use
xmpp_uuid_gen()for IDs; guard withxmpp_string_guard.
<type>: <short description>
[optional body — explain the why, not the what]
Types: feat, fix, docs, refactor, test, chore.
Keep commits atomic — one logical change per commit.
| File | Responsibility |
|---|---|
src/connection/message_handler.cpp |
Thin adapter → src/xmpp/message_*.cpp slices |
src/connection/iq_handler.cpp |
Thin adapter → src/xmpp/iq_*.cpp slices |
src/connection/presence_handler.cpp |
Presence and MUC join/leave |
src/connection/session_lifecycle.cpp |
Connect/disconnect, stream management |
src/xmpp/stanza_view.cpp |
Inbound stanza reads |
src/xmpp/iq_handlers.cpp |
Pure IQ reply builders |
src/weechat/ui_port.cpp, buffer_port.cpp, line_store.cpp
|
WeeChat ports |
src/account.cpp |
Account management, LMDB cache |
src/channel.cpp |
Chat buffer management (MUC and PM) |
src/command/*.cpp |
WeeChat /xmpp sub-commands |
src/omemo/api.cpp |
OMEMO encryption/decryption |
src/pgp.cpp |
PGP encryption |
Large .inl fragments are compiled via thin .cpp wrappers in subdirectories.
Open the .cpp wrapper (not the .inl) to read implementation logic.
channel::chat_type::MUC — multi-user chat room
channel::chat_type::PM — private (1-on-1) message
channel::chat_type::FEED — PubSub feed buffer
| Value | Meaning |
|---|---|
0 |
Brand new — fetch 7 days of history |
-1 |
User deliberately closed — skip MAM; do not auto-recreate |
> 0 |
Existing channel — fetch only messages newer than this timestamp |
123 doctests run automatically at the end of make DEBUG=1 (or make test anytime). They cover handler
slices, StanzaView, IQ builders, and port stubs (tests/weechat_stub.hh
provides CapturingUiPort, NullUiPort, StubRuntimePort).
make testFull WeeChat integration still requires manual testing:
- Build and install:
make && make install -
Restart WeeChat (do not
/plugin reload xmpp). - Connect an account and exercise the changed feature.
- Check logs (
xmpp.look.debug,xmpp.look.raw_xml_log) for protocol issues.
- PM buffers do not reappear after
/close - Typing indicators show nick (not full JID) in MUC
- OMEMO encrypts/decrypts in a PM
-
/bookmarklists bookmarks; autojoin works on reconnect - Plugin loads without errors (
/plugin listshowsxmpp)
- Fork the repository on GitHub.
- Create a branch:
git checkout -b fix/my-bugorfeat/my-feature. - Make focused, atomic commits.
- Run
make(doctests + build). - Test manually in WeeChat.
- Open a pull request against
master.
See the Releasing wiki page. Pushing a v* tag triggers GitHub Actions to
build and attach packages automatically.