#+TITLE: jabber.el - The XMPP client for Emacs
#+TEXINFO_DIR_NAME: * jabber.el: (jabber)
#+TEXINFO_DIR_DESC: jabber.el - The XMPP client for Emacs
#+TEXINFO_DIR_CATEGORY: Emacs

* About
[[https://elpa.nongnu.org/nongnu/jabber.svg]]

=jabber.el= is an [[http://xmpp.org][XMPP]] client for Emacs.

See the [[https://xmpp.org/software/jabber-el/][xmpp.org page]] for the full list of supported XEPs.

+ [[https://thanosapollo.org/projects/jabber/][Homepage]]

+ Source:
  + [[https://git.thanosapollo.org/emacs-jabber/about/][git.thanosapollo.org]]

* Requirements

+ Emacs 29.1 or later, compiled with dynamic module support
+ [[https://elpa.gnu.org/packages/fsm.html][fsm]] 0.2.0 or later
+ [[https://elpa.gnu.org/packages/keymap-popup.html][keymap-popup]] 0.2 or later

** OMEMO encryption (optional)

OMEMO end-to-end encryption uses a native C module built from the
vendored [[https://github.com/mierenhoop/picomemo][picomemo]] source.  Build dependencies: a C compiler,
=pkg-config=, and Mbed TLS 3.0 or later (=mbedcrypto=).

Build the module manually from the jabber source or ELPA/package
directory:

#+begin_src sh
  cd /path/to/jabber-source-or-elpa-dir
  make module
#+end_src

The resulting =jabber-omemo-core.so= (or =.dylib= on macOS) lands
beside the Elisp files and is loaded automatically.  If the module is
missing, OMEMO use signals =OMEMO module not compiled=.

* Installation
=jabber.el= is available via [[https://elpa.nongnu.org/nongnu/jabber.html][NonGNU ELPA]].

You can install it via =M-x package-install RET jabber=

** package-vc (Emacs 30+)

Emacs honors package-vc build commands such as =:make= only when
=package-vc-allow-build-commands= allows the package.

#+begin_src emacs-lisp
  (setq package-vc-allow-build-commands '(jabber))

  (use-package jabber
    :ensure nil
    :vc (:url "https://git.thanosapollo.org/emacs-jabber"
              :branch "master"
              :rev :newest
              :lisp-dir "lisp"
              :doc "README.org"
              :make "module")
    :custom
    (jabber-account-list '(("user@example.org")))
    :config
    (jabber-modeline-mode 1)
    :bind-keymap (("C-x C-j" . jabber-global-keymap))
    :hook (kill-emacs . jabber-disconnect))
#+end_src

** straight.el

#+begin_src emacs-lisp
  (use-package jabber
    :straight `(jabber
                :type git
                :host nil
                :repo "https://git.thanosapollo.org/emacs-jabber"
                :branch "master"
                :files ("lisp/*.el"
                        "lisp/jabber-omemo-core.so"
                        "lisp/jabber-omemo-core.dylib")
                :pre-build ,(pcase system-type
                              ('berkeley-unix '(("gmake" "module" "CC=clang")))
                              ('darwin '(("make" "module" "CC=clang")))
                              (_ '(("make" "module")))))
    :custom
    (jabber-account-list '(("user@example.org")))
    :config
    (jabber-modeline-mode 1)
    :bind-keymap (("C-x C-j" . jabber-global-keymap))
    :hook (kill-emacs . jabber-disconnect))
#+end_src


** Nix

The repository ships a =flake.nix= with Emacs, test, lint, and
native-module build dependencies.

#+begin_src sh
  make test
  make module
#+end_src

To enter the same environment manually:

#+begin_src sh
  nix develop
#+end_src

To run the isolated Nix checks:

#+begin_src sh
  nix flake check
#+end_src

* Configuration
** Authentication
Accounts are configured via =jabber-account-list=.  The simplest form
uses auth-source =~/.authinfo.gpg= for passwords:

#+begin_src emacs-lisp
  (setq jabber-account-list '(("user@example.org")
                               ("second@account.org")))
#+end_src

With =pass= (password-store):

#+begin_src emacs-lisp
  (setq jabber-account-list
        `(("user@example.org"
           (:password . ,(auth-source-pass-get 'secret "xmpp/example.org/user")))))
#+end_src

** SOCKS5 proxy
An account can connect through an unauthenticated SOCKS5 proxy:

#+begin_src emacs-lisp
  (setq jabber-account-list
        '(("user@example.org"
           (:proxy . (:type socks5 :host "127.0.0.1" :port 9050)))))
#+end_src

The destination hostname is sent to the proxy rather than resolved locally.
Proxy connections bypass SRV lookup and use the JID domain on port 5222, or
=:network-server= and =:port= when those are configured.  STARTTLS is supported.
Direct TLS discovery, proxy authentication, and other proxy protocols are not
supported for proxied accounts.

** Bug references

#+begin_src emacs-lisp
  (add-hook 'jabber-chat-mode-hook #'bug-reference-mode)

  ;; Customize references
  (setq jabber-bug-reference-alist
        '(("jabber-el@conference\\.hmm\\.st"
           "\\(#\\([0-9]+\\)\\)"
           "https://todos.thanosapollo.org/r/emacs-jabber/%s")))
#+end_src

* Basic commands
+ Use =M-x jabber-roster= or =C-x C-j C-r= to get started.
