Skip to content

Commit

Permalink
Fix: Writing reply from compose buffer from minibuffer
Browse files Browse the repository at this point in the history
Fixes #189.

Reported-by: Phil Sainty <phil@catalyst.net.nz>
  • Loading branch information
alphapapa committed Sep 24, 2023
1 parent 01ec34b commit 351aea8
Showing 1 changed file with 46 additions and 35 deletions.
81 changes: 46 additions & 35 deletions ement-room.el
Expand Up @@ -97,6 +97,10 @@ to sort events and update other slots."
"Non-nil when earlier messages are being loaded.
Used to avoid overlapping requests.")

(defvar-local ement-room-editing-event nil
"When non-nil, the user is editing this event.
Used by `ement-room-send-message'.")

(defvar-local ement-room-replying-to-event nil
"When non-nil, the user is replying to this event.
Used by `ement-room-send-message'.")
Expand Down Expand Up @@ -706,14 +710,13 @@ number (to darken rather than lighten)."
(declare (indent 1))
`(let* ((node (ewoc-locate ement-ewoc ,position))
(event (ewoc-data node))
ement-room-replying-to-event ement-room-replying-to-overlay)
ement-room-replying-to-overlay)
(unless (and (ement-event-p event)
(ement-event-id event))
(error "No event at point"))
(unwind-protect
(progn
(setf ement-room-replying-to-event event
ement-room-replying-to-overlay
(setf ement-room-replying-to-overlay
(make-overlay (ewoc-location node)
;; NOTE: It doesn't seem possible to get the end position of
;; a node, so if there is no next node, we use point-max.
Expand All @@ -725,8 +728,7 @@ number (to darken rather than lighten)."
,@body)
(when (overlayp ement-room-replying-to-overlay)
(delete-overlay ement-room-replying-to-overlay))
(setf ement-room-replying-to-event nil
ement-room-replying-to-overlay nil))))
(setf ement-room-replying-to-overlay nil))))

(defmacro ement-room-with-typing (&rest body)
"Send typing notifications around BODY.
Expand Down Expand Up @@ -1702,7 +1704,8 @@ The message must be one sent by the local user."
((cl-struct ement-session user events) ement-session)
((cl-struct ement-event sender id
(content (map body ('m.relates_to relates-to))))
event))
event)
(ement-room-editing-event event))
(unless (equal (ement-user-id sender) (ement-user-id user))
(user-error "You may only edit your own messages"))
(when relates-to
Expand Down Expand Up @@ -1748,23 +1751,24 @@ The message must be one sent by the local user."
(user-error "Message not deleted"))))
(ement-redact event room session reason))

(defun ement-room-write-reply ()
"Send a reply to event at point."
(interactive)
(defun ement-room-write-reply (event)
"Write and send a reply to EVENT.
Interactively, to event at point."
(interactive (list (ewoc-data (ewoc-locate ement-ewoc))))
(cl-assert ement-ewoc) (cl-assert ement-room) (cl-assert ement-session)
(cl-assert (ement-event-p (ewoc-data (ewoc-locate ement-ewoc))))
(ement-room-with-highlighted-event-at (point)
(pcase-let* ((event (ewoc-data (ewoc-locate ement-ewoc)))
(room ement-room)
(session ement-session)
(prompt (format "Send reply (%s): " (ement-room-display-name room)))
(ement-room-read-string-setup-hook
(lambda ()
(setq-local ement-room-replying-to-event event)))
(body (ement-room-with-typing
(ement-room-read-string prompt nil 'ement-room-message-history
nil 'inherit-input-method))))
(ement-room-send-message room session :body body :replying-to-event event))))
(cl-assert (ement-event-p event))
(let ((ement-room-replying-to-event event))
(ement-room-with-highlighted-event-at (point)
(pcase-let* ((room ement-room)
(session ement-session)
(prompt (format "Send reply (%s): " (ement-room-display-name room)))
(ement-room-read-string-setup-hook
(lambda ()
(setq-local ement-room-replying-to-event event)))
(body (ement-room-with-typing
(ement-room-read-string prompt nil 'ement-room-message-history
nil 'inherit-input-method))))
(ement-room-send-message room session :body body :replying-to-event event)))))

(defun ement-room-send-reaction (key position)
"Send reaction of KEY to event at POSITION.
Expand Down Expand Up @@ -3676,6 +3680,7 @@ To be called from a minibuffer opened from
(input-method current-input-method) ; Capture this value from the minibuffer.
(send-message-filter ement-room-send-message-filter)
(replying-to-event ement-room-replying-to-event)
(editing-event ement-room-editing-event)
(compose-fn (lambda ()
;; HACK: Since exiting the minibuffer restores the previous window configuration,
;; we have to do some magic to get the new compose buffer to appear.
Expand All @@ -3685,13 +3690,16 @@ To be called from a minibuffer opened from
(ement-room-compose-message ement-room ement-session :body body)
;; FIXME: This doesn't propagate the send-message-filter to the minibuffer.
(setf ement-room-send-message-filter send-message-filter)
(setq-local ement-room-replying-to-event replying-to-event)
(when replying-to-event
(setq-local header-line-format
(concat header-line-format
(format " (Replying to message from %s)"
(ement--user-displayname-in
ement-room (ement-event-sender replying-to-event))))))
(setq-local ement-room-replying-to-event replying-to-event
ement-room-editing-event editing-event)
(cond (replying-to-event
(setq-local header-line-format
(concat header-line-format
(format " (Replying to message from %s)"
(ement--user-displayname-in
ement-room (ement-event-sender replying-to-event))))))
(editing-event
(setq-local header-line-format (concat header-line-format " (Editing message)"))))
(let* ((compose-buffer (current-buffer))
(show-buffer-fn-symbol (gensym "ement-show-compose-buffer"))
(show-buffer-fn (lambda ()
Expand Down Expand Up @@ -3721,23 +3729,26 @@ To be called from an `ement-room-compose' buffer."
(session ement-session)
(input-method current-input-method)
(send-message-filter ement-room-send-message-filter)
(replying-to-event ement-room-replying-to-event))
(replying-to-event ement-room-replying-to-event)
(editing-event ement-room-editing-event))
(quit-restore-window nil 'kill)
(ement-view-room room session)
(let* ((prompt (format "Send message (%s): " (ement-room-display-name ement-room)))
(current-input-method input-method) ; Bind around read-string call.
(ement-room-send-message-filter send-message-filter)
(pos (when replying-to-event
(pos (when (or editing-event replying-to-event)
(ewoc-location (ement-room--ewoc-last-matching ement-ewoc
(lambda (data)
(eq data replying-to-event))))))
(body (if replying-to-event
(eq data (or editing-event replying-to-event)))))))
(body (if (or editing-event replying-to-event)
(ement-room-with-highlighted-event-at pos
(ement-room-read-string prompt (car kill-ring) 'ement-room-message-history
nil 'inherit-input-method))
(ement-room-read-string prompt (car kill-ring) 'ement-room-message-history
nil 'inherit-input-method)) ))
(ement-room-send-message ement-room ement-session :body body :replying-to-event replying-to-event))))
nil 'inherit-input-method))))
(if editing-event
(ement-room-edit-message editing-event ement-room ement-session body)
(ement-room-send-message ement-room ement-session :body body :replying-to-event replying-to-event)))))

(defun ement-room-init-compose-buffer (room session)
"Eval BODY, setting up the current buffer as a compose buffer.
Expand Down

0 comments on commit 351aea8

Please sign in to comment.