Next: Installation [Contents]
https://elpa.gnu.org/packages/ement.svg
Ement.el is a Matrix client for GNU Emacs. It aims to be simple, fast, featureful, and reliable, while integrating naturally with Emacs.
Feel free to join us in the chat room: https://img.shields.io/matrix/ement.el:matrix.org.svg?label=%23ement.el:matrix.org
Next: GNU Guix, Up: Installation [Contents]
Ement.el is published in GNU ELPA as ement, so it may be installed in Emacs with the command M-x package-install RET ement RET
. This is the recommended way to install Ement.el, as it will install the current stable release.
The latest development build may be installed from ELPA-devel or from Git (see below).
Next: Debian, Ubuntu, Previous: GNU ELPA, Up: Installation [Contents]
Ement.el is available in GNU Guix as emacs-ement.
Next: Nix, Previous: GNU Guix, Up: Installation [Contents]
Ement.el is available in Debian as elpa-ement and in Ubuntu as elpa-ement.
Next: Other distributions, Previous: Debian, Ubuntu, Up: Installation [Contents]
Ement.el is available in NixOS as emacsPackages.ement.
Next: Git master, Previous: Nix, Up: Installation [Contents]
Ement.el is also available in some other distributions. See Repology for details.
Next: Manual, Previous: Other distributions, Up: Installation [Contents]
The master
branch of the Git repository is intended to be usable at all times; only minor bugs are expected to be found in it before a new stable release is made.
To install, it is recommended to use quelpa-use-package, like this (using this helpful command for upgrading versions):
;; Install and load `quelpa-use-package'. (package-install 'quelpa-use-package) (require 'quelpa-use-package) ;; Install Ement. (use-package ement :quelpa (ement :fetcher github :repo "alphapapa/ement.el"))
One might also use systems like Elpaca or Straight (which is also used by DOOM), but the author cannot offer support for them.
Previous: Git master, Up: Installation [Contents]
Ement.el is intended to be installed with Emacs’s package system, which will ensure that the required autoloads are generated, etc. If you choose to install it manually, you’re on your own.
Next: Changelog, Previous: Installation, Up: Ement.el [Contents]
ement-connect
to connect. Multiple sessions are supported: call the command again with a C-u
universal prefix to connect to another account.
ement-list-rooms
to view the list of joined rooms.
ement-view-room
to view a room’s buffer, selected with completion.
ement-create-room
to create a new room.
ement-create-space
to create a space.
ement-invite-user
to invite a user to a room.
ement-join-room
to join a room.
ement-leave-room
to leave a room.
ement-forget-room
to forget a room.
ement-tag-room
to toggle a tag on a room (including favorite/low-priority status).
ement-list-members
to list members in a room.
ement-send-direct-message
to send a direct message to a user (in an existing direct room, or creating a new one automatically).
ement-room-edit-message
to edit a message at point.
ement-room-send-file
to send a file.
ement-room-send-image
to send an image.
ement-room-set-topic
to set a room’s topic.
ement-room-occur
to search in a room’s known events.
ement-room-override-name
to override a room’s display name.
ement-ignore-user
to ignore a user (or with interactive prefix, un-ignore).
ement-room-set-message-format
to set a room’s message format buffer-locally.
ement-room-toggle-space
to toggle a room’s membership in a space (a way to group rooms in Matrix).
ement-directory
to view a room directory.
ement-directory-search
to search a room directory.
These bindings are common to all of the following buffer types:
M-g M-r
M-g M-l
M-g M-m
M-g M-n
Next: Room list buffer, Up: Bindings [Contents]
Note that if global minor mode ement-room-self-insert-mode
is enabled (by default it is disabled), typing any of the common printable ascii characters (such as letters) in a room buffer will start a new message, and most of the following bindings are instead accessed via a prefix key. See the minor mode docstring for details. (The ?
binding is an exception; by default it opens the command menu regardless of this minor mode.)
?
Movement
n
p
N
SPC
S-SPC
M-g M-p
m
S-SPC
, M-v
or mwheel-scroll
)
Switching
M-g M-l
M-g M-r
M-g M-m
M-g M-n
q
Messages
RET
M-RET
(while writing in minibuffer: C-c '
). Customize the option ement-room-compose-method
to make RET
and the other message bindings use a compose buffer by default. Use command ement-room-compose-org
to activate Org mode in the compose buffer.
S-<return>
<insert>
C-k
s r
s e
s f
s i
v
C-M-i
(standard completion-at-point
command). (Type an @
prefix for a member mention, a #
prefix for a room alias, or a !
prefix for a room ID.)
Images
mouse-1
double-mouse-1
Users
u RET
u i
u I
Room
M-s o
r m
r t
r f
r n
r N
r T
Room membership
R c
R j
R l
R F
R s
Other
g
Next: Directory buffers, Previous: Room buffers, Up: Bindings [Contents]
RET
SPC
TAB
/ <backtab>
k
s
Next: Mentions/notifications buffers, Previous: Room list buffer, Up: Bindings [Contents]
RET
/ mouse-1
+
Previous: Directory buffers, Up: Bindings [Contents]
TAB
/ <backtab>
RET
S-<return>
Next: Encrypted room support through Pantalaimon, Previous: Bindings, Up: Usage [Contents]
ement-room-send-message-filter
(which enables Org format by default), or by calling ement-room-compose-org
in a compose buffer (which enables it for a single message). Then Org-formatted messages are automatically converted and sent as HTML-formatted messages (with the Org syntax as the plain-text fallback). You can send syntax such as:
:exports both
)
org-export-preserve-breaks
value causes singular line breaks to be exported as spaces. To preserve the line breaks, indentation, and blank lines in a region, but otherwise use normal formatting, you can use the verse
block type. Refer to (info "(org) Paragraphs")
and (info "(org) Structure Templates")
for details.
SPC
repeatedly, you can cycle through and read all rooms with unread buffers. (If a room doesn’t have a buffer, it will not be included.)
@
followed by their displayname or Matrix ID. (Members’ names and rooms’ aliases/IDs may be completed with completion-at-point
commands.)
ement-room-use-variable-pitch
to render messages using proportional fonts.
ement
group.
setq
should not be used for certain options, because it will not call the associated setter function. Users who have an aversion to the customization system may experience problems.
Emacs may not display certain symbols and emojis well by default. Based on this question and answer, you may find that the simplest way to fix this is to install an appropriate font, like Noto Emoji, and then use this Elisp code:
(setf use-default-font-for-symbols nil) (set-fontset-font t 'unicode "Noto Emoji" nil 'append)
Ement.el doesn’t support encrypted rooms natively, but it can be used transparently with the E2EE-aware reverse proxy daemon Pantalaimon. After configuring it according to its documentation, call ement-connect
with the appropriate hostname and port, like:
(ement-connect :uri-prefix "http://localhost:8009")
Next: Development, Previous: Usage, Up: Ement.el [Contents]
Compatibility
Additions
ement-room-images
is disabled (preventing automatic download and display of images), individual images may be shown by clicking the button in their events.
Changes
ement-room-coalesce-events
may now be set to (and defaults to) a maximum number of events to coalesce together. (This avoids potential performance problems in rare cases. See #247. Thanks to Arto Jantunen for reporting and Sergio Durigan Junior for testing.)
Fixes
filter-buffer-substring-function
in room buffers to prevent undesired text properties from being included in copied text. (#278. Thanks to Phil Sainty.)
ement-disconnect
no longer shows an error message. (#208.)
ement-room-mode-hook
and ement-room-self-insert-mode
. (Thanks to Phil Sainty.)
Fixes
ement-directory
list. (See #248. Thanks to Hunter Jozwiak and Bharath Palavalli for reporting.)
cl-type
pcase
form in Emacs versions before 28. (#279. Thanks to Adam Bark for reporting.)
Additions
ement-room-reaction-picker
sets the default picker. Within that, the user may press C-g
to choose a different one with a key bound in ement-room-reaction-map
.
Chiefly, messages can now be composed in small windows below room windows, rather than in the minibuffer or a full-sized window. A variety of options and commands are available related to these features. See compose buffer enhancements.
ement-room-self-insert-mode
enables "just typing" to start a message. (Thanks to Phil Sainty.)See image display.
Changes
dabbrev
will prioritise firstly the associated room, and secondly all other rooms, before looking to other buffers for completions. (Thanks to Phil Sainty.)
ement-room-message-history
rather than the kill-ring. (Thanks to Phil Sainty.)
ement-room-mode-map
now have named labels in which-key
and similar. (Thanks to Phil Sainty.)
ement-room-use-variable-pitch
(previously named ement-room-shr-use-fonts
) enables variable-pitch fonts for all message types. (This option previously supported formatted messages, but now works for plain text messages as well.) Note: users who have customized the ement-room-message-text
face to be variable-pitch should revert that change, as it causes problems for formatted messages, and is no longer necessary. (#174. Thanks to Phil Sainty.)
Fixes
ement-room-message-format-spec
are considered when calculating the wrap-prefix. (Thanks to Phil Sainty.)
ement-room-list-direct
(now correctly bold in room list heading).
Next: ement-room-self-insert-mode
, Up: 0.15 [Contents]
ement-room-compose-buffer-display-action
declares how and where a new compose buffer window should be displayed. (By default, in a new window below the associated room buffer.)
ement-room-compose-buffer-window-dedicated
determines whether compose buffers will have dedicated windows.
ement-room-compose-buffer-window-auto-height
causes dynamic scaling of the compose buffer window height so that the full message is visible at all times.
ement-room-compose-buffer-window-auto-height-min
specifies the minimum window height when ement-room-compose-buffer-window-auto-height
is enabled.
ement-room-compose-buffer-window-auto-height-max
specifies the maximum window height when ement-room-compose-buffer-window-auto-height
is enabled.
ement-room-compose-method
chooses between minibuffer-centric or compose-buffer-centric behaviour.
ement-room-dispatch-new-message
starts writing a new message using your chosen ement-room-compose-method
. (Bound to RET
in room buffers.)
ement-room-dispatch-new-message-alt
starts writing a new message using the alternative method. (Bound to M-RET
in room buffers.)
ement-room-dispatch-edit-message
edits a message using your chosen ement-room-compose-method
. (Bound to <insert>
in room buffers.)
ement-room-dispatch-reply-to-message
replies to a message using your chosen ement-room-compose-method
. (Bound to S-<return>
in room buffers.)
ement-room-compose-edit
edits a message using a compose buffer.
ement-room-compose-reply
replies to a message using a compose buffer.
ement-room-compose-send-direct
sends a message directly from a compose buffer (without the minibuffer). (Bound to C-x C-s
in compose buffers.)
ement-room-compose-abort
kills the compose buffer and delete its window. (Bound to C-c C-k
in compose buffers.)
ement-room-compose-abort-no-history
does the same without adding to ement-room-message-history
. (Equivalent to C-u C-c C-k
.)
ement-room-compose-history-prev-message
cycles backwards through ement-room-message-history
. (Bound to M-p
in compose buffers.)
ement-room-compose-history-next-message
cycles forwards through ement-room-message-history
. (Bound to M-n
in compose buffers.)
ement-room-compose-history-isearch-backward
initiates an isearch through ement-room-message-history
. (Bound to M-r
in compose buffers; continue searching with C-r
or C-s
.)
ement-room-compose-history-isearch-backward-regexp
initiates a regexp isearch through ement-room-message-history
. (Bound to C-M-r
in compose buffers; continue searching with C-r
or C-s
.)
Next: Image display, Previous: Compose buffer enhancements, Up: 0.15 [Contents]
ement-room-self-insert-mode
ement-room-self-insert-commands
determines which commands will start a new message when ement-room-self-insert-mode
is enabled (defaulting to self-insert-command
and yank
).
ement-room-self-insert-chars
determines which typed characters will start a new message when ement-room-self-insert-mode
is enabled (regardless of whether they are bound to self-insert-command
).
ement-room-mode-map-prefix-key
defines a prefix key for accessing the full ement-room-mode-map
when ement-room-self-insert-mode
is enabled. (By default this key is DEL
.)
Previous: ement-room-self-insert-mode
, Up: 0.15 [Contents]
ement-room-image-margin
is the number of pixels of margin around image thumbnails.
ement-room-image-relief
is the number of pixels of shadow rectangle around image thumbnails.
ement-room-image-thumbnail-height
is the window body height multiple to use when toggling full-sized images to thumbnails (by default, 0.2).
ement-room-image-thumbnail-height-min
is the minimum pixel height for thumbnail images (by default, 30 pixels).
Additions
ement-room-list
.
ement-room-list-space-prefix
is applied to space names in the room list (e.g. set to empty string for cleaner appearance).
ement-room-reaction-names-limit
sets how many senders of a reaction are shown in the buffer (more than that many are shown in the tooltip).
Changes
TAB
/ BACKTAB
to move between links in room and like buffers. (#113. Thanks to Eric S. Fraga for suggesting.)
Fixes
ement-room-send-reaction
checks for an event at point. (Thanks to Phil Sainty.)
Additions
end-of-buffer
is bound to N
in room buffers.
Changes
ement-room-image-show
use frame parameters to maximize the frame, making it easier for users to override. (#223. Thanks to Nicholas Vollmer.)
Fixes
ement-room-flush-colors
maintains point position.
Additions
ement-notifications
shows recent notifications, similar to the pane in the Element client. (This new command fetches recent notifications from the server and allows scrolling up to retrieve older ones. Newly received notifications, as configured in the ement-notify
options, are displayed in the same buffer. This functionality will be consolidated in the future.)
ement-room-quote
, applied to quoted parts of replies.
Changes
ement-room-goto-next
and ement-room-goto-prev
work more usefully at the end of a room buffer. (Now pressing n
on the last event moves point to the end of the buffer so it will scroll automatically for new messages, and then pressing p
skips over any read marker to the last event.)
ement-room-goto-next
and ement-room-goto-prev
are bound to n
and p
, respectively.
ement-room-goto-fully-read-marker
is bound to M-g M-p
(the mnemonic being "go to previously read").
ement-room
buffers and ement-connect
user ID prompts use separate history list variables.
Fixes
savehist-mode
’s serializing of the command-history
variable’s arguments. (For ement-
commands, that may include large data structures, like ement-session
structs, which should never be serialized or reused, and savehist
’s doing so could cause noticeable delays for users who enabled it). (See #216. Thanks to Phil Sainty and other users who helped to discover this problem.)
Additions
ement-room-image-show
and ement-room-image-scale
(bound to RET
and M-RET
when point is at an image) view and scale images. (Thanks to Steven Allen for these and other image-related improvements.)
ement-room-image-show-mouse
is used to show an image with the mouse.
Changes
image-mode
when showing images in a new buffer. (Thanks to Steven Allen.)
ement-room-image-show
is not used for mouse events.
Fixes
ement-room-list-next-unread
could enter an infinite loop. (Thanks to Visuwesh and @mrtnmrtn:matrix.org
.)
Internal
ement-read-receipt-idle-timer
could be duplicated when using multiple sessions. (#196. Thanks to Phil Sainty.)
Security Fixes
.gpg
), if the recipient’s private key or the symmetric encryption key were cached by Emacs (or a configured agent, like gpg-agent
), Emacs would automatically decrypt the file while reading its contents and then upload the decrypted contents. (This happened because the function insert-file-contents
was used, which does many things automatically, some of which are not even mentioned in its docstring; refer to its entry in the Elisp Info manual for details. The fix is to use insert-file-contents-literally
instead.) Thanks to @welkinsl:matrix.org
for reporting.
Additions
m
in room buffers to ement-room-mark-read
(which moves read markers to point).
Changes
ement-view-space
(which shows a directory of rooms in the space) instead of ement-view-room
(which shows events in the space, which is generally not useful).
ement-view-room
, when used for a space, shows a footer explaining that the buffer is showing a space rather than a normal room, with a button to call ement-view-space
for it (which lists rooms in the space).
ement-describe-room
shows whether a room is a space or a normal room.
ement-view-space
shows the space’s name and alias.
ement-room-scroll-up-mark-read
moves the fully read marker to the top of the window (when the marker’s position is within the range of known events), rather than only moving it when at the end of the buffer. (This eases the process of gradually reading a long backlog of messages.)
Fixes
ement-room-list-mode
when room list buffer is refreshed. (#146. Thanks to Ted Reed for reporting.)
@welkinsl:matrix.org
for reporting.
Fixes
ement-room-list-next-unread
.
Fixes
Fixes
ement-room-list
command upon initial sync.
Additions
ement-room-timestamp-header-align
controls how timestamp headers are aligned in room buffers.
ement-room-view-hook
runs functions when ement-room-view
is called. (By default, it refreshes the room list buffer.)
Changes
ement-room-timestamp-header-align
, timestamp headers default to right-aligned. (With default settings, this keeps them near message timestamps and makes for a cleaner appearance.)
Fixes
ement-room-list
when no rooms are joined. (Fixes #123. Thanks to @Kabouik and Omar Antolín Camarena for reporting.)
Fixes
pcase
’s (map :KEYWORD)
form. (This can cause a broken installation on older versions of Emacs that have an older version of the map
library loaded, such as Emacs 27.2 included in Debian 11. Since there’s no way to force Emacs to actually load the version of map
required by this package before installing it (which would naturally happen upon restarting Emacs), we can only avoid using such forms while these versions of Emacs are widely used.)
Fixes
Added missing changelog entry (of course).
Additions
ement-create-space
creates a new space.
ement-room-toggle-space
toggles a room’s membership in a space (a way to group rooms in Matrix).
ement-room-list-kill-buffer
kills a room’s buffer from the room list.
device_id
and initial_device_display_name
upon login (e.g. ‘Ement.el: username@hostname’). (#134. Thanks to Arto Jantunen for reporting.)
Changes
ement-room-list
reuses an existing window showing the room list when possible. (#131. Thanks to Jeff Bowman for suggesting.)
ement-tag-room
toggles tags (rather than adding by default and removing when called with a prefix).
Fixes
ement-leave-room
and ement-forget-room
.
Additions
ement-room-override-name
sets a local override for a room’s display name. (Especially helpful for 1:1 rooms and bridged rooms. See MSC3015.)
Changes
ement-leave-room
and ement-forget-room
commands.
Fixes
ement-view-space
when called from a room buffer. (Thanks to Richard Brežák for reporting.)
display-buffer
when reverting room list buffer. (Fixes #121. Thanks to mekeor for reporting.)
Internal
ement-put-account-data
accepts :room
argument to put on a room’s account data.
Additions
ement-view-space
to view a space’s rooms in a directory buffer.
Changes
ement-describe-room
command (formatting, bindings).
Fixes
Fixes
ement-initial-sync-timeout
properly (important for when the homeserver is slow to respond).
Fixes
ement-directory
commands.
ement-directory
listings.
Additions
Changes
ement-room-list
. (The old, tabulated-list-mode
-based room list is available as ement-tabulated-room-list
.)
Fixes
Fixes
Additions
ement-room-unread-only-counts-notifications
, now enabled by default, causes rooms’ unread status to be determined only by their notification counts (which are set by the server and depend on rooms’ notification settings).
ement-room-set-notification-state
sets a room’s notification state (imitating Element’s user-friendly presets).
ement-set-display-name
sets the user’s global displayname.
ement-room-set-display-name
sets the user’s displayname in a room (which is also now displayed in the room’s Transient menu).
Notifications
in the ement-taxy-room-list
buffer shows rooms’ notification state.
ement-interrupted-sync-hook
allows customization of how sync interruptions are handled. (Now, by default, a warning is displayed instead of merely a message.)
Changes
Fixes
ement-forget-room
in room buffers.
@room
mentions.
Fixes
Additions
ement-directory
shows a server’s room directory.
ement-directory-search
searches a server’s room directory.
ement-directory-next
fetches the next batch of rooms in a directory.
ement-leave-room
accepts a FORCE-P
argument (interactively, with prefix) to leave a room without prompting.
ement-forget-room
accepts a FORCE-P
argument (interactively, with prefix) to also leave the room, and to forget it without prompting.
ement-notify-mark-frame-urgent-predicates
marks the frame as urgent when (by default) a message mentions the local user or "@room" and the message’s room has an open buffer.
Changes
Fixes
ement-describe-room
for rooms without topics.
Changes
window-scroll-functions
, which sometimes caused a strange race condition that could cause Emacs to become unresponsive or crash.)
ement-taxy-room-list
view no longer automatically refreshes the list if the region is active in the buffer. (This allows the user to operate on multiple rooms without the contents of the buffer changing before completing the process.)
Fixes
Fixed
Fixed
ement-room-sync
correctly updates room-list buffers. (Thanks to Visuwesh.)
Fixed
ement-room-scroll-up-mark-read
selects the correct room window.
ement-room-list-avatars
defaults to what function display-images-p
returns.
Bug reports, feature requests, suggestions — oh my!
Next: Matrix spec in Org format, Up: Development [Contents]
Ement.el is published in GNU ELPA and is considered part of GNU Emacs. Therefore, cumulative contributions of more than 15 lines of code require that the author assign copyright of such contributions to the FSF. Authors who are interested in doing so may contact assign@gnu.org to request the appropriate form.
Next: Rationale, Previous: Copyright Assignment, Up: Development [Contents]
An Org-formatted version of the Matrix spec is available in the meta/spec branch.
Previous: Matrix spec in Org format, Up: Development [Contents]
This section is preserved for posterity. As it says, Ement.el has long since surpassed matrix-client
, which should no longer be used.
Why write a new Emacs Matrix client when there is already matrix-client.el, by the same author, no less? A few reasons:
matrix-client
uses an older version of the Matrix spec, r0.3.0, with a few elements of r0.4.0 grafted in. Bringing it up to date with the current version of the spec, r0.6.1, would be more work than to begin with the current version. Ement.el targets r0.6.1 from the beginning.
matrix-client
does not use Matrix’s lazy-loading feature (which was added to the specification later), so initial sync requests can take a long time for the server to process and can be large (sometimes tens of megabytes of JSON for the client to process!). Ement.el uses lazy-loading, which significantly improves performance.
matrix-client
automatically makes buffers for every room a user has joined, even if the user doesn’t currently want to watch a room. Ement.el opens room buffers on-demand, improving performance by not having to insert events into buffers for rooms the user isn’t watching.
matrix-client
was developed without the intention of publishing it to, e.g. MELPA or ELPA. It has several dependencies, and its code does not always install or compile cleanly due to macro-expansion issues (apparently depending on the user’s Emacs config). Ement.el is designed to have minimal dependencies outside of Emacs (currently only one, plz
, which could be imported into the project), and every file is linted and compiles cleanly using makem.sh.
matrix-client
uses EIEIO, probably unnecessarily, since few, if any, of the benefits of EIEIO are realized in it. Ement.el uses structs instead.
matrix-client
uses bespoke code for inserting messages into buffers, which works pretty well, but has a few minor bugs which are difficult to track down. Ement.el uses Emacs’s built-in (and perhaps little-known) ewoc
library, which makes it much simpler and more reliable to insert and update messages in buffers, and enables the development of advanced UI features more easily.
matrix-client
was, to a certain extent, designed to imitate other messaging apps. The result is, at least when used with the matrix-client-frame
command, fairly pleasing to use, but isn’t especially "Emacsy." Ement.el is intended to better fit into Emacs’s paradigms.
matrix-client
’s long name makes for long symbol names, which makes for tedious, verbose code. ement
is easy to type and makes for concise, readable code.
matrix-client
and hopes to write simpler, more readable, more maintainable code in Ement.el. It’s hoped that this will enable others to contribute more easily.
Note that, while matrix-client
remains usable, and probably will for some time to come, Ement.el has now surpassed it in every way. The only reason to choose matrix-client
instead is if one is using an older version of Emacs that isn’t supported by Ement.el.