mu4e: handle the new queries command responses
This commit is contained in:
@ -65,11 +65,6 @@ You can customize the exact fancy characters used with
|
|||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'mu4e)
|
:group 'mu4e)
|
||||||
|
|
||||||
(defcustom mu4e-display-update-status-in-modeline nil
|
|
||||||
"Non-nil value will display the update status in the modeline."
|
|
||||||
:group 'mu4e
|
|
||||||
:type 'boolean)
|
|
||||||
|
|
||||||
;; maybe move the next ones... but they're convenient
|
;; maybe move the next ones... but they're convenient
|
||||||
;; here because they're needed in multiple buffers.
|
;; here because they're needed in multiple buffers.
|
||||||
|
|
||||||
@ -234,101 +229,6 @@ Function returns the cdr of the list element."
|
|||||||
(cdr chosen)
|
(cdr chosen)
|
||||||
(mu4e-warn "Unknown shortcut '%c'" response))))
|
(mu4e-warn "Unknown shortcut '%c'" response))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; Server properties
|
|
||||||
(defvar mu4e--server-props nil
|
|
||||||
"Metadata we receive from the mu4e server.
|
|
||||||
Use `mu4e--update-server-props' to update.")
|
|
||||||
|
|
||||||
;; XXX: we could make these session-persistent
|
|
||||||
|
|
||||||
(defvar mu4e--baseline-query-results nil
|
|
||||||
"Some previous version of the query-results.
|
|
||||||
This is used as the baseline to track updates by comparing it to
|
|
||||||
the latest query-results.")
|
|
||||||
|
|
||||||
(defvar mu4e--baseline-query-results-tstamp nil
|
|
||||||
"Timestamp for when the query-results baseline was updated.")
|
|
||||||
|
|
||||||
(defun mu4e-reset-baseline-query-results ()
|
|
||||||
"Reset the baseline query-results."
|
|
||||||
(interactive)
|
|
||||||
(setq mu4e--baseline-query-results nil
|
|
||||||
mu4e--baseline-query-results-tstamp nil))
|
|
||||||
|
|
||||||
(defun mu4e--update-server-props (props)
|
|
||||||
"Update server props and possibly the baseline query results."
|
|
||||||
(setq mu4e--server-props props)
|
|
||||||
(when-let ((queries (plist-get mu4e--server-props :queries)))
|
|
||||||
(unless mu4e--baseline-query-results
|
|
||||||
(setq mu4e--baseline-query-results queries
|
|
||||||
mu4e--baseline-query-results-tstamp (current-time)))))
|
|
||||||
|
|
||||||
(defun mu4e-server-properties ()
|
|
||||||
"Get the server metadata plist."
|
|
||||||
mu4e--server-props)
|
|
||||||
|
|
||||||
(defun mu4e-root-maildir()
|
|
||||||
"Get the root maildir."
|
|
||||||
(or (and mu4e--server-props
|
|
||||||
(plist-get mu4e--server-props :root-maildir))
|
|
||||||
(mu4e-error "Root maildir unknown; did you start mu4e?")))
|
|
||||||
|
|
||||||
(defun mu4e-database-path()
|
|
||||||
"Get the root maildir."
|
|
||||||
(or (and mu4e--server-props
|
|
||||||
(plist-get mu4e--server-props :database-path))
|
|
||||||
(mu4e-error "Root maildir unknown; did you start mu4e?")))
|
|
||||||
|
|
||||||
(defun mu4e-server-version()
|
|
||||||
"Get the root maildir."
|
|
||||||
(or (and mu4e--server-props
|
|
||||||
(plist-get mu4e--server-props :version))
|
|
||||||
(mu4e-error "Version unknown; did you start mu4e?")))
|
|
||||||
|
|
||||||
(defun mu4e-last-query-results ()
|
|
||||||
"Get the results (counts) of the last cached queries.
|
|
||||||
|
|
||||||
The cached queries are the bookmark / maildir queries that are
|
|
||||||
used to populated the read/unread counts in the main view. They
|
|
||||||
are refreshed when calling `(mu4e)', i.e., when going to the main
|
|
||||||
view.
|
|
||||||
|
|
||||||
When available, the based-line results are added as well.
|
|
||||||
|
|
||||||
The results are a list of elements of the form
|
|
||||||
(:query \"query string\"
|
|
||||||
:count <total number matching count>
|
|
||||||
:unread <number of unread messages in count>
|
|
||||||
:baseline ( ;; baseline results
|
|
||||||
:count <total number matching count>
|
|
||||||
:unread <number of unread messages in count>)) The
|
|
||||||
baseline part is optional (see
|
|
||||||
`mu4e-reset-baseline-query-results') for more details)."
|
|
||||||
(unless mu4e--baseline-query-results
|
|
||||||
(mu4e-reset-baseline-query-results))
|
|
||||||
(seq-map (lambda (qres)
|
|
||||||
(let* ((query (plist-get qres :query))
|
|
||||||
(bres (seq-find ;; find the corresponding baseline entry
|
|
||||||
(lambda (bq) (string= query (plist-get bq :query)))
|
|
||||||
mu4e--baseline-query-results)))
|
|
||||||
(when bres
|
|
||||||
(plist-put qres :baseline
|
|
||||||
`(:count ,(plist-get bres :count)
|
|
||||||
:unread ,(plist-get bres :unread))))
|
|
||||||
qres))
|
|
||||||
(plist-get mu4e--server-props :queries)))
|
|
||||||
|
|
||||||
(defun mu4e-last-query-result (query)
|
|
||||||
"Get the last result for some QUERY or nil if not found.
|
|
||||||
See `mu4e-last-query-results' for the format."
|
|
||||||
(seq-find
|
|
||||||
(lambda (elm) ;;; XXX do we need the decoding?
|
|
||||||
(let ((qstring (decode-coding-string (plist-get elm :query) 'utf-8 t)))
|
|
||||||
(string= query qstring)))
|
|
||||||
(mu4e-last-query-results)))
|
|
||||||
|
|
||||||
|
|
||||||
;;; Logging / debugging
|
;;; Logging / debugging
|
||||||
|
|
||||||
|
|||||||
@ -132,12 +132,55 @@ from the server process.")
|
|||||||
(defvar mu4e-pong-func nil
|
(defvar mu4e-pong-func nil
|
||||||
"Function called for each (:pong type ....) sexp received.")
|
"Function called for each (:pong type ....) sexp received.")
|
||||||
|
|
||||||
|
(defvar mu4e-queries-func nil
|
||||||
|
"Function called for each (:queries type ....) sexp received.")
|
||||||
|
|
||||||
(defvar mu4e-contacts-func nil
|
(defvar mu4e-contacts-func nil
|
||||||
"A function called for each (:contacts (<list-of-contacts>))
|
"A function called for each (:contacts (<list-of-contacts>))
|
||||||
sexp received from the server process.")
|
sexp received from the server process.")
|
||||||
|
|
||||||
|
|
||||||
;;; Internal vars
|
;;; Dealing with Server properties
|
||||||
|
(defvar mu4e--server-props nil
|
||||||
|
"Metadata we receive from the mu4e server.")
|
||||||
|
|
||||||
|
(defun mu4e-server-properties ()
|
||||||
|
"Get the server metadata plist."
|
||||||
|
mu4e--server-props)
|
||||||
|
|
||||||
|
(defun mu4e-root-maildir()
|
||||||
|
"Get the root maildir."
|
||||||
|
(or (and mu4e--server-props
|
||||||
|
(plist-get mu4e--server-props :root-maildir))
|
||||||
|
(mu4e-error "Root maildir unknown; did you start mu4e?")))
|
||||||
|
|
||||||
|
(defun mu4e-database-path()
|
||||||
|
"Get the root maildir."
|
||||||
|
(or (and mu4e--server-props
|
||||||
|
(plist-get mu4e--server-props :database-path))
|
||||||
|
(mu4e-error "Root maildir unknown; did you start mu4e?")))
|
||||||
|
|
||||||
|
(defun mu4e-server-version()
|
||||||
|
"Get the root maildir."
|
||||||
|
(or (and mu4e--server-props
|
||||||
|
(plist-get mu4e--server-props :version))
|
||||||
|
(mu4e-error "Version unknown; did you start mu4e?")))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; server-query-results are the results from the counting-queries
|
||||||
|
;; we do for bookmarks etc. to populate the main view with unread
|
||||||
|
;; counts.
|
||||||
|
|
||||||
|
;;; remember queries result.
|
||||||
|
(defvar mu4e--server-query-results nil
|
||||||
|
"Metadata we receive from the mu4e server.")
|
||||||
|
|
||||||
|
(defun mu4e-server-query-results ()
|
||||||
|
"Get the latest server queries list."
|
||||||
|
mu4e--server-query-results)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Handling raw server data
|
||||||
|
|
||||||
(defvar mu4e--server-buf nil
|
(defvar mu4e--server-buf nil
|
||||||
"Buffer (string) for data received from the backend.")
|
"Buffer (string) for data received from the backend.")
|
||||||
@ -164,8 +207,7 @@ Match 1 will be the length (in hex).")
|
|||||||
Checks whether the server process is live."
|
Checks whether the server process is live."
|
||||||
(and mu4e--server-process
|
(and mu4e--server-process
|
||||||
(memq (process-status mu4e--server-process)
|
(memq (process-status mu4e--server-process)
|
||||||
'(run open listen connect stop))
|
'(run open listen connect stop)) t))
|
||||||
t))
|
|
||||||
|
|
||||||
(defsubst mu4e--server-eat-sexp-from-buf ()
|
(defsubst mu4e--server-eat-sexp-from-buf ()
|
||||||
"'Eat' the next s-expression from `mu4e--server-buf'.
|
"'Eat' the next s-expression from `mu4e--server-buf'.
|
||||||
@ -286,9 +328,14 @@ The server output is as follows:
|
|||||||
|
|
||||||
;; received a pong message
|
;; received a pong message
|
||||||
((plist-get sexp :pong)
|
((plist-get sexp :pong)
|
||||||
(mu4e--update-server-props (plist-get sexp :props))
|
(setq mu4e--server-props (plist-get sexp :props))
|
||||||
(funcall mu4e-pong-func sexp))
|
(funcall mu4e-pong-func sexp))
|
||||||
|
|
||||||
|
;; receive queries info
|
||||||
|
((plist-get sexp :queries)
|
||||||
|
(setq mu4e--server-query-results (plist-get sexp :queries))
|
||||||
|
(funcall mu4e-queries-func sexp))
|
||||||
|
|
||||||
;; received a contacts message
|
;; received a contacts message
|
||||||
;; note: we use 'member', to match (:contacts nil)
|
;; note: we use 'member', to match (:contacts nil)
|
||||||
((plist-member sexp :contacts)
|
((plist-member sexp :contacts)
|
||||||
@ -562,11 +609,15 @@ Returns either (:update ... ) or (:error ) sexp, which are handled my
|
|||||||
:rename ,(and maildir mu4e-change-filenames-when-moving t)
|
:rename ,(and maildir mu4e-change-filenames-when-moving t)
|
||||||
:no-view ,(and no-view t))))
|
:no-view ,(and no-view t))))
|
||||||
|
|
||||||
(defun mu4e--server-ping (&optional queries)
|
(defun mu4e--server-ping ()
|
||||||
"Sends a ping to the mu server, expecting a (:pong ...) in response.
|
"Sends a ping to the mu server, expecting a (:pong ...) in response."
|
||||||
|
(mu4e--server-call-mu `(ping)))
|
||||||
|
|
||||||
|
(defun mu4e--server-queries (queries)
|
||||||
|
"Sends queries to the mu server, expecting a (:queries ...) in response.
|
||||||
QUERIES is a list of queries for the number of results with
|
QUERIES is a list of queries for the number of results with
|
||||||
read/unread status are returned in the pong-response."
|
read/unread status are returned in the pong-response."
|
||||||
(mu4e--server-call-mu `(ping :queries ,queries)))
|
(mu4e--server-call-mu `(queries :queries ,queries)))
|
||||||
|
|
||||||
(defun mu4e--server-remove (docid)
|
(defun mu4e--server-remove (docid)
|
||||||
"Remove message with DOCID.
|
"Remove message with DOCID.
|
||||||
|
|||||||
16
mu4e/mu4e.el
16
mu4e/mu4e.el
@ -138,6 +138,21 @@ Invoke FUNC if non-nil."
|
|||||||
(lambda () (mu4e-update-mail-and-index
|
(lambda () (mu4e-update-mail-and-index
|
||||||
mu4e-index-update-in-background)))))))
|
mu4e-index-update-in-background)))))))
|
||||||
|
|
||||||
|
(defun mu4e--queries-handler (_sexp)
|
||||||
|
;; we've received new server-queries; so update the main view
|
||||||
|
;; (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)
|
||||||
|
|
||||||
|
;; 2. update the main view, if any
|
||||||
|
(when (buffer-live-p mu4e-main-buffer-name)
|
||||||
|
(with-current-buffer mu4e-main-buffer-name
|
||||||
|
(revert-buffer))))
|
||||||
|
|
||||||
(defun mu4e--start (&optional func)
|
(defun mu4e--start (&optional func)
|
||||||
"Start mu4e.
|
"Start mu4e.
|
||||||
If `mu4e-contexts' have been defined, but we don't have a context
|
If `mu4e-contexts' have been defined, but we don't have a context
|
||||||
@ -258,6 +273,7 @@ chance."
|
|||||||
(mu4e-setq-if-nil mu4e-contacts-func #'mu4e--update-contacts)
|
(mu4e-setq-if-nil mu4e-contacts-func #'mu4e--update-contacts)
|
||||||
(mu4e-setq-if-nil mu4e-info-func #'mu4e--info-handler)
|
(mu4e-setq-if-nil mu4e-info-func #'mu4e--info-handler)
|
||||||
(mu4e-setq-if-nil mu4e-pong-func #'mu4e--default-handler))
|
(mu4e-setq-if-nil mu4e-pong-func #'mu4e--default-handler))
|
||||||
|
(mu4e-setq-if-nil mu4e-queries-func #'mu4e--queries-handler))
|
||||||
|
|
||||||
(defun mu4e-clear-caches ()
|
(defun mu4e-clear-caches ()
|
||||||
"Clear any cached resources."
|
"Clear any cached resources."
|
||||||
|
|||||||
Reference in New Issue
Block a user