Multiple buffer support and standardised window and buffer handling
This commit is contained in:
@ -724,9 +724,7 @@ docid is not found."
|
||||
|
||||
(defun mu4e~headers-view-this-message-p (docid)
|
||||
"Is DOCID currently being viewed?"
|
||||
(when (buffer-live-p (mu4e-get-view-buffer))
|
||||
(with-current-buffer (mu4e-get-view-buffer)
|
||||
(eq docid (plist-get mu4e~view-message :docid)))))
|
||||
(mu4e-get-view-buffers (lambda (buf) (eq docid (plist-get mu4e~view-message :docid)))))
|
||||
|
||||
;; note: this function is very performance-sensitive
|
||||
(defun mu4e~headers-append-handler (msglst)
|
||||
@ -808,10 +806,10 @@ present, don't do anything."
|
||||
;; if we were viewing this message, close it now.
|
||||
(when (and (mu4e~headers-view-this-message-p docid)
|
||||
(buffer-live-p (mu4e-get-view-buffer)))
|
||||
(unless (eq mu4e-split-view 'single-window)
|
||||
(let ((buf (mu4e-get-view-buffer)))
|
||||
(mapc #'delete-window (get-buffer-window-list
|
||||
(mu4e-get-view-buffer) nil t)))
|
||||
(kill-buffer (mu4e-get-view-buffer))))
|
||||
buf nil t))
|
||||
(kill-buffer buf))))
|
||||
|
||||
|
||||
|
||||
@ -825,7 +823,7 @@ present, don't do anything."
|
||||
|
||||
Switch to the output buffer for the results. If IGNORE-HISTORY is
|
||||
true, do *not* update the query history stack."
|
||||
(let* ((buf (get-buffer-create mu4e-headers-buffer-name))
|
||||
(let* ((buf (mu4e-get-headers-buffer nil t))
|
||||
(inhibit-read-only t)
|
||||
(rewritten-expr (funcall mu4e-query-rewrite-function expr))
|
||||
(maxnum (unless mu4e-search-full mu4e-search-results-limit)))
|
||||
@ -842,7 +840,7 @@ true, do *not* update the query history stack."
|
||||
;; when the buffer is already visible, select it; otherwise,
|
||||
;; switch to it.
|
||||
(unless (get-buffer-window buf 0)
|
||||
(switch-to-buffer buf))
|
||||
(mu4e-display-buffer buf t))
|
||||
(run-hook-with-args 'mu4e-search-hook expr)
|
||||
(mu4e~headers-clear mu4e~search-message)
|
||||
(setq mu4e~headers-search-start (float-time))
|
||||
@ -1155,7 +1153,8 @@ no user-interaction ongoing."
|
||||
(when (and mu4e-headers-auto-update ;; must be set
|
||||
mu4e-index-update-status
|
||||
(not (zerop (plist-get mu4e-index-update-status :updated)))
|
||||
(zerop (mu4e-mark-marks-num)) ;; non active marks
|
||||
;; NOTE: `mu4e-mark-marks-num' can return nil. Is that intended?
|
||||
(zerop (or (mu4e-mark-marks-num) 0)) ;; non active marks
|
||||
(not (active-minibuffer-window))) ;; no user input only
|
||||
;; rerun search if there's a live window with search results;
|
||||
;; otherwise we'd trigger a headers view from out of nowhere.
|
||||
@ -1329,32 +1328,6 @@ message plist, or nil if not found."
|
||||
""))))))
|
||||
|
||||
|
||||
(defun mu4e~headers-redraw-get-view-window ()
|
||||
"Close all windows, redraw the headers buffer based on the value
|
||||
of `mu4e-split-view', and return a window for the message view."
|
||||
(if (eq mu4e-split-view 'single-window)
|
||||
(or (and (buffer-live-p (mu4e-get-view-buffer))
|
||||
(get-buffer-window (mu4e-get-view-buffer)))
|
||||
(selected-window))
|
||||
(mu4e-hide-other-mu4e-buffers)
|
||||
(unless (buffer-live-p (mu4e-get-headers-buffer))
|
||||
(mu4e-error "No headers buffer available"))
|
||||
(switch-to-buffer (mu4e-get-headers-buffer))
|
||||
;; kill the existing view buffer
|
||||
(when (buffer-live-p (mu4e-get-view-buffer))
|
||||
(kill-buffer (mu4e-get-view-buffer)))
|
||||
;; get a new view window
|
||||
(setq mu4e~headers-view-win
|
||||
(with-demoted-errors "Unable to split window: %S"
|
||||
(cond
|
||||
((eq mu4e-split-view 'horizontal) ;; split horizontally
|
||||
(split-window-vertically mu4e-headers-visible-lines))
|
||||
((eq mu4e-split-view 'vertical) ;; split vertically
|
||||
(split-window-horizontally mu4e-headers-visible-columns))
|
||||
((functionp mu4e-split-view)
|
||||
(funcall mu4e-split-view))
|
||||
(t ;; no splitting; just use the currently selected one
|
||||
(selected-window)))))))
|
||||
|
||||
;;; Search-based marking
|
||||
|
||||
@ -1623,41 +1596,21 @@ _not_ refresh the last search with the new setting for threading."
|
||||
(mu4e~headers-toggle "Skip-duplicates"
|
||||
'mu4e-headers-skip-duplicates dont-refresh))
|
||||
|
||||
(defvar mu4e~headers-loading-buf nil
|
||||
"A buffer for loading a message view.")
|
||||
|
||||
(defun mu4e-headers-view-message ()
|
||||
"View message at point .
|
||||
If there's an existing window for the view, re-use that one . If
|
||||
not, create a new one, depending on the value of
|
||||
`mu4e-split-view': if it's a symbol `horizontal' or `vertical',
|
||||
split the window accordingly; if it is nil, replace the current
|
||||
window . "
|
||||
"View message at point."
|
||||
(interactive)
|
||||
(unless (eq major-mode 'mu4e-headers-mode)
|
||||
(mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
|
||||
(let* ((msg (mu4e-message-at-point))
|
||||
(path (mu4e-message-field msg :path))
|
||||
(_exists (or (file-readable-p path)
|
||||
(mu4e-warn "No message at %s" path)))
|
||||
(mu4e-warn "No message at %s" path)))
|
||||
(docid (or (mu4e-message-field msg :docid)
|
||||
(mu4e-warn "No message at point")))
|
||||
(mark-as-read
|
||||
(if (functionp mu4e-view-auto-mark-as-read)
|
||||
(funcall mu4e-view-auto-mark-as-read msg)
|
||||
mu4e-view-auto-mark-as-read))
|
||||
(viewwin (mu4e~headers-redraw-get-view-window)))
|
||||
(unless (window-live-p viewwin)
|
||||
(mu4e-error "Cannot get a message view"))
|
||||
(select-window viewwin)
|
||||
|
||||
;; show some 'loading...' buffer
|
||||
(unless (buffer-live-p mu4e~headers-loading-buf)
|
||||
(setq mu4e~headers-loading-buf (get-buffer-create " *mu4e-loading*"))
|
||||
(with-current-buffer mu4e~headers-loading-buf
|
||||
(mu4e-loading-mode)))
|
||||
|
||||
(switch-to-buffer mu4e~headers-loading-buf)
|
||||
mu4e-view-auto-mark-as-read)))
|
||||
(mu4e--server-view docid mark-as-read)))
|
||||
|
||||
|
||||
@ -1688,15 +1641,15 @@ return nil."
|
||||
;; update all windows showing the headers buffer
|
||||
(walk-windows
|
||||
(lambda (win)
|
||||
(when (eq (window-buffer win) (mu4e-get-headers-buffer))
|
||||
(when (eq (window-buffer win) (mu4e-get-headers-buffer (buffer-name)))
|
||||
(set-window-point win (point))))
|
||||
nil t)
|
||||
(if (eq mu4e-split-view 'single-window)
|
||||
(when (eq (window-buffer) (mu4e-get-view-buffer))
|
||||
(mu4e-headers-view-message))
|
||||
;; update message view if it was already showing
|
||||
(when (and mu4e-split-view (window-live-p mu4e~headers-view-win))
|
||||
(mu4e-headers-view-message)))
|
||||
;; If the assigned (and buffer-local) `mu4e~headers-view-win'
|
||||
;; is not live then that is indicates the user does not want
|
||||
;; to pop up the view when they navigate in the headers
|
||||
;; buffer.
|
||||
(when (window-live-p mu4e~headers-view-win)
|
||||
(mu4e-headers-view-message))
|
||||
;; attempt to highlight the new line, display the message
|
||||
(mu4e~headers-highlight docid)
|
||||
(if succeeded
|
||||
@ -1807,42 +1760,19 @@ region if there is a region, then move to the next message."
|
||||
This is a rather complex function, to ensure we don't disturb
|
||||
other windows."
|
||||
(interactive)
|
||||
(if (eq mu4e-split-view 'single-window)
|
||||
(progn (mu4e-mark-handle-when-leaving)
|
||||
(kill-buffer))
|
||||
(unless (eq major-mode 'mu4e-headers-mode)
|
||||
(mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
|
||||
(mu4e-mark-handle-when-leaving)
|
||||
(let ((curbuf (current-buffer))
|
||||
(curwin (selected-window)))
|
||||
(walk-windows
|
||||
(lambda (win)
|
||||
(with-selected-window win
|
||||
;; if we the view window connected to this one, kill it
|
||||
(when (and (not (one-window-p win)) (eq mu4e~headers-view-win win))
|
||||
(delete-window win)
|
||||
(setq mu4e~headers-view-win nil)))
|
||||
;; and kill any _other_ (non-selected) window that shows the current
|
||||
;; buffer
|
||||
(when (and
|
||||
(eq curbuf (window-buffer win)) ;; does win show curbuf?
|
||||
(not (eq curwin win)) ;; it's not the curwin?
|
||||
(not (one-window-p))) ;; and not the last one?
|
||||
(delete-window win)))) ;; delete it!
|
||||
;; now, all *other* windows should be gone. kill ourselves, and return
|
||||
;; to the main view
|
||||
(kill-buffer)
|
||||
(mu4e--main-view 'refresh))))
|
||||
(mu4e-mark-handle-when-leaving)
|
||||
(quit-window t)
|
||||
(mu4e--main-view 'refresh))
|
||||
|
||||
|
||||
;;; Loading messages
|
||||
;;
|
||||
(defvar mu4e-loading-mode-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "n" #'ignore)
|
||||
(define-key map "p" #'ignore)
|
||||
(define-key map "q" #'bury-buffer)
|
||||
map)
|
||||
(define-key map "n" #'ignore)
|
||||
(define-key map "p" #'ignore)
|
||||
(define-key map "q" #'bury-buffer)
|
||||
map)
|
||||
"Keymap for *mu4e-loading* buffers.")
|
||||
|
||||
(define-derived-mode mu4e-loading-mode special-mode
|
||||
|
||||
Reference in New Issue
Block a user