Add: Emacs bookmark support

Room buffers and the room list buffer can be bookmarked.

Especially useful with Burly: <https://github.com/alphapapa/burly.el>.
This commit is contained in:
Adam Porter 2021-07-25 20:31:41 -05:00
parent 7c589b7b72
commit c5e83b76d7
3 changed files with 58 additions and 0 deletions

View file

@ -116,6 +116,7 @@ In a room buffer:
+ You can customize settings in the ~ement~ group.
- Set ~ement-auto-sync~ to sync new messages automatically.
+ Room buffers and the room-list buffer can be bookmarked in Emacs, i.e. using =C-x r m=. This is especially useful with [[https://github.com/alphapapa/burly.el][Burly]]: you can arrange an Emacs frame with several room buffers displayed at once, use =burly-bookmark-windows= to bookmark the layout, and then you can restore that layout and all of the room buffers by opening the bookmark, rather than having to manually arrange them every time you start Emacs or change the window configuration.
*** Displaying symbols and emojis

View file

@ -56,6 +56,30 @@
;;;; Customization
;;;; Bookmark support
;; Especially useful with Burly: <https://github.com/alphapapa/burly.el>
(require 'bookmark)
(defun ement-room-list-bookmark-make-record ()
"Return a bookmark record for the `ement-room-list' buffer."
(pcase-let* (((cl-struct ement-session user) ement-session)
((cl-struct ement-user (id session-id)) user))
;; MAYBE: Support bookmarking specific events in a room.
(list (concat "Ement room list (" session-id ")")
(cons 'session-id session-id)
(cons 'handler #'ement-room-list-bookmark-handler))))
(defun ement-room-list-bookmark-handler (bookmark)
"Show Ement room list buffer for BOOKMARK."
(pcase-let* (((map session-id) bookmark))
(unless (cl-loop for session in ement-sessions
thereis (equal session-id (ement-user-id (ement-session-user session))))
;; MAYBE: Automatically connect.
(user-error "Session %s not connected: call `ement-connect' first" session-id))
;; FIXME: Support multiple sessions.
(ement-room-list)))
;;;; Commands
@ -67,6 +91,7 @@ call `pop-to-buffer'."
(interactive)
(with-current-buffer (get-buffer-create "*Ement Rooms*")
(ement-room-list-mode)
(setq-local bookmark-make-record-function #'ement-room-list-bookmark-make-record)
;; FIXME: There must be a better way to handle this.
(funcall (if current-prefix-arg
#'pop-to-buffer #'pop-to-buffer-same-window)

View file

@ -299,6 +299,37 @@ See Info node `(elisp)Specified Space'."
"Show timestamp header where events are at least this many seconds apart."
:type 'integer)
;;;; Bookmark support
;; Especially useful with Burly: <https://github.com/alphapapa/burly.el>
(require 'bookmark)
(defun ement-room-bookmark-make-record ()
"Return a bookmark record for the current `ement-room' buffer."
(pcase-let* (((cl-struct ement-room (id room-id) canonical-alias display-name) ement-room)
((cl-struct ement-session user) ement-session)
((cl-struct ement-user (id session-id)) user))
;; MAYBE: Support bookmarking specific events in a room.
(list (concat "Ement room: " display-name " (" canonical-alias ")")
(cons 'session-id session-id)
(cons 'room-id room-id)
(cons 'handler #'ement-room-bookmark-handler))))
(defun ement-room-bookmark-handler (bookmark)
"Show Ement room buffer for BOOKMARK."
(pcase-let* ((`(,_name . ,(map session-id room-id)) bookmark))
(unless (cl-loop for session in ement-sessions
thereis (equal session-id (ement-user-id (ement-session-user session))))
;; MAYBE: Automatically connect.
(user-error "Session %s not connected: call `ement-connect' first" session-id))
;; FIXME: Support multiple sessions.
(let ((room (cl-loop for room in (ement-session-rooms (car ement-sessions))
when (equal room-id (ement-room-id room))
return room)))
(cl-assert room)
(ement-view-room (car ement-sessions) room))))
;;;; Commands
(defun ement-room-goto-prev (num)
@ -581,6 +612,7 @@ data slot."
(lambda ()
(setf (map-elt (ement-room-local ement-room) 'buffer) nil))
nil 'local)
(setq-local bookmark-make-record-function #'ement-room-bookmark-make-record)
;; TODO: Some code is duplicated here and in `ement--update-room-buffers'.
;; Move new events to the main timeline slot first, because some events can
;; refer to other events, and we want them to be found in the timeline slot.