Files
emacs/lisp/mu4e-maildirs-extension.el
Daniel Weschke 82f05baffe pkg update and first config fix
org-brain not working, add org-roam
2022-12-19 23:02:34 +01:00

803 lines
31 KiB
EmacsLisp

;;; mu4e-maildirs-extension.el --- Show mu4e maildirs summary in mu4e-main-view
;; This file is not part of Emacs
;; Copyright (C) 2013--2017 Andreu Gil Pàmies
;; Filename: mu4e-maildirs-extension.el
;; Version: 0.1
;; Package-Version: 20220517.1852
;; Package-Commit: cdc2e141d8ecd59508a5cd50d6d02120073bf4f1
;; Author: Andreu Gil Pàmies <agpchil@gmail.com>
;; Created: 22-07-2013
;; Description: Show mu4e maildirs summary in mu4e-main-view with unread and
;; total mails for each maildir
;; URL: http://github.com/agpchil/mu4e-maildirs-extension
;; Package-Requires: ((dash "0.0.0"))
;; This file is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Usage:
;; (require 'mu4e-maildirs-extension)
;; (mu4e-maildirs-extension)
;;; Commentary:
;;; Code:
(require 'mu4e)
(require 'dash)
(defgroup mu4e-maildirs-extension nil
"Show mu4e maildirs summary in mu4e-main-view with unread and
total mails for each maildir."
:link '(url-link "https://github.com/agpchil/mu4e-maildirs-extension")
:prefix "mu4e-maildirs-extension-"
:group 'external)
(defcustom mu4e-maildirs-extension-action-key "u"
"Key shortcut to update index and cache."
:group 'mu4e-maildirs-extension
:type '(key-sequence))
(defcustom mu4e-maildirs-extension-toggle-maildir-key (kbd "SPC")
"Key shortcut to expand/collapse maildir at point."
:group 'mu4e-maildirs-extension
:type '(key-sequence))
(defcustom mu4e-maildirs-extension-action-text "\t* [u]pdate index & cache\n"
"Action text to display for updating the index and cache.
If set to 'Don't Display (nil)' it won't be displayed."
:group 'mu4e-maildirs-extension
:type '(choice string (const :tag "Don't Display" nil)))
(defcustom mu4e-maildirs-extension-count-command-format
(concat mu4e-mu-binary " find %s --fields 'i' | wc -l")
"The command to count a maildir. [Most people won't need to edit this]."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-custom-list nil
"List of folders to show.
If set to nil all folders are shown.
Example:
'(\"/account1/INBOX\"
\"/account2/INBOX\")"
:group 'mu4e-maildirs-extension
:type '(repeat string))
;; :type '(sexp))
(defcustom mu4e-maildirs-extension-ignored-regex
nil
"Optional regular expression that is used for filtering list of
maildirs. It's a dynamic alternative to
mu4e-maildirs-extension-custom-list - new maildirs will
automatically appear in the list unless they are explicitly
ignored."
:group 'mu4e-maildirs-extension
:type '(choice string (const :tag "Show all maildirs" nil)))
(defcustom mu4e-maildirs-extension-use-bookmarks
nil
"If non-nil, show the bookmarks count in the mu4e main view."
:group 'mu4e-maildirs-extension
:type 'boolean
:risky t)
(defcustom mu4e-maildirs-extension-use-maildirs
t
"If non-nil, show the maildir summary in the mu4e main view."
:group 'mu4e-maildirs-extension
:type 'boolean)
(defcustom mu4e-maildirs-extension-insert-before-str "\n Misc"
"The place where the maildirs section should be inserted."
:group 'mu4e-maildirs-extension
:type '(choice (const :tag "Basics" "\n Basics")
(const :tag "Bookmarks" "\n Bookmarks")
(const :tag "Misc" "\n Misc")
(const :tag "End of file" "\n")))
(defcustom mu4e-maildirs-extension-bookmark-format " (%u/%t)"
"The bookmark stats format.
Available formatters:
%u is the unread count
%t is the total count"
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-bookmark-format-spec
'(lambda(m)
(list (cons ?u (or (plist-get m :unread) ""))
(cons ?t (or (plist-get m :total) ""))))
"A function to build the bookmark format spec."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-bookmark-hl-regex
mu4e-maildirs-extension-bookmark-format
"Regex to highlight when `mu4e-maildirs-extension-bookmark-hl-pred' matches."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-bookmark-hl-pred
'(lambda(m)
(> (or (plist-get m :unread) 0) 0))
"Predicate function used to highlight."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-maildir-format "\t%i%p %n (%u/%t)"
"The maildir format.
Available formatters:
%i is the folder indentation
%p is the maildir prefix
%l is the folder level
%e is the expand flag
%P is the maildir path
%n is the maildir name
%u is the unread count
%t is the total count"
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-maildir-format-spec
'(lambda(m)
(list (cons ?i (plist-get m :indent))
(cons ?p (plist-get m :prefix))
(cons ?l (plist-get m :level))
(cons ?e (plist-get m :expand))
(cons ?P (plist-get m :path))
(cons ?n (plist-get m :name))
(cons ?u (or (plist-get m :unread) ""))
(cons ?t (or (plist-get m :total) ""))))
"A function to build the maildir format spec."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-maildir-hl-regex
mu4e-maildirs-extension-maildir-format
"Regex to highlight when `mu4e-maildirs-extension-maildir-hl-pred' matches."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-maildir-hl-pred
'(lambda(m)
(> (or (plist-get m :unread) 0) 0))
"Predicate function used to highlight."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-before-insert-maildir-hook
'(mu4e-maildirs-extension-insert-newline-when-root-maildir)
"Hook called before inserting a maildir."
:group 'mu4e-maildirs-extension
:type 'hook)
(defcustom mu4e-maildirs-extension-after-insert-maildir-hook
'(mu4e-maildirs-extension-insert-newline-when-unread)
"Hook called after inserting a maildir."
:group 'mu4e-maildirs-extension
:type 'hook)
(defcustom mu4e-maildirs-extension-propertize-bm-func
#'mu4e-maildirs-extension-propertize-bm-handler
"The function to format the bookmark info.
Default dispays as ' (unread/total)'."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-propertize-func
#'mu4e-maildirs-extension-propertize-handler
"The function to format the maildir info.
Default dispays as '| maildir_name (unread/total)'."
:group 'mu4e-maildirs-extension
:type '(function))
(defcustom mu4e-maildirs-extension-maildir-indent 2
"Maildir indentation."
:group 'mu4e-maildirs-extension
:type '(integer))
(defcustom mu4e-maildirs-extension-maildir-indent-char " "
"The char used for indentation."
:group 'mu4e-maildirs-extension
:type '(integer))
(defcustom mu4e-maildirs-extension-default-collapse-level nil
"The default level to collapse maildirs.
Set `nil' to disable."
:group 'mu4e-maildirs-extension
:type '(choice integer nil))
(defcustom mu4e-maildirs-extension-maildir-collapsed-prefix "+"
"The prefix for collapsed maildir."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-maildir-expanded-prefix "-"
"The prefix for expanded maildir."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-maildir-default-prefix "|"
"The prefix for default maildir."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-fake-maildir-separator nil
"The separator to fake a hierarchy using directory names.
For example:
/Archive
/Archive.foo
/Archive.foo.bar
/Archive.baz
Offlineimap does this when setting `sep = .'."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-updating-string "\n\t* Updating...\n"
"The string to show while updating in background."
:group 'mu4e-maildirs-extension
:type '(string))
(defcustom mu4e-maildirs-extension-title " Maildirs\n"
"The title for the maildirs extension section.
If set to `nil' it won't be displayed."
:group 'mu4e-maildirs-extension
:type '(choice string (const :tag "Don't Display" nil)))
(defcustom mu4e-maildirs-extension-hide-empty-maildirs nil
"Non-nil indicates that maildirs with no new message are hidden."
:group 'mu4e-maildirs-extension
:type 'boolean)
(defface mu4e-maildirs-extension-maildir-face
'((t :inherit mu4e-header-face))
"Face for a normal maildir."
:group 'mu4e-maildirs-extension)
(defface mu4e-maildirs-extension-maildir-hl-face
'((t :inherit mu4e-unread-face))
"Face for a highlighted maildir."
:group 'mu4e-maildirs-extension)
(defcustom mu4e-maildirs-extension-parallel-processes 6
"Max parallel processes."
:group 'mu4e-maildirs-extension
:type '(integer))
(defvar mu4e-maildirs-extension-mu-14 (> (string-to-number mu4e-mu-version) 1.3))
(defvar mu4e-maildirs-extension-running-processes 0)
(defvar mu4e-maildirs-extension-queue nil)
(defvar mu4e-maildirs-extension-start-point nil)
(defvar mu4e-maildirs-extension-end-point nil)
(defvar mu4e-maildirs-extension-maildirs nil)
(defvar mu4e-maildirs-extension-bookmarks nil)
(defvar mu4e-maildirs-extension-buffer-name
;; mu4e~main-buffer-name used to be private API, but is now public. We
;; maintain backward-compatibility with older versions.
(if (boundp 'mu4e~main-buffer-name)
mu4e~main-buffer-name
mu4e-main-buffer-name))
(defvar mu4e-maildirs-extension-index-updated-func
'mu4e-maildirs-extension-index-updated-handler)
(defvar mu4e-maildirs-extension-main-view-func
'mu4e-maildirs-extension-main-view-handler)
(defun mu4e-maildirs-extension-index-updated-handler ()
"Handler for `mu4e-index-updated-hook'."
(let ((arg (if (get-buffer-window mu4e-maildirs-extension-buffer-name)
'(16)
'(4))))
(mu4e-maildirs-extension-force-update arg)))
(defun mu4e-maildirs-extension-main-view-handler ()
"Handler for `mu4e-main-view-mode-hook'."
(setq mu4e-maildirs-extension-start-point nil)
(mu4e-maildirs-extension-update)
(mu4e-maildirs-extension-unqueue-maybe))
(defmacro mu4e-maildirs-extension-with-buffer (&rest body)
"Switch to `mu4e-maildirs-extension' buffer and yield BODY."
(declare (indent defun))
`(let* ((buffer (get-buffer mu4e-maildirs-extension-buffer-name))
(buffer-window (car (get-buffer-window-list buffer)))
(old-pos nil)
(inhibit-read-only t))
(when buffer
(cond (buffer-window
(with-selected-window buffer-window
(setq old-pos (point))
(save-excursion
,@body)
(unless (> old-pos (point-max))
(goto-char old-pos))))
(t
(with-current-buffer buffer
(setq old-pos (point))
(save-excursion
,@body)
(unless (> old-pos (point-max))
(goto-char old-pos))))))))
(defun mu4e-maildirs-extension-unqueue-maybe ()
(when (< mu4e-maildirs-extension-running-processes
mu4e-maildirs-extension-parallel-processes)
(let ((proc-func (pop mu4e-maildirs-extension-queue)))
(cond (proc-func
(funcall proc-func)
(setq mu4e-maildirs-extension-running-processes
(1+ mu4e-maildirs-extension-running-processes)))
(t
(mu4e-maildirs-extension-update))))))
(defun mu4e-maildirs-extension-bookmark-command (query)
"Quote the mu bookmark command with arguments in QUERY quoted."
(format mu4e-maildirs-extension-count-command-format
(mapconcat #'append
(mapcar 'shell-quote-argument (split-string query " "))
" ")))
(defun mu4e-maildirs-extension-maildir-command (path flags)
"Quote the mu maildir command with PATH and FLAGS arguments quoted."
(let ((query (format "%s %s"
(shell-quote-argument (concat "maildir:" (shell-quote-argument path)))
(shell-quote-argument flags))))
(format mu4e-maildirs-extension-count-command-format query)))
(defun mu4e-maildirs-extension-fetch (cmd &optional callback)
"Execute the mu CMD in a shell process and fetch the result.
Optional call the function CALLBACK on finish."
(let* ((finish-func `(lambda(proc event)
(when (and (memq (process-status proc) '(exit))
(buffer-live-p (process-buffer proc))
,callback)
(let ((buffer (process-buffer proc))
(result nil))
(with-current-buffer buffer
(setq result
(cond ((= 0 (process-exit-status proc))
(string-to-number
(replace-regexp-in-string "![0-9]"
""
(buffer-string))))
(t 0))))
(funcall ,callback result)
(kill-buffer buffer)
(setq mu4e-maildirs-extension-running-processes
(1- mu4e-maildirs-extension-running-processes))
(mu4e-maildirs-extension-unqueue-maybe)))))
(proc `(lambda()
(let ((proc (start-process-shell-command "mu4e-maildirs-extension"
(make-temp-name "mu4e-maildirs-extension")
,cmd)))
(set-process-sentinel proc ,finish-func)))))
(add-to-list 'mu4e-maildirs-extension-queue proc t)))
(defun mu4e-maildirs-extension-parse (path)
"Get the maildir parents of maildir PATH name.
Given PATH \"/foo/bar/alpha\" will return '(\"/foo\" \"/bar\")."
(let ((name (replace-regexp-in-string "^/" "" path))
(parents nil)
(fake-sep mu4e-maildirs-extension-fake-maildir-separator)
(all-parents nil))
(setq name (replace-regexp-in-string "\\/\\*$" "" name))
(setq parents (split-string name "/" t))
(cond (mu4e-maildirs-extension-fake-maildir-separator
(mapc #'(lambda(s)
(setq all-parents (append all-parents (split-string s fake-sep t))))
parents))
(t (setq all-parents parents)))
all-parents))
(defun mu4e-maildirs-extension-get-relevant-maildirs ()
"Get a list of maildirs set (or filtered) according to
configuration values."
(or mu4e-maildirs-extension-custom-list
(let ((list (mu4e-get-maildirs)))
(if mu4e-maildirs-extension-ignored-regex
(--remove (string-match mu4e-maildirs-extension-ignored-regex it) list)
list))))
(defun mu4e-maildirs-extension-paths ()
"Get maildirs paths."
(let ((paths (mu4e-maildirs-extension-get-relevant-maildirs))
(paths-to-show nil))
(mapc #'(lambda (name)
(let ((parents (butlast (mu4e-maildirs-extension-parse name)))
(path nil))
(mapc #'(lambda (parent-name)
(setq path (concat path "/" parent-name))
(unless (member path paths-to-show)
(add-to-list 'paths-to-show (format "%s/*" path) t)))
parents))
(add-to-list 'paths-to-show name t))
paths)
paths-to-show))
(defun mu4e-maildirs-extension-update-maildir-prefix (m)
"Get the prefix of maildir M."
(let* ((l mu4e-maildirs-extension-maildirs)
(children (mu4e-maildirs-extension-children m l))
(prefix nil))
(setq prefix (cond ((and children (plist-get m :expand))
mu4e-maildirs-extension-maildir-expanded-prefix)
((and children (not (plist-get m :expand)))
mu4e-maildirs-extension-maildir-collapsed-prefix)
(t mu4e-maildirs-extension-maildir-default-prefix)))
(setq m (plist-put m :prefix prefix))
prefix))
(defun mu4e-maildirs-extension-propertize-handler (m)
"Propertize the maildir text using M plist."
(let* ((fmt mu4e-maildirs-extension-maildir-format)
(hl-regex mu4e-maildirs-extension-maildir-hl-regex)
(hl-p (funcall mu4e-maildirs-extension-maildir-hl-pred m)))
(setq fmt (propertize fmt 'face 'mu4e-maildirs-extension-maildir-face))
(when hl-p
(setq fmt (replace-regexp-in-string hl-regex
(propertize hl-regex
'face
'mu4e-maildirs-extension-maildir-hl-face)
fmt)))
(format-spec fmt (funcall mu4e-maildirs-extension-maildir-format-spec m))))
(defun mu4e-maildirs-extension-load-bookmarks ()
"Fetch data or load from cache."
(unless mu4e-maildirs-extension-bookmarks
(mapc (lambda(it)
(let ((query (if mu4e-maildirs-extension-mu-14 (eval (plist-get it :query))
(eval (mu4e-bookmark-query it))))
(bm (list :data it)))
(when (stringp query)
(add-to-list 'mu4e-maildirs-extension-bookmarks bm t)
(mu4e-maildirs-extension-bm-count bm
:unread
(concat "(" query ") AND flag:unread"))
(mu4e-maildirs-extension-bm-count bm :total query))))
(mu4e-bookmarks)))
mu4e-maildirs-extension-bookmarks)
(defun mu4e-maildirs-extension-load-maildirs ()
"Fetch data or load from cache."
(unless mu4e-maildirs-extension-maildirs
(let ((paths (mu4e-maildirs-extension-paths)))
(setq mu4e-maildirs-extension-maildirs
(mapcar #'mu4e-maildirs-extension-new-maildir paths))))
(mapc #'(lambda (it)
(mu4e-maildirs-extension-count-unread it)
(mu4e-maildirs-extension-count-total it)
(mu4e-maildirs-extension-update-maildir-prefix it))
mu4e-maildirs-extension-maildirs)
mu4e-maildirs-extension-maildirs)
(defun mu4e-maildirs-extension-action-str (str &optional func-or-shortcut)
"Custom action without using [.] in STR.
If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it
when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is
a string, execute the corresponding keyboard action when it is
clicked."
(let ((newstr str)
(map (make-sparse-keymap))
(func (if (functionp func-or-shortcut)
func-or-shortcut
(if (stringp func-or-shortcut)
(lexical-let ((macro func-or-shortcut))
(lambda()(interactive)
(execute-kbd-macro macro)))))))
(define-key map [mouse-2] func)
(define-key map (kbd "RET") func)
(put-text-property 0 (length newstr) 'keymap map newstr)
(put-text-property (string-match "[^\n\t\s-].+$" newstr)
(- (length newstr) 1) 'mouse-face 'highlight newstr)
newstr))
(defun mu4e-maildirs-extension-run-when-unread (m func args)
"Call FUNC passing ARGS to it if M contains unread messages."
(when (or (not mu4e-maildirs-extension-hide-empty-maildirs)
(> (or (plist-get m :unread) 0) 0))
(funcall func args)))
(defun mu4e-maildirs-extension-insert-newline-when-root-maildir (m)
"Insert a newline when M is a root maildir."
(when (equal (plist-get m :level) 0)
(insert "\n")))
(defun mu4e-maildirs-extension-insert-newline (m)
"Insert a newline."
(insert "\n"))
(defun mu4e-maildirs-extension-insert-newline-when-unread (m)
"Insert a newline if M contains unread messages."
(mu4e-maildirs-extension-run-when-unread m #'mu4e-maildirs-extension-insert-newline m))
(defun mu4e-maildirs-extension-count (m key flags)
"Fetch count results using mu FLAGS and store result in M plist with KEY"
(let* ((path (plist-get m :path))
(cmd (mu4e-maildirs-extension-maildir-command path flags))
(count (plist-get m key))
(callback `(lambda(result)
(let ((m (--first (equal (plist-get it :path) ,path)
mu4e-maildirs-extension-maildirs)))
(setq m (plist-put m ,key result))))))
(unless count
(mu4e-maildirs-extension-fetch cmd callback))
(when (numberp count)
(number-to-string count))))
(defun mu4e-maildirs-extension-count-total (m)
"Fetch total count of M."
(or (mu4e-maildirs-extension-count m :total "") ""))
(defun mu4e-maildirs-extension-count-unread (m)
"Fetch unread count of M."
(or (mu4e-maildirs-extension-count m :unread "flag:unread") ""))
(defun mu4e-maildirs-extension-propertize-bm-handler (bm)
"Propertize the bookmark text using BM plist."
(let* ((fmt mu4e-maildirs-extension-bookmark-format)
(hl-regex mu4e-maildirs-extension-bookmark-hl-regex)
(hl-p (funcall mu4e-maildirs-extension-bookmark-hl-pred bm)))
(setq fmt (propertize fmt 'face 'mu4e-maildirs-extension-maildir-face))
(when hl-p
(setq fmt (replace-regexp-in-string hl-regex
(propertize hl-regex
'face
'mu4e-maildirs-extension-maildir-hl-face)
fmt)))
(format-spec fmt (funcall mu4e-maildirs-extension-maildir-format-spec bm))))
(defun mu4e-maildirs-extension-bm-update (bm-point)
"Update bookmark BM entry at MARKER in mu4e main view."
(when (cdr bm-point)
(goto-char (cdr bm-point))
(delete-region (point) (point-at-eol))
(insert (funcall mu4e-maildirs-extension-propertize-bm-func (car bm-point)))))
(defun mu4e-maildirs-extension-insert-maildir (m)
"Insert maildir entry into mu4e main view."
(insert (mu4e-maildirs-extension-action-str
(funcall mu4e-maildirs-extension-propertize-func m)
`(lambda (prefix)
(interactive "P")
(let ((maildir ,(plist-get m :path)))
(if prefix
(mu4e~headers-search-execute
(format "%s AND flag:unread"
(shell-quote-argument (concat "maildir:" maildir)))
nil)
(mu4e~headers-jump-to-maildir maildir)))))))
(defun mu4e-maildirs-extension-new-maildir (path)
"Build new maildir plist from maildir PATH."
(let* ((m nil)
(current-maildirs (mu4e-maildirs-extension-parse path))
(level (1- (length current-maildirs))))
(setq m (plist-put m
:name (car (last current-maildirs))))
(setq m (plist-put m
:level
level))
(setq m (plist-put m
:expand (or (not mu4e-maildirs-extension-default-collapse-level)
(< level mu4e-maildirs-extension-default-collapse-level))))
(setq m (plist-put m
:path
path))
(setq m (plist-put m
:indent
(make-string (* mu4e-maildirs-extension-maildir-indent level)
(string-to-char mu4e-maildirs-extension-maildir-indent-char))))
(setq m (plist-put m
:total
nil))
(setq m (plist-put m
:unread
nil))
m))
(defun mu4e-maildirs-extension-children (m l)
"Return a list of children of M."
(let* ((path (plist-get m :path))
(sane-path (replace-regexp-in-string "\\/\\*$" "" path)))
(-filter (lambda(it)
(let* ((it-path (plist-get it :path)))
(and (not (equal it-path path))
(string-match sane-path it-path))))
l)))
(defun mu4e-maildirs-extension-roots (l)
"Return the list of root maildirs in L."
(--filter (= (plist-get it :level) 0) l))
(defun mu4e-maildirs-extension-member (path l)
"Return the maildir with PATH in L."
(--first (string= (plist-get it :path) path) l))
(defun mu4e-maildirs-extension-is-parent-of (a b)
"Return t if A is parent of B."
(let ((path-a (replace-regexp-in-string "\\/\\*$"
""
(plist-get a :path)))
(path-b (replace-regexp-in-string "\\/\\*$"
""
(plist-get b :path))))
(and (not (equal path-a path-b))
(string-match path-a path-b))))
(defun mu4e-maildirs-extension-parents (m l)
"Return the list of parent maildirs of M in L."
(--filter (mu4e-maildirs-extension-is-parent-of it m) l))
(defun mu4e-maildirs-extension-expanded (l)
"Return the list of expanded maildirs."
(-filter (lambda(m)
(let ((parents (mu4e-maildirs-extension-parents m l)))
(--all? (plist-get it :expand) parents)))
l))
(defun mu4e-maildirs-extension-toggle-maildir-at-point (&optional universal-arg)
""
(interactive "P")
(let ((m nil)
(l mu4e-maildirs-extension-maildirs)
(marker (make-marker)))
(mu4e-maildirs-extension-with-buffer
(set-marker marker (point-at-bol)))
(setq m (--first (equal (plist-get it :marker) marker) l))
(let ((c (when m (mu4e-maildirs-extension-children m l))))
(when (and m c)
(setq m (plist-put m :expand (not (plist-get m :expand))))
(when universal-arg
(mapc (lambda(it)
(when (mu4e-maildirs-extension-children it l)
(setq it (plist-put it :expand (plist-get m :expand)))))
c))))
(mu4e-maildirs-extension-update)))
(defun mu4e-maildirs-extension-bm-count (bm key flags)
"Fetch count results using mu FLAGS and store result in M plist with KEY"
(let* ((data (plist-get bm :data))
(cmd (mu4e-maildirs-extension-bookmark-command flags))
(count (plist-get bm key))
(callback `(lambda(result)
(let ((m (--first (equal (plist-get it :data) ',data)
mu4e-maildirs-extension-bookmarks)))
(setq m (plist-put m ,key result))))))
(unless count
(mu4e-maildirs-extension-fetch cmd callback))
(when (numberp count)
(number-to-string count))))
(defun mu4e-maildirs-extension-update ()
"Insert maildirs summary in `mu4e-main-view'."
(let ((maildirs (mu4e-maildirs-extension-load-maildirs)))
(mu4e-maildirs-extension-with-buffer
(when mu4e-maildirs-extension-use-bookmarks
(mapc #'mu4e-maildirs-extension-bm-update
(let (beg bm-points-alist)
(dolist (bm (mu4e-maildirs-extension-load-bookmarks))
(goto-char (if beg beg (point-min)))
(setq bm-name (if mu4e-maildirs-extension-mu-14
(plist-get (plist-get bm :data) :name)
(mu4e-bookmark-name (plist-get bm :data))))
(setq beg (search-forward bm-name nil t))
(push (cons bm beg) bm-points-alist))
bm-points-alist)))
(goto-char (point-max))
(cond ((and mu4e-maildirs-extension-start-point
mu4e-maildirs-extension-end-point)
(delete-region mu4e-maildirs-extension-start-point
mu4e-maildirs-extension-end-point))
(t
(setq mu4e-maildirs-extension-start-point (make-marker))
(set-marker mu4e-maildirs-extension-start-point
(search-backward mu4e-maildirs-extension-insert-before-str))
(set-marker-insertion-type mu4e-maildirs-extension-start-point nil)))
;; persistent end-point mark
(setq mu4e-maildirs-extension-end-point (make-marker))
(set-marker mu4e-maildirs-extension-end-point mu4e-maildirs-extension-start-point)
(set-marker-insertion-type mu4e-maildirs-extension-end-point t)
(goto-char mu4e-maildirs-extension-start-point)
(define-key mu4e-main-mode-map
mu4e-maildirs-extension-action-key
'mu4e-maildirs-extension-force-update)
(when mu4e-maildirs-extension-use-maildirs
(when mu4e-maildirs-extension-title
(insert "\n"
(propertize mu4e-maildirs-extension-title 'face 'mu4e-title-face)))
(cond (mu4e-maildirs-extension-queue
(insert mu4e-maildirs-extension-updating-string))
(mu4e-maildirs-extension-action-text
(insert "\n"
(mu4e--main-action-str mu4e-maildirs-extension-action-text
mu4e-maildirs-extension-action-key))))
(define-key mu4e-main-mode-map
mu4e-maildirs-extension-toggle-maildir-key
'mu4e-maildirs-extension-toggle-maildir-at-point)
(mapc #'(lambda (m)
(run-hook-with-args 'mu4e-maildirs-extension-before-insert-maildir-hook m)
(setq m (plist-put m :marker (copy-marker (point-marker))))
(mu4e-maildirs-extension-run-when-unread m #'mu4e-maildirs-extension-insert-maildir m)
(run-hook-with-args 'mu4e-maildirs-extension-after-insert-maildir-hook m))
(mu4e-maildirs-extension-expanded maildirs))))))
(defun mu4e-maildirs-extension-force-update (&optional universal-arg)
"Force update cache and summary.
Default behaviour calls `mu4e-update-index' and update cache/summary if needed.
When preceded with `universal-argument':
4 = clears the cache,
16 = clears the cache and update the summary."
(interactive "P")
(cond ((equal universal-arg nil)
(mu4e-update-index))
((equal universal-arg '(4))
(setq mu4e-maildirs-extension-bookmarks nil)
(setq mu4e-maildirs-extension-maildirs nil))
((equal universal-arg '(16))
(setq mu4e-maildirs-extension-bookmarks nil)
(setq mu4e-maildirs-extension-maildirs nil)
(mu4e-maildirs-extension-update)
(mu4e-maildirs-extension-unqueue-maybe))))
;;;###autoload
(defun mu4e-maildirs-extension-load ()
"Initialize."
(mu4e-maildirs-extension-unload)
(if (boundp 'mu4e-message-changed-hook)
(add-hook 'mu4e-message-changed-hook mu4e-maildirs-extension-index-updated-func)
(add-hook 'mu4e-index-updated-hook mu4e-maildirs-extension-index-updated-func))
(add-hook 'mu4e-main-mode-hook mu4e-maildirs-extension-main-view-func))
;;;###autoload
(defun mu4e-maildirs-extension-unload ()
"Un-initialize."
(if (boundp 'mu4e-message-changed-hook)
(remove-hook 'mu4e-message-changed-hook mu4e-maildirs-extension-index-updated-func)
(remove-hook 'mu4e-index-updated-hook mu4e-maildirs-extension-index-updated-func))
(remove-hook 'mu4e-main-mode-hook mu4e-maildirs-extension-main-view-func))
;;;###autoload
(defalias 'mu4e-maildirs-extension 'mu4e-maildirs-extension-load)
(provide 'mu4e-maildirs-extension)
;;; mu4e-maildirs-extension.el ends here