mirror of https://github.com/djcb/mu.git
mu4e: use caching for modeline items
Avoid excessive (unnecessary) recalculation.
This commit is contained in:
parent
f77bc903e7
commit
5e5a74ed22
|
@ -167,11 +167,11 @@ the latest query-results.")
|
|||
(defun mu4e--reset-baseline ()
|
||||
(setq mu4e--baseline (mu4e-server-query-results)
|
||||
mu4e--baseline-tstamp (current-time))
|
||||
(mu4e-last-query-results 'force)) ; for side-effects
|
||||
(mu4e-last-query-results 'refresh)) ; for side-effects
|
||||
|
||||
|
||||
(defvar mu4e--last-query-results-cached nil)
|
||||
(defun mu4e-last-query-results(&optional force)
|
||||
(defun mu4e-last-query-results(&optional refresh)
|
||||
"Get the results (counts) of the latest queries.
|
||||
|
||||
Either read form the cache or update them when oudated or FORCE
|
||||
|
@ -195,32 +195,32 @@ The results are a list of elements of the form
|
|||
baseline part is optional (see `mu4e-reset-query-results') for
|
||||
more details).
|
||||
|
||||
Uses a cached string unless its nil or FORCE is non-nil."
|
||||
(if (and mu4e--last-query-results-cached (not force))
|
||||
mu4e--last-query-results-cached ;; use cache
|
||||
;; otherwise, recalculate.
|
||||
(let* ((favorite (mu4e-favorite-bookmark))
|
||||
(favorite-query
|
||||
(and favorite (mu4e--bookmark-query favorite))))
|
||||
(setq mu4e--last-query-results-cached ;; walk over the remembered queries
|
||||
;; and augment them with the baseline data and ':favorite' flag, if
|
||||
;; any.
|
||||
(seq-map
|
||||
(lambda (qres)
|
||||
;; note: queries can be _functions_ too; use their
|
||||
;; string value.
|
||||
(let* ((query (mu4e--bookmark-query qres))
|
||||
(bres (seq-find ;; find the corresponding baseline entry
|
||||
(lambda (bq)
|
||||
(string= query (mu4e--bookmark-query bq)))
|
||||
mu4e--baseline)))
|
||||
(when (string= query (or favorite-query ""))
|
||||
(plist-put qres :favorite t))
|
||||
(when bres
|
||||
(plist-put qres :baseline
|
||||
`(:count ,(plist-get bres :count)
|
||||
:unread ,(plist-get bres :unread))))
|
||||
qres)) (mu4e-server-query-results))))))
|
||||
Uses a cached string unless it is nil or REFRESH is non-nil."
|
||||
(or (and (not refresh) mu4e--last-query-results-cached)
|
||||
(setq mu4e--last-query-results-cached
|
||||
(let* ((favorite (mu4e-favorite-bookmark))
|
||||
(favorite-query
|
||||
(and favorite (mu4e--bookmark-query favorite))))
|
||||
;; walk over the remembered queries
|
||||
;; and augment them with the baseline data and ':favorite' flag, if
|
||||
;; any.
|
||||
(seq-map
|
||||
(lambda (qres)
|
||||
;; note: queries can be _functions_ too; use their
|
||||
;; string value.
|
||||
(let* ((query (mu4e--bookmark-query qres))
|
||||
(bres (seq-find ;; find the corresponding baseline entry
|
||||
(lambda (bq)
|
||||
(string= query (mu4e--bookmark-query bq)))
|
||||
mu4e--baseline)))
|
||||
(when (string= query (or favorite-query ""))
|
||||
(plist-put qres :favorite t))
|
||||
(when bres
|
||||
(plist-put qres :baseline
|
||||
`(:count ,(plist-get bres :count)
|
||||
:unread ,(plist-get bres :unread))))
|
||||
qres))
|
||||
(mu4e-server-query-results))))))
|
||||
|
||||
(defun mu4e-last-query-result (query)
|
||||
"Get the last result for some QUERY or nil if not found.
|
||||
|
@ -247,51 +247,39 @@ I.e., very new messages.")
|
|||
(when-let ((fav (mu4e--bookmark-query (mu4e-favorite-bookmark))))
|
||||
(mu4e-search-bookmark fav)))
|
||||
|
||||
(defvar mu4e--bookmarks-modeline-cached nil)
|
||||
|
||||
(defun mu4e--bookmarks-modeline-item ()
|
||||
"Modeline item showing message counts for the favorite bookmark.
|
||||
|
||||
This uses the one special ':favorite' bookmark, and if there is
|
||||
one, creates a propertized string for display in the modeline."
|
||||
(or mu4e--bookmarks-modeline-cached
|
||||
(setq mu4e--bookmarks-modeline-cached
|
||||
(when-let ((fav ;; any results for the favorite bookmark item?
|
||||
(seq-find (lambda (bm) (plist-get bm :favorite))
|
||||
(mu4e-last-query-results))))
|
||||
(let* ((unread (plist-get fav :unread))
|
||||
(count (plist-get fav :count))
|
||||
(baseline (plist-get fav :baseline))
|
||||
(baseline-unread
|
||||
(or (when baseline (plist-get baseline :unread)) unread))
|
||||
(delta (- unread baseline-unread)))
|
||||
(propertize
|
||||
(format "%s%s%s/%s "
|
||||
(funcall (if mu4e-use-fancy-chars 'cdr 'car)
|
||||
(cond
|
||||
((> delta 0) mu4e-modeline-new-items)
|
||||
((> unread 0) mu4e-modeline-unread-items)
|
||||
((> count 0) mu4e-modeline-all-read)
|
||||
(t mu4e-modeline-all-clear)))
|
||||
(propertize (number-to-string unread) 'face 'mu4e-header-key-face)
|
||||
(if (<= delta 0) ""
|
||||
(propertize (format "(%+d)" delta)
|
||||
'face 'mu4e-unread-face))
|
||||
(number-to-string count))
|
||||
'help-echo (format "mu4e query: '%s'" (mu4e--bookmark-query fav))
|
||||
'mouse-face 'mode-line-highlight
|
||||
'keymap '(mode-line keymap
|
||||
(mouse-1 . mu4e-jump-to-favorite)
|
||||
(mouse-2 . mu4e-jump-to-favorite)
|
||||
(mouse-3 . mu4e-jump-to-favorite))))))))
|
||||
|
||||
|
||||
(defun mu4e--modeline-update()
|
||||
"Update the modeline and redisplay if mu4e-modeline-mode is
|
||||
active."
|
||||
(when mu4e-modeline-mode
|
||||
(setq mu4e--bookmarks-modeline-cached nil) ;; force recalculation
|
||||
(force-mode-line-update)))
|
||||
(when-let ((fav ;; any results for the favorite bookmark item?
|
||||
(seq-find (lambda (bm) (plist-get bm :favorite))
|
||||
(mu4e-last-query-results))))
|
||||
(let* ((unread (plist-get fav :unread))
|
||||
(count (plist-get fav :count))
|
||||
(baseline (plist-get fav :baseline))
|
||||
(baseline-unread
|
||||
(or (when baseline (plist-get baseline :unread)) unread))
|
||||
(delta (- unread baseline-unread)))
|
||||
(propertize
|
||||
(format "%s%s%s/%s "
|
||||
(funcall (if mu4e-use-fancy-chars 'cdr 'car)
|
||||
(cond
|
||||
((> delta 0) mu4e-modeline-new-items)
|
||||
((> unread 0) mu4e-modeline-unread-items)
|
||||
((> count 0) mu4e-modeline-all-read)
|
||||
(t mu4e-modeline-all-clear)))
|
||||
(propertize (number-to-string unread) 'face 'mu4e-header-key-face)
|
||||
(if (<= delta 0) ""
|
||||
(propertize (format "(%+d)" delta)
|
||||
'face 'mu4e-unread-face))
|
||||
(number-to-string count))
|
||||
'help-echo (format "mu4e query: '%s'" (mu4e--bookmark-query fav))
|
||||
'mouse-face 'mode-line-highlight
|
||||
'keymap '(mode-line keymap
|
||||
(mouse-1 . mu4e-jump-to-favorite)
|
||||
(mouse-2 . mu4e-jump-to-favorite)
|
||||
(mouse-3 . mu4e-jump-to-favorite))))))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -146,6 +146,7 @@ non-nil."
|
|||
(setq mu4e--context-current context)
|
||||
|
||||
(run-hooks 'mu4e-context-changed-hook)
|
||||
(mu4e--modeline-update)
|
||||
(mu4e-message "Switched context to %s" (mu4e-context-name context)))
|
||||
context))
|
||||
|
||||
|
@ -207,12 +208,13 @@ as it is."
|
|||
(eval ,@body))))
|
||||
|
||||
(defun mu4e--context-modeline-item ()
|
||||
"Propertized string with the current context name.
|
||||
An empty string \"\" if there is none."
|
||||
(if (mu4e-context-current)
|
||||
(concat "[" (propertize (mu4e-quote-for-modeline
|
||||
(mu4e-context-name (mu4e-context-current)))
|
||||
'face 'mu4e-context-face) "] " ) ""))
|
||||
"Propertized string with the current context or nil."
|
||||
(when (mu4e-context-current)
|
||||
(concat
|
||||
"["
|
||||
(propertize (mu4e-quote-for-modeline
|
||||
(mu4e-context-name (mu4e-context-current)))
|
||||
'face 'mu4e-context-face) "] " )))
|
||||
|
||||
(define-minor-mode mu4e-context-minor-mode
|
||||
"Mode for switching the mu4e context."
|
||||
|
|
|
@ -130,6 +130,7 @@ This version handles updating the current screen as well."
|
|||
(mu4e-context-minor-mode)
|
||||
(mu4e-search-minor-mode)
|
||||
(mu4e-update-minor-mode)
|
||||
(mu4e-modeline-mode)
|
||||
(setq-local revert-buffer-function
|
||||
(lambda (_ignore-auto _noconfirm)
|
||||
(mu4e--main-view 'refresh))))
|
||||
|
@ -352,13 +353,14 @@ character of the keyboard shortcut
|
|||
|
||||
(declare-function mu4e--start "mu4e")
|
||||
|
||||
(defun mu4e--main-view (&optional refresh)
|
||||
(defun mu4e--main-view (&optional refresh no-reset)
|
||||
"Create or refresh the mu4e main-view, and switch to it.
|
||||
When REFRESH is non nil refresh infos from server.
|
||||
|
||||
If `mu4e-split-view' equals \='single-window, show a mu4e menu
|
||||
instead."
|
||||
(mu4e--reset-baseline)
|
||||
(unless no-reset
|
||||
(mu4e--reset-baseline))
|
||||
(if (eq mu4e-split-view 'single-window)
|
||||
(mu4e--main-menu)
|
||||
(let ((buf (get-buffer-create mu4e-main-buffer-name))
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file contains functionality for putting mu4e-related information
|
||||
;; in the emacs modeline, both buffer-specific and globally.
|
||||
;; This file contains functionality for putting mu4e-related information in the
|
||||
;; Emacs modeline, both buffer-specific and globally.
|
||||
|
||||
;;; Code:
|
||||
|
||||
|
@ -38,24 +38,35 @@ Each element is function that evaluates to a string.")
|
|||
Each element is function that evaluates to a string.")
|
||||
|
||||
(defun mu4e--modeline-register (func &optional global)
|
||||
"Register a function for calculating some mu4e modeline part.
|
||||
"Register FUNC for calculating some mu4e modeline part.
|
||||
If GLOBAL is non-nil, add to the global-modeline; otherwise use
|
||||
the buffer-local one."
|
||||
(add-to-list
|
||||
(if global 'mu4e--modeline-global-items 'mu4e--modeline-buffer-items)
|
||||
(if global
|
||||
'mu4e--modeline-global-items
|
||||
'mu4e--modeline-buffer-items)
|
||||
func))
|
||||
|
||||
(defvar mu4e--modeline-item nil
|
||||
"Mu4e item for the global-mode-line.")
|
||||
|
||||
(defvar mu4e--modeline-string-cached nil
|
||||
"Cached version of the modeline string.")
|
||||
|
||||
(defun mu4e--modeline-string ()
|
||||
"Calculate the current mu4e modeline string."
|
||||
(mapconcat
|
||||
(lambda (item)
|
||||
(if (functionp item)
|
||||
(or (funcall item) "")
|
||||
""))
|
||||
(append mu4e--modeline-buffer-items mu4e--modeline-global-items) " "))
|
||||
"Get the current mu4e modeline string."
|
||||
(or mu4e--modeline-string-cached
|
||||
(setq mu4e--modeline-string-cached
|
||||
(mapconcat
|
||||
(lambda (func) (or (funcall func) ""))
|
||||
(append mu4e--modeline-buffer-items
|
||||
mu4e--modeline-global-items)
|
||||
" "))))
|
||||
|
||||
(defun mu4e--modeline-update ()
|
||||
"Recalculate and force-update the modeline."
|
||||
(setq mu4e--modeline-string-cached nil)
|
||||
(force-mode-line-update))
|
||||
|
||||
(define-minor-mode mu4e-modeline-mode
|
||||
"Minor mode for showing mu4e information on the modeline."
|
||||
|
@ -68,12 +79,14 @@ the buffer-local one."
|
|||
(if mu4e-modeline-mode
|
||||
(progn
|
||||
(setq mu4e--modeline-item '(:eval (mu4e--modeline-string)))
|
||||
(add-to-list 'global-mode-string mu4e--modeline-item))
|
||||
(add-to-list 'global-mode-string mu4e--modeline-item)
|
||||
(mu4e--modeline-update))
|
||||
(progn
|
||||
(setq global-mode-string
|
||||
(seq-remove (lambda (item) (equal item mu4e--modeline-item))
|
||||
global-mode-string))))
|
||||
(force-mode-line-update))
|
||||
global-mode-string)))
|
||||
(force-mode-line-update)))
|
||||
|
||||
(provide 'mu4e-modeline)
|
||||
;; mu4e-modeline.el ends here
|
||||
|
||||
;;; mu4e-modeline.el ends here
|
||||
|
|
|
@ -204,7 +204,8 @@ show the message with MSGID."
|
|||
(mu4e-mark-handle-when-leaving)
|
||||
(mu4e--search-execute expr ignore-history)
|
||||
(setq mu4e--search-msgid-target msgid
|
||||
mu4e--search-view-target show)))
|
||||
mu4e--search-view-target show)
|
||||
(mu4e--modeline-update)))
|
||||
|
||||
(defun mu4e-search-edit ()
|
||||
"Edit the last search expression."
|
||||
|
@ -459,6 +460,7 @@ If KEY is provided, use it instead of asking user."
|
|||
(when choice
|
||||
(set choice (not (symbol-value choice)))
|
||||
(mu4e-message "Set `%s' to %s" (symbol-name choice) (symbol-value choice))
|
||||
(mu4e--modeline-update)
|
||||
(unless dont-refresh
|
||||
(mu4e-search-rerun)))))
|
||||
|
||||
|
|
11
mu4e/mu4e.el
11
mu4e/mu4e.el
|
@ -156,10 +156,11 @@ Invoke FUNC if non-nil."
|
|||
;; (if any) and the modeline.
|
||||
|
||||
;; 1. update the query results (i.e. process the new server queries)
|
||||
(mu4e-last-query-results 'force-update)
|
||||
(unless mu4e--baseline
|
||||
(mu4e--reset-baseline))
|
||||
(mu4e--modeline-update)
|
||||
(mu4e-last-query-results 'refresh)
|
||||
(if mu4e--baseline
|
||||
(mu4e-last-query-results 'refresh)
|
||||
(mu4e--reset-baseline))
|
||||
;; note: mu4e-reset-baseline implies mu4e--last-query-results
|
||||
|
||||
;; 2. update the main view, if any
|
||||
(when (buffer-live-p mu4e-main-buffer-name)
|
||||
|
@ -261,7 +262,7 @@ Otherwise, check requirements, then start mu4e. When successful, invoke
|
|||
(when (and (buffer-live-p mainbuf) (get-buffer-window mainbuf))
|
||||
(save-window-excursion
|
||||
(select-window (get-buffer-window mainbuf))
|
||||
(mu4e--main-view 'refresh))))))
|
||||
(mu4e--main-view 'refresh 'no-reset))))))
|
||||
((plist-get info :message)
|
||||
(mu4e-index-message "%s" (plist-get info :message))))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue