diff --git a/README.org b/README.org index ec7fc9c4..8b24afc0 100644 --- a/README.org +++ b/README.org @@ -302,6 +302,12 @@ Note that, while ~matrix-client~ remains usable, and probably will for some time + Improve readme export settings. +** 0.9.3 + +*Fixes* ++ Another attempt at restoring position in room list when refreshing. ++ Command ~ement-room-list-next-unread~. + ** 0.9.2 *Fixes* diff --git a/ement-room-list.el b/ement-room-list.el index 49a8d9dd..6dad2354 100644 --- a/ement-room-list.el +++ b/ement-room-list.el @@ -547,8 +547,8 @@ After showing it, its window is selected. The buffer is named BUFFER-NAME and is shown with DISPLAY-BUFFER-ACTION; or if DISPLAY-BUFFER-ACTION is nil, the buffer is not displayed." (interactive) - (let ((inhibit-read-only t) - pos format-table column-sizes window-start room-session-vectors) + (let ((window-start 0) (window-point 0) + format-table column-sizes) (cl-labels (;; (heading-face ;; (depth) (list :inherit (list 'bufler-group (bufler-level-face depth)))) (format-item (item) (gethash item format-table)) @@ -616,18 +616,16 @@ DISPLAY-BUFFER-ACTION is nil, the buffer is not displayed." ;; (kill-buffer buffer-name)) (unless ement-sessions (error "Ement: Not connected. Use `ement-connect' to connect")) - (setf room-session-vectors - (cl-loop for (_id . session) in ement-sessions - append (cl-loop for room in (ement-session-rooms session) - collect (vector room session)))) - (with-current-buffer (get-buffer-create buffer-name) - (setf pos (point)) - (ement-room-list-mode) - (delete-all-overlays) - (erase-buffer) - (if (not room-session-vectors) - (insert "No joined rooms. Use command `ement-join-room' to join a room, or `ement-directory' or `ement-directory-search' to find rooms.") - (let* ((taxy (cl-macrolet ((first-item + (if (not (cl-loop for (_id . session) in ement-sessions + thereis (ement-session-rooms session))) + (ement-message "No rooms have been joined") + (with-current-buffer (get-buffer-create buffer-name) + (ement-room-list-mode) + (let* ((room-session-vectors + (cl-loop for (_id . session) in ement-sessions + append (cl-loop for room in (ement-session-rooms session) + collect (vector room session)))) + (taxy (cl-macrolet ((first-item (pred) `(lambda (taxy) (when (taxy-items taxy) (,pred (car (taxy-items taxy)))))) @@ -659,35 +657,51 @@ DISPLAY-BUFFER-ACTION is nil, the buffer is not displayed." (taxy-sort* #'t>nil (name= "Low-priority")) (taxy-sort* #'t>nil (first-item item-left-p))))) (taxy-magit-section-insert-indent-items nil) + (inhibit-read-only t) (format-cons (taxy-magit-section-format-items ement-room-list-columns ement-room-list-column-formatters taxy)) + (pos (point)) (section-ident (when (magit-current-section) (magit-section-ident (magit-current-section))))) (setf format-table (car format-cons) column-sizes (cdr format-cons) header-line-format (taxy-magit-section-format-header - column-sizes ement-room-list-column-formatters) - window-start (if (get-buffer-window buffer-name) - (window-start (get-buffer-window buffer-name)) - 0)) + column-sizes ement-room-list-column-formatters)) + (when-let ((window (get-buffer-window (current-buffer)))) + (setf window-point (window-point window) + window-start (window-start window))) (when ement-room-list-visibility-cache (setf magit-section-visibility-cache ement-room-list-visibility-cache)) (add-hook 'kill-buffer-hook #'ement-room-list--cache-visibility nil 'local) + ;; Before this point, no changes have been made to the buffer's contents. + (delete-all-overlays) + (erase-buffer) (save-excursion (taxy-magit-section-insert taxy :items 'first ;; :blank-between-depth bufler-taxy-blank-between-depth :initial-depth 0)) - (goto-char pos) - (when (and section-ident (magit-get-section section-ident)) - (goto-char (oref (magit-get-section section-ident) start)))))) - (when display-buffer-action - (when-let ((window (display-buffer buffer-name display-buffer-action))) - (select-window window))) - (when (get-buffer-window buffer-name) - (set-window-start (get-buffer-window buffer-name) window-start)) - ;; NOTE: In order for `bookmark--jump-via' to work properly, the restored buffer - ;; must be set as the current buffer, so we have to do this explicitly here. - (set-buffer buffer-name)))) + (if-let* ((section-ident) + (section (magit-get-section section-ident))) + (goto-char (oref section start)) + (goto-char pos)))) + (when display-buffer-action + (when-let ((window (display-buffer buffer-name display-buffer-action))) + (select-window window))) + (when-let ((window (get-buffer-window buffer-name))) + (set-window-start window window-start) + (set-window-point window window-point)) + ;; FIXME: Despite all this code to save and restore point and window point and + ;; window start, when I send a message from the minibuffer, or when I abort + ;; sending a message from the minibuffer, point is moved to the beginning of the + ;; buffer. While the minibuffer is open (and the typing messages are being sent + ;; to the server, causing it to repeatedly sync), the point stays in the correct + ;; place. I can't find any reason why this happens. It makes no sense. And + ;; while trying to debug the problem, somehow Emacs got put into an unbreakable, + ;; infinite loop twice; even C-g and SIGUSR2 didn't stop it. + + ;; NOTE: In order for `bookmark--jump-via' to work properly, the restored buffer + ;; must be set as the current buffer, so we have to do this explicitly here. + (set-buffer buffer-name))))) (cl-defun ement-room-list-side-window (&key (side 'left)) "Show room list in side window on SIDE. @@ -739,19 +753,17 @@ left." (defun ement-room-list-next-unread () "Show next unread room." (interactive) - (unless (button-at (point)) - (call-interactively #'forward-button)) + (when (eobp) + (goto-char (point-min))) (unless (cl-loop with starting-line = (line-number-at-pos) for value = (oref (magit-current-section) value) - for room = (elt value 0) - for session = (elt value 1) - if (ement--room-unread-p room session) + if (and (vectorp value) + (ement--room-unread-p (elt value 0) (elt value 1))) do (progn - (goto-char (button-end (button-at (point)))) - (push-button (1- (point))) + (ement-view-room (elt value 0) (elt value 1)) (ement-room-goto-fully-read-marker) (cl-return t)) - else do (call-interactively #'forward-button) + else do (forward-line 1) while (> (line-number-at-pos) starting-line)) ;; No more unread rooms. (message "No more unread rooms")))