By inspection this looks good, though I haven't tested, so...

On Wednesday, 2020-04-15 at 20:28:22 +02, Jonas Bernoulli wrote:

> Starting with Emacs 27 the old `cl' implementation is finally
> considered obsolete.  Previously its use was strongly discouraged
> at run-time but one was still allowed to use it at compile-time.
>
> For the most part the transition is very simple and boils down to
> adding the "cl-" prefix to some symbols.  A few replacements do not
> follow that simple pattern; e.g. `first' is replaced with `car',
> even though the alias `cl-first' exists, because the latter is not
> idiomatic emacs-lisp.
>
> In a few cases we start using `pcase-let' or `pcase-lambda' instead
> of renaming e.g. `first' to `car'.  That way we can remind the reader
> of the meaning of the various parts of the data that is being
> deconstructed.
>
> An obsolete `lexical-let' and a `lexical-let*' are replaced with their
> regular variants `let' and `let*' even though we do not at the same
> time enable `lexical-binding' for that file.  That is the right thing
> to do because it does not actually make a difference in those cases
> whether lexical bindings are used or not, and because this should be
> enabled in a separate commit.
>
> We need to explicitly depend on the `cl-lib' package because Emacs
> 24.1 and 24.2 lack that library.  When using these releases we end
> up using the backport from GNU Elpa.
>
> We need to explicitly require the `pcase' library because
> `pcase-dolist' was not autoloaded until Emacs 25.1.

Reviewed-by: David Edmondson <d...@dme.org>

> ---
>  emacs/notmuch-company.el     |   5 +-
>  emacs/notmuch-draft.el       |   2 +-
>  emacs/notmuch-hello.el       | 147 ++++++++++++++++++-----------------
>  emacs/notmuch-jump.el        |  45 +++++------
>  emacs/notmuch-lib.el         |  18 ++---
>  emacs/notmuch-maildir-fcc.el |  35 +++++----
>  emacs/notmuch-mua.el         |  76 +++++++++---------
>  emacs/notmuch-parser.el      |  18 ++---
>  emacs/notmuch-pkg.el.tmpl    |   3 +-
>  emacs/notmuch-show.el        | 103 ++++++++++++------------
>  emacs/notmuch-tag.el         |  45 ++++++-----
>  emacs/notmuch-tree.el        |  20 ++---
>  emacs/notmuch.el             |  62 +++++++--------
>  test/test-lib.el             |   2 +-
>  14 files changed, 292 insertions(+), 289 deletions(-)
>
> diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
> index 3e12e7a9..ac998f9b 100644
> --- a/emacs/notmuch-company.el
> +++ b/emacs/notmuch-company.el
> @@ -27,7 +27,8 @@
>  
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'notmuch-lib)
>  
>  (defvar notmuch-company-last-prefix nil)
> @@ -65,7 +66,7 @@ (defun notmuch-company (command &optional arg &rest _ignore)
>    (require 'company)
>    (let ((case-fold-search t)
>       (completion-ignore-case t))
> -    (case command
> +    (cl-case command
>        (interactive (company-begin-backend 'notmuch-company))
>        (prefix (and (derived-mode-p 'message-mode)
>                  (looking-back (concat 
> notmuch-address-completion-headers-regexp ".*")
> diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
> index e22e0d16..504b33be 100644
> --- a/emacs/notmuch-draft.el
> +++ b/emacs/notmuch-draft.el
> @@ -152,7 +152,7 @@ (defun notmuch-draft--query-encryption ()
>    "Checks if we should save a message that should be encrypted.
>  
>  `notmuch-draft-save-plaintext' controls the behaviour."
> -  (case notmuch-draft-save-plaintext
> +  (cl-case notmuch-draft-save-plaintext
>       ((ask)
>        (unless (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to 
> avoid this warning)
>  This message contains mml tags that suggest it is intended to be encrypted.
> diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
> index aff8beb5..74996636 100644
> --- a/emacs/notmuch-hello.el
> +++ b/emacs/notmuch-hello.el
> @@ -21,7 +21,8 @@
>  
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'widget)
>  (require 'wid-edit) ; For `widget-forward'.
>  
> @@ -44,17 +45,19 @@ (defun notmuch-saved-search-get (saved-search field)
>     ((keywordp (car saved-search))
>      (plist-get saved-search field))
>     ;; It is not a plist so it is an old-style entry.
> -   ((consp (cdr saved-search)) ;; It is a list (NAME QUERY COUNT-QUERY)
> -    (case field
> -      (:name (first saved-search))
> -      (:query (second saved-search))
> -      (:count-query (third saved-search))
> -      (t nil)))
> -   (t  ;; It is a cons-cell (NAME . QUERY)
> -    (case field
> -      (:name (car saved-search))
> -      (:query (cdr saved-search))
> -      (t nil)))))
> +   ((consp (cdr saved-search))
> +    (pcase-let ((`(,name ,query ,count-query) saved-search))
> +      (cl-case field
> +     (:name name)
> +     (:query query)
> +     (:count-query count-query)
> +     (t nil))))
> +   (t
> +    (pcase-let ((`(,name . ,query) saved-search))
> +      (cl-case field
> +     (:name name)
> +     (:query query)
> +     (t nil))))))
>  
>  (defun notmuch-hello-saved-search-to-plist (saved-search)
>    "Return a copy of SAVED-SEARCH in plist form.
> @@ -63,7 +66,7 @@ (defun notmuch-hello-saved-search-to-plist (saved-search)
>  cases, for backwards compatibility, convert to plist form and
>  return that."
>    (if (keywordp (car saved-search))
> -      (copy-seq saved-search)
> +      (copy-sequence saved-search)
>      (let ((fields (list :name :query :count-query))
>         plist-search)
>        (dolist (field fields plist-search)
> @@ -392,10 +395,10 @@ (defun notmuch-hello-add-saved-search (widget)
>                              notmuch-saved-searches)))
>      ;; If an existing saved search with this name exists, remove it.
>      (setq notmuch-saved-searches
> -       (loop for elem in notmuch-saved-searches
> -             if (not (equal name
> -                            (notmuch-saved-search-get elem :name)))
> -             collect elem))
> +       (cl-loop for elem in notmuch-saved-searches
> +                if (not (equal name
> +                               (notmuch-saved-search-get elem :name)))
> +                collect elem))
>      ;; Add the new one.
>      (customize-save-variable 'notmuch-saved-searches
>                            (add-to-list 'notmuch-saved-searches
> @@ -413,28 +416,28 @@ (defun notmuch-hello-delete-search-from-history (widget)
>      (notmuch-hello-update)))
>  
>  (defun notmuch-hello-longest-label (searches-alist)
> -  (or (loop for elem in searches-alist
> -         maximize (length (notmuch-saved-search-get elem :name)))
> +  (or (cl-loop for elem in searches-alist
> +            maximize (length (notmuch-saved-search-get elem :name)))
>        0))
>  
>  (defun notmuch-hello-reflect-generate-row (ncols nrows row list)
>    (let ((len (length list)))
> -    (loop for col from 0 to (- ncols 1)
> -       collect (let ((offset (+ (* nrows col) row)))
> -                 (if (< offset len)
> -                     (nth offset list)
> -                   ;; Don't forget to insert an empty slot in the
> -                   ;; output matrix if there is no corresponding
> -                   ;; value in the input matrix.
> -                   nil)))))
> +    (cl-loop for col from 0 to (- ncols 1)
> +          collect (let ((offset (+ (* nrows col) row)))
> +                    (if (< offset len)
> +                        (nth offset list)
> +                      ;; Don't forget to insert an empty slot in the
> +                      ;; output matrix if there is no corresponding
> +                      ;; value in the input matrix.
> +                      nil)))))
>  
>  (defun notmuch-hello-reflect (list ncols)
>    "Reflect a `ncols' wide matrix represented by `list' along the
>  diagonal."
>    ;; Not very lispy...
>    (let ((nrows (ceiling (length list) ncols)))
> -    (loop for row from 0 to (- nrows 1)
> -       append (notmuch-hello-reflect-generate-row ncols nrows row list))))
> +    (cl-loop for row from 0 to (- nrows 1)
> +          append (notmuch-hello-reflect-generate-row ncols nrows row list))))
>  
>  (defun notmuch-hello-widget-search (widget &rest ignore)
>    (if (widget-get widget :notmuch-search-type)
> @@ -575,7 +578,7 @@ (defun notmuch-hello-insert-buttons (searches)
>                 (widget-insert (make-string column-indent ? )))
>             (let* ((name (plist-get elem :name))
>                    (query (plist-get elem :query))
> -                  (oldest-first (case (plist-get elem :sort-order)
> +                  (oldest-first (cl-case (plist-get elem :sort-order)
>                                    (newest-first nil)
>                                    (oldest-first t)
>                                    (otherwise notmuch-search-oldest-first)))
> @@ -803,48 +806,48 @@ (defun notmuch-hello-insert-recent-searches ()
>                  "clear")
>      (widget-insert "\n\n")
>      (let ((start (point)))
> -      (loop for i from 1 to notmuch-hello-recent-searches-max
> -         for search in notmuch-search-history do
> -         (let ((widget-symbol (intern (format "notmuch-hello-search-%d" i))))
> -           (set widget-symbol
> -                (widget-create 'editable-field
> -                               ;; Don't let the search boxes be
> -                               ;; less than 8 characters wide.
> -                               :size (max 8
> -                                          (- (window-width)
> -                                             ;; Leave some space
> -                                             ;; at the start and
> -                                             ;; end of the
> -                                             ;; boxes.
> -                                             (* 2 notmuch-hello-indent)
> -                                             ;; 1 for the space
> -                                             ;; before the
> -                                             ;; `[save]' button. 6
> -                                             ;; for the `[save]'
> -                                             ;; button.
> -                                             1 6
> -                                             ;; 1 for the space
> -                                             ;; before the `[del]'
> -                                             ;; button. 5 for the
> -                                             ;; `[del]' button.
> -                                             1 5))
> -                               :action (lambda (widget &rest ignore)
> -                                         (notmuch-hello-search (widget-value 
> widget)))
> -                               search))
> -           (widget-insert " ")
> -           (widget-create 'push-button
> -                          :notify (lambda (widget &rest ignore)
> -                                    (notmuch-hello-add-saved-search widget))
> -                          :notmuch-saved-search-widget widget-symbol
> -                          "save")
> -           (widget-insert " ")
> -           (widget-create 'push-button
> -                          :notify (lambda (widget &rest ignore)
> -                                    (when (y-or-n-p "Are you sure you want 
> to delete this search? ")
> -                                      
> (notmuch-hello-delete-search-from-history widget)))
> -                          :notmuch-saved-search-widget widget-symbol
> -                          "del"))
> -         (widget-insert "\n"))
> +      (cl-loop for i from 1 to notmuch-hello-recent-searches-max
> +            for search in notmuch-search-history do
> +            (let ((widget-symbol (intern (format "notmuch-hello-search-%d" 
> i))))
> +              (set widget-symbol
> +                   (widget-create 'editable-field
> +                                  ;; Don't let the search boxes be
> +                                  ;; less than 8 characters wide.
> +                                  :size (max 8
> +                                             (- (window-width)
> +                                                ;; Leave some space
> +                                                ;; at the start and
> +                                                ;; end of the
> +                                                ;; boxes.
> +                                                (* 2 notmuch-hello-indent)
> +                                                ;; 1 for the space
> +                                                ;; before the
> +                                                ;; `[save]' button. 6
> +                                                ;; for the `[save]'
> +                                                ;; button.
> +                                                1 6
> +                                                ;; 1 for the space
> +                                                ;; before the `[del]'
> +                                                ;; button. 5 for the
> +                                                ;; `[del]' button.
> +                                                1 5))
> +                                  :action (lambda (widget &rest ignore)
> +                                            (notmuch-hello-search 
> (widget-value widget)))
> +                                  search))
> +              (widget-insert " ")
> +              (widget-create 'push-button
> +                             :notify (lambda (widget &rest ignore)
> +                                       (notmuch-hello-add-saved-search 
> widget))
> +                             :notmuch-saved-search-widget widget-symbol
> +                             "save")
> +              (widget-insert " ")
> +              (widget-create 'push-button
> +                             :notify (lambda (widget &rest ignore)
> +                                       (when (y-or-n-p "Are you sure you 
> want to delete this search? ")
> +                                         
> (notmuch-hello-delete-search-from-history widget)))
> +                             :notmuch-saved-search-widget widget-symbol
> +                             "del"))
> +            (widget-insert "\n"))
>        (indent-rigidly start (point) notmuch-hello-indent))
>      nil))
>  
> diff --git a/emacs/notmuch-jump.el b/emacs/notmuch-jump.el
> index 3e20b8c7..1df6e7f4 100644
> --- a/emacs/notmuch-jump.el
> +++ b/emacs/notmuch-jump.el
> @@ -22,7 +22,9 @@
>  
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile
> +  (require 'cl-lib)
> +  (require 'pcase))
>  
>  (require 'notmuch-lib)
>  (require 'notmuch-hello)
> @@ -51,7 +53,7 @@ (defun notmuch-jump-search ()
>         (let ((name (plist-get saved-search :name))
>               (query (plist-get saved-search :query))
>               (oldest-first
> -              (case (plist-get saved-search :sort-order)
> +              (cl-case (plist-get saved-search :sort-order)
>                  (newest-first nil)
>                  (oldest-first t)
>                  (otherwise (default-value 'notmuch-search-oldest-first)))))
> @@ -123,18 +125,16 @@ (defun notmuch-jump--format-actions (action-map)
>  
>    ;; Compute the maximum key description width
>    (let ((key-width 1))
> -    (dolist (entry action-map)
> +    (pcase-dolist (`(,key ,desc) action-map)
>        (setq key-width
>           (max key-width
> -              (string-width (format-kbd-macro (first entry))))))
> +              (string-width (format-kbd-macro key)))))
>      ;; Format each action
> -    (mapcar (lambda (entry)
> -           (let ((key (format-kbd-macro (first entry)))
> -                 (desc (second entry)))
> -             (concat
> -              (propertize key 'face 'minibuffer-prompt)
> -              (make-string (- key-width (length key)) ? )
> -              " " desc)))
> +    (mapcar (pcase-lambda (`(,key ,desc))
> +           (setq key (format-kbd-macro key))
> +           (concat (propertize key 'face 'minibuffer-prompt)
> +                   (make-string (- key-width (length key)) ? )
> +                   " " desc))
>           action-map)))
>  
>  (defun notmuch-jump--insert-items (width items)
> @@ -169,28 +169,25 @@ (defun notmuch-jump--make-keymap (action-map prompt)
>    "Translate ACTION-MAP into a minibuffer keymap."
>    (let ((map (make-sparse-keymap)))
>      (set-keymap-parent map notmuch-jump-minibuffer-map)
> -    (dolist (action action-map)
> -      (if (= (length (first action)) 1)
> -       (define-key map (first action)
> +    (pcase-dolist (`(,key ,name ,fn) action-map)
> +      (if (= (length key) 1)
> +       (define-key map key
>           `(lambda () (interactive)
> -            (setq notmuch-jump--action ',(third action))
> +            (setq notmuch-jump--action ',fn)
>              (exit-minibuffer)))))
>      ;; By doing this in two passes (and checking if we already have a
>      ;; binding) we avoid problems if the user specifies a binding which
>      ;; is a prefix of another binding.
> -    (dolist (action action-map)
> -      (if (> (length (first action)) 1)
> -       (let* ((key (elt (first action) 0))
> +    (pcase-dolist (`(,key ,name ,fn) action-map)
> +      (if (> (length key) 1)
> +       (let* ((key (elt key 0))
>                (keystr (string key))
>                (new-prompt (concat prompt (format-kbd-macro keystr) " "))
>                (action-submap nil))
>           (unless (lookup-key map keystr)
> -           (dolist (act action-map)
> -             (when (= key (elt (first act) 0))
> -               (push (list (substring (first act) 1)
> -                           (second act)
> -                           (third act))
> -                     action-submap)))
> +           (pcase-dolist (`(,k ,n ,f) action-map)
> +             (when (= key (elt k 0))
> +               (push (list (substring k 1) n f) action-submap)))
>             ;; We deal with backspace specially
>             (push (list (kbd "DEL")
>                         "Backup"
> diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
> index 8acad267..6eaf64d8 100644
> --- a/emacs/notmuch-lib.el
> +++ b/emacs/notmuch-lib.el
> @@ -23,10 +23,12 @@
>  
>  ;;; Code:
>  
> +(require 'cl-lib)
> +
>  (require 'mm-util)
>  (require 'mm-view)
>  (require 'mm-decode)
> -(require 'cl)
> +
>  (require 'notmuch-compat)
>  
>  (unless (require 'notmuch-version nil t)
> @@ -572,7 +574,7 @@ (defun notmuch-multipart/alternative-choose (msg types)
>  (defun notmuch-parts-filter-by-type (parts type)
>    "Given a list of message parts, return a list containing the ones matching
>  the given type."
> -  (remove-if-not
> +  (cl-remove-if-not
>     (lambda (part) (notmuch-match-content-type (plist-get part :content-type) 
> type))
>     parts))
>  
> @@ -683,8 +685,8 @@ (defun notmuch-mm-display-part-inline (msg part 
> content-type process-crypto)
>  ;; have symbols of the form :Header as keys, and the resulting alist will 
> have
>  ;; symbols of the form 'Header as keys.
>  (defun notmuch-headers-plist-to-alist (plist)
> -  (loop for (key value . rest) on plist by #'cddr
> -     collect (cons (intern (substring (symbol-name key) 1)) value)))
> +  (cl-loop for (key value . rest) on plist by #'cddr
> +        collect (cons (intern (substring (symbol-name key) 1)) value)))
>  
>  (defun notmuch-face-ensure-list-form (face)
>    "Return FACE in face list form.
> @@ -778,7 +780,7 @@ (defun notmuch-check-async-exit-status (proc msg 
> &optional command err)
>  are passed to `notmuch-check-exit-status'.  If COMMAND is not
>  provided, it is taken from `process-command'."
>    (let ((exit-status
> -      (case (process-status proc)
> +      (cl-case (process-status proc)
>          ((exit) (process-exit-status proc))
>          ((signal) msg))))
>      (when exit-status
> @@ -846,7 +848,7 @@ (defun notmuch-call-notmuch--helper (destination args)
>  
>    (let (stdin-string)
>      (while (keywordp (car args))
> -      (case (car args)
> +      (cl-case (car args)
>       (:stdin-string (setq stdin-string (cadr args)
>                            args (cddr args)))
>       (otherwise
> @@ -1024,8 +1026,4 @@ (define-obsolete-function-alias
>  
>  (provide 'notmuch-lib)
>  
> -;; Local Variables:
> -;; byte-compile-warnings: (not cl-functions)
> -;; End:
> -
>  ;;; notmuch-lib.el ends here
> diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el
> index ae56bacd..b9cca543 100644
> --- a/emacs/notmuch-maildir-fcc.el
> +++ b/emacs/notmuch-maildir-fcc.el
> @@ -22,7 +22,8 @@
>  
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'message)
>  
>  (require 'notmuch-lib)
> @@ -251,12 +252,12 @@ (defun notmuch-maildir-fcc-with-notmuch-insert 
> (fcc-header &optional create)
>         (let ((response (notmuch-read-char-choice
>                       "Insert failed: (r)etry, (c)reate folder, (i)gnore, or 
> (e)dit the header? "
>                       '(?r ?c ?i ?e))))
> -      (case response
> -            (?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header))
> -            (?c (notmuch-maildir-fcc-with-notmuch-insert fcc-header 't))
> -            (?i 't)
> -            (?e (notmuch-maildir-fcc-with-notmuch-insert
> -                 (read-from-minibuffer "Fcc header: " fcc-header)))))))))
> +      (cl-case response
> +        (?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header))
> +        (?c (notmuch-maildir-fcc-with-notmuch-insert fcc-header 't))
> +        (?i 't)
> +        (?e (notmuch-maildir-fcc-with-notmuch-insert
> +             (read-from-minibuffer "Fcc header: " fcc-header)))))))))
>  
>  
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> @@ -335,16 +336,16 @@ (defun notmuch-maildir-fcc-file-fcc (fcc-header)
>      (let* ((prompt (format "Fcc %s is not a maildir: (r)etry, (c)reate 
> folder, (i)gnore, or  (e)dit the header? "
>                          fcc-header))
>           (response (notmuch-read-char-choice prompt '(?r ?c ?i ?e))))
> -      (case response
> -            (?r (notmuch-maildir-fcc-file-fcc fcc-header))
> -            (?c (if (file-writable-p fcc-header)
> -                    (notmuch-maildir-fcc-create-maildir fcc-header)
> -                  (message "No permission to create %s." fcc-header)
> -                  (sit-for 2))
> -                (notmuch-maildir-fcc-file-fcc fcc-header))
> -            (?i 't)
> -            (?e (notmuch-maildir-fcc-file-fcc
> -                 (read-from-minibuffer "Fcc header: " fcc-header)))))))
> +      (cl-case response
> +        (?r (notmuch-maildir-fcc-file-fcc fcc-header))
> +        (?c (if (file-writable-p fcc-header)
> +                (notmuch-maildir-fcc-create-maildir fcc-header)
> +              (message "No permission to create %s." fcc-header)
> +              (sit-for 2))
> +            (notmuch-maildir-fcc-file-fcc fcc-header))
> +        (?i 't)
> +        (?e (notmuch-maildir-fcc-file-fcc
> +             (read-from-minibuffer "Fcc header: " fcc-header)))))))
>  
>  (defun notmuch-maildir-fcc-write-buffer-to-maildir (destdir &optional 
> mark-seen)
>    "Writes the current buffer to maildir destdir. If mark-seen is
> diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
> index 76572b87..40a1e6bc 100644
> --- a/emacs/notmuch-mua.el
> +++ b/emacs/notmuch-mua.el
> @@ -21,6 +21,8 @@
>  
>  ;;; Code:
>  
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'message)
>  (require 'mm-view)
>  (require 'format-spec)
> @@ -30,8 +32,6 @@ (require 'notmuch-address)
>  (require 'notmuch-draft)
>  (require 'notmuch-message)
>  
> -(eval-when-compile (require 'cl))
> -
>  (declare-function notmuch-show-insert-body "notmuch-show" (msg body depth))
>  (declare-function notmuch-fcc-header-setup "notmuch-maildir-fcc" ())
>  (declare-function notmuch-maildir-message-do-fcc "notmuch-maildir-fcc" ())
> @@ -140,17 +140,18 @@ (defun notmuch-mua-attachment-check ()
>          ;; Limit search from reaching other possible parts of the message
>          (let ((search-limit (search-forward "\n<#" nil t)))
>            (message-goto-body)
> -          (loop while (re-search-forward notmuch-mua-attachment-regexp 
> search-limit t)
> -                ;; For every instance of the "attachment" string
> -                ;; found, examine the text properties. If the text
> -                ;; has either a `face' or `syntax-table' property
> -                ;; then it is quoted text and should *not* cause the
> -                ;; user to be asked about a missing attachment.
> -                if (let ((props (text-properties-at (match-beginning 0))))
> -                     (not (or (memq 'syntax-table props)
> -                              (memq 'face props))))
> -                return t
> -                finally return nil)))
> +          (cl-loop while (re-search-forward notmuch-mua-attachment-regexp
> +                                            search-limit t)
> +                   ;; For every instance of the "attachment" string
> +                   ;; found, examine the text properties. If the text
> +                   ;; has either a `face' or `syntax-table' property
> +                   ;; then it is quoted text and should *not* cause the
> +                   ;; user to be asked about a missing attachment.
> +                   if (let ((props (text-properties-at (match-beginning 0))))
> +                        (not (or (memq 'syntax-table props)
> +                                 (memq 'face props))))
> +                   return t
> +                   finally return nil)))
>        ;; ...but doesn't have a part with a filename...
>        (save-excursion
>          (message-goto-body)
> @@ -203,11 +204,11 @@ (defun notmuch-mua-add-more-hidden-headers ()
>  
>  (defun notmuch-mua-reply-crypto (parts)
>    "Add mml sign-encrypt flag if any part of original message is encrypted."
> -  (loop for part in parts
> -     if (notmuch-match-content-type (plist-get part :content-type) 
> "multipart/encrypted")
> -       do (mml-secure-message-sign-encrypt)
> -     else if (notmuch-match-content-type (plist-get part :content-type) 
> "multipart/*")
> -       do (notmuch-mua-reply-crypto (plist-get part :content))))
> +  (cl-loop for part in parts
> +        if (notmuch-match-content-type (plist-get part :content-type) 
> "multipart/encrypted")
> +          do (mml-secure-message-sign-encrypt)
> +        else if (notmuch-match-content-type (plist-get part :content-type) 
> "multipart/*")
> +          do (notmuch-mua-reply-crypto (plist-get part :content))))
>  
>  ;; There is a bug in emacs 23's message.el that results in a newline
>  ;; not being inserted after the References header, so the next header
> @@ -252,14 +253,14 @@ (defun notmuch-mua-reply (query-string &optional sender 
> reply-all)
>       ;; We modify message-header-format-alist to get around a bug in 
> message.el.
>       ;; See the comment above on notmuch-mua-insert-references.
>       (let ((message-header-format-alist
> -            (loop for pair in message-header-format-alist
> -                  if (eq (car pair) 'References)
> -                  collect (cons 'References
> -                                (apply-partially
> -                                 'notmuch-mua-insert-references
> -                                 (cdr pair)))
> -                  else
> -                  collect pair)))
> +            (cl-loop for pair in message-header-format-alist
> +                     if (eq (car pair) 'References)
> +                     collect (cons 'References
> +                                   (apply-partially
> +                                    'notmuch-mua-insert-references
> +                                    (cdr pair)))
> +                     else
> +                     collect pair)))
>         (notmuch-mua-mail (plist-get reply-headers :To)
>                           (notmuch-sanitize (plist-get reply-headers 
> :Subject))
>                           (notmuch-headers-plist-to-alist reply-headers)
> @@ -309,10 +310,10 @@ (defun notmuch-mua-reply (query-string &optional sender 
> reply-all)
>                      ;; Don't indent multipart sub-parts.
>                      (notmuch-show-indent-multipart nil))
>                   ;; We don't want sigstatus buttons (an information leak and 
> usually wrong anyway).
> -                 (letf (((symbol-function 
> 'notmuch-crypto-insert-sigstatus-button) #'ignore)
> -                        ((symbol-function 
> 'notmuch-crypto-insert-encstatus-button) #'ignore))
> -                       (notmuch-show-insert-body original (plist-get 
> original :body) 0)
> -                       (buffer-substring-no-properties (point-min) 
> (point-max))))))
> +                 (cl-letf (((symbol-function 
> 'notmuch-crypto-insert-sigstatus-button) #'ignore)
> +                           ((symbol-function 
> 'notmuch-crypto-insert-encstatus-button) #'ignore))
> +                   (notmuch-show-insert-body original (plist-get original 
> :body) 0)
> +                   (buffer-substring-no-properties (point-min) 
> (point-max))))))
>  
>       (set-mark (point))
>       (goto-char start)
> @@ -526,10 +527,9 @@ (defun notmuch-mua-new-forward-messages (messages 
> &optional prompt-for-sender)
>        ;; Create a buffer-local queue for tag changes triggered when sending 
> the message
>        (when notmuch-message-forwarded-tags
>       (setq-local notmuch-message-queued-tag-changes
> -                 (loop for id in forward-queries
> -                       collect
> -                       (cons id
> -                             notmuch-message-forwarded-tags))))
> +                 (cl-loop for id in forward-queries
> +                          collect
> +                          (cons id notmuch-message-forwarded-tags))))
>  
>        ;; `message-forward-make-body' shows the User-agent header.  Hide
>        ;; it again.
> @@ -609,10 +609,10 @@ (defun notmuch-mua-send-common (arg &optional exit)
>    (run-hooks 'notmuch-mua-send-hook)
>    (when (and (notmuch-mua-check-no-misplaced-secure-tag)
>            (notmuch-mua-check-secure-tag-has-newline))
> -    (letf (((symbol-function 'message-do-fcc) 
> #'notmuch-maildir-message-do-fcc))
> -       (if exit
> -           (message-send-and-exit arg)
> -         (message-send arg)))))
> +    (cl-letf (((symbol-function 'message-do-fcc) 
> #'notmuch-maildir-message-do-fcc))
> +      (if exit
> +       (message-send-and-exit arg)
> +     (message-send arg)))))
>  
>  (defun notmuch-mua-send-and-exit (&optional arg)
>    (interactive "P")
> diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
> index bb0379c1..dc9fbe2f 100644
> --- a/emacs/notmuch-parser.el
> +++ b/emacs/notmuch-parser.el
> @@ -21,7 +21,7 @@
>  
>  ;;; Code:
>  
> -(require 'cl)
> +(eval-when-compile (require 'cl-lib))
>  
>  (defun notmuch-sexp-create-parser ()
>    "Return a new streaming S-expression parser.
> @@ -70,7 +70,7 @@ (defun notmuch-sexp-read (sp)
>            ;; error to be consistent with all other code paths.
>            (read (current-buffer))
>          ;; Go up a level and return an end token
> -        (decf (notmuch-sexp--depth sp))
> +        (cl-decf (notmuch-sexp--depth sp))
>          (forward-char)
>          'end))
>       ((= (char-after) ?\()
> @@ -94,8 +94,8 @@ (defun notmuch-sexp-read (sp)
>                                 (notmuch-sexp--partial-state sp)))
>                     ;; A complete value is available if we've
>                     ;; reached depth 0.
> -                   (depth (first new-state)))
> -              (assert (>= depth 0))
> +                   (depth (car new-state)))
> +              (cl-assert (>= depth 0))
>                (if (= depth 0)
>                    ;; Reset partial parse state
>                    (setf (notmuch-sexp--partial-state sp) nil
> @@ -139,7 +139,7 @@ (defun notmuch-sexp-begin-list (sp)
>    (cond ((eobp) 'retry)
>       ((= (char-after) ?\()
>        (forward-char)
> -      (incf (notmuch-sexp--depth sp))
> +      (cl-incf (notmuch-sexp--depth sp))
>        t)
>       (t
>        ;; Skip over the bad character like `read' does
> @@ -181,7 +181,7 @@ (defun notmuch-sexp-parse-partial-list (result-function 
> result-buffer)
>      (set (make-local-variable 'notmuch-sexp--state) 'begin))
>    (let (done)
>      (while (not done)
> -      (case notmuch-sexp--state
> +      (cl-case notmuch-sexp--state
>       (begin
>        ;; Enter the list
>        (if (eq (notmuch-sexp-begin-list notmuch-sexp--parser) 'retry)
> @@ -190,7 +190,7 @@ (defun notmuch-sexp-parse-partial-list (result-function 
> result-buffer)
>       (result
>        ;; Parse a result
>        (let ((result (notmuch-sexp-read notmuch-sexp--parser)))
> -        (case result
> +        (cl-case result
>            (retry (setq done t))
>            (end   (setq notmuch-sexp--state 'end))
>            (t     (with-current-buffer result-buffer
> @@ -204,8 +204,4 @@ (defun notmuch-sexp-parse-partial-list (result-function 
> result-buffer)
>  
>  (provide 'notmuch-parser)
>  
> -;; Local Variables:
> -;; byte-compile-warnings: (not cl-functions)
> -;; End:
> -
>  ;;; notmuch-parser.el ends here
> diff --git a/emacs/notmuch-pkg.el.tmpl b/emacs/notmuch-pkg.el.tmpl
> index 3eb0e04e..9d0999c1 100644
> --- a/emacs/notmuch-pkg.el.tmpl
> +++ b/emacs/notmuch-pkg.el.tmpl
> @@ -3,4 +3,5 @@
>    "notmuch"
>    %VERSION%
>    "Emacs based front-end (MUA) for notmuch"
> -  '((emacs "24")))
> +  '((emacs "24")
> +    (cl-lib "0.6.1")))
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index ef2bf1e0..338f868e 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -23,7 +23,10 @@
>  
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile
> +  (require 'cl-lib)
> +  (require 'pcase))
> +
>  (require 'mm-view)
>  (require 'message)
>  (require 'mm-decode)
> @@ -427,17 +430,16 @@ (defun notmuch-clean-address (address)
>       (setq p-name (replace-regexp-in-string "\\\\" "" p-name))
>  
>       ;; Outer single and double quotes, which might be nested.
> -     (loop
> -      with start-of-loop
> -      do (setq start-of-loop p-name)
> +     (cl-loop with start-of-loop
> +              do (setq start-of-loop p-name)
>  
> -      when (string-match "^\"\\(.*\\)\"$" p-name)
> -      do (setq p-name (match-string 1 p-name))
> +              when (string-match "^\"\\(.*\\)\"$" p-name)
> +              do (setq p-name (match-string 1 p-name))
>  
> -      when (string-match "^'\\(.*\\)'$" p-name)
> -      do (setq p-name (match-string 1 p-name))
> +              when (string-match "^'\\(.*\\)'$" p-name)
> +              do (setq p-name (match-string 1 p-name))
>  
> -      until (string= start-of-loop p-name)))
> +              until (string= start-of-loop p-name)))
>  
>        ;; If the address is 'f...@bar.com <f...@bar.com>' then show just
>        ;; 'f...@bar.com'.
> @@ -571,13 +573,13 @@ (defun notmuch-show--register-cids (msg part)
>    ;; Recurse on sub-parts
>    (let ((ctype (notmuch-split-content-type
>               (downcase (plist-get part :content-type)))))
> -    (cond ((equal (first ctype) "multipart")
> +    (cond ((equal (car ctype) "multipart")
>          (mapc (apply-partially #'notmuch-show--register-cids msg)
>                (plist-get part :content)))
>         ((equal ctype '("message" "rfc822"))
>          (notmuch-show--register-cids
>           msg
> -         (first (plist-get (first (plist-get part :content)) :body)))))))
> +         (car (plist-get (car (plist-get part :content)) :body)))))))
>  
>  (defun notmuch-show--get-cid-content (cid)
>    "Return a list (CID-content content-type) or nil.
> @@ -588,8 +590,8 @@ (defun notmuch-show--get-cid-content (cid)
>  will return nil if the CID is unknown or cannot be retrieved."
>    (let ((descriptor (cdr (assoc cid notmuch-show--cids))))
>      (when descriptor
> -      (let* ((msg (first descriptor))
> -          (part (second descriptor))
> +      (let* ((msg (car descriptor))
> +          (part (cadr descriptor))
>            ;; Request caching for this content, as some messages
>            ;; reference the same cid: part many times (hundreds!).
>            (content (notmuch-get-bodypart-binary
> @@ -614,8 +616,8 @@ (defun notmuch-show--cid-w3m-retrieve (url &rest args)
>         (with-current-buffer w3m-current-buffer
>           (notmuch-show--get-cid-content cid))))
>      (when content-and-type
> -      (insert (first content-and-type))
> -      (second content-and-type))))
> +      (insert (car content-and-type))
> +      (cadr content-and-type))))
>  
>  ;; MIME part renderers
>  
> @@ -783,7 +785,7 @@ (if (version< emacs-version "25.3")
>        ;; is defined before it will be shadowed by the letf below. Otherwise 
> the version
>        ;; in enriched.el may be loaded a bit later and used instead (for the 
> first time).
>        (require 'enriched)
> -      (letf (((symbol-function 'enriched-decode-display-prop)
> +      (cl-letf (((symbol-function 'enriched-decode-display-prop)
>                (lambda (start end &optional param) (list start end))))
>       (notmuch-show-insert-part-*/* msg part content-type nth depth button))))
>  
> @@ -841,7 +843,7 @@ (defun notmuch-show--insert-part-text/html-shr (msg part)
>          ;; shr strips the "cid:" part of URL, but doesn't
>          ;; URL-decode it (see RFC 2392).
>          (let ((cid (url-unhex-string url)))
> -          (first (notmuch-show--get-cid-content cid))))))
> +          (car (notmuch-show--get-cid-content cid))))))
>      (shr-insert-document dom)
>      t))
>  
> @@ -871,15 +873,16 @@ (defun notmuch-show-handlers-for (content-type)
>  
>  (defun notmuch-show-insert-bodypart-internal (msg part content-type nth 
> depth button)
>    ;; Run the handlers until one of them succeeds.
> -  (loop for handler in (notmuch-show-handlers-for content-type)
> -     until (condition-case err
> -               (funcall handler msg part content-type nth depth button)
> -             ;; Specifying `debug' here lets the debugger run if
> -             ;; `debug-on-error' is non-nil.
> -             ((debug error)
> -              (insert "!!! Bodypart handler `" (prin1-to-string handler) "' 
> threw an error:\n"
> -                      "!!! " (error-message-string err) "\n")
> -              nil))))
> +  (cl-loop for handler in (notmuch-show-handlers-for content-type)
> +        until (condition-case err
> +                  (funcall handler msg part content-type nth depth button)
> +                ;; Specifying `debug' here lets the debugger run if
> +                ;; `debug-on-error' is non-nil.
> +                ((debug error)
> +                 (insert "!!! Bodypart handler `" (prin1-to-string handler)
> +                         "' threw an error:\n"
> +                         "!!! " (error-message-string err) "\n")
> +                 nil))))
>  
>  (defun notmuch-show-create-part-overlays (button beg end)
>    "Add an overlay to the part between BEG and END"
> @@ -905,13 +908,15 @@ (defun notmuch-show-record-part-information (part beg 
> end)
>    ;; watch out for sticky specs of t, which means all properties are
>    ;; front-sticky/rear-nonsticky.
>    (notmuch-map-text-property beg end 'front-sticky
> -                          (lambda (v) (if (listp v)
> -                                          (pushnew :notmuch-part v)
> -                                        v)))
> +                          (lambda (v)
> +                            (if (listp v)
> +                                (cl-pushnew :notmuch-part v)
> +                              v)))
>    (notmuch-map-text-property beg end 'rear-nonsticky
> -                          (lambda (v) (if (listp v)
> -                                          (pushnew :notmuch-part v)
> -                                        v))))
> +                          (lambda (v)
> +                            (if (listp v)
> +                                (cl-pushnew :notmuch-part v)
> +                              v))))
>  
>  (defun notmuch-show-lazy-part (part-args button)
>    ;; Insert the lazy part after the button for the part. We would just
> @@ -939,7 +944,7 @@ (defun notmuch-show-lazy-part (part-args button)
>       (indent-rigidly part-beg part-end (* notmuch-show-indent-messages-width 
> depth)))
>        (goto-char part-end)
>        (delete-char 1)
> -      (notmuch-show-record-part-information (second part-args)
> +      (notmuch-show-record-part-information (cadr part-args)
>                                           (button-start button)
>                                           part-end)
>        ;; Create the overlay. If the lazy-part turned out to be empty/not
> @@ -1035,7 +1040,7 @@ (defun notmuch-show-insert-body (msg body depth)
>    ;; Register all content IDs for this message.  According to RFC
>    ;; 2392, content IDs are *global*, but it's okay if an MUA treats
>    ;; them as only global within a message.
> -  (notmuch-show--register-cids msg (first body))
> +  (notmuch-show--register-cids msg (car body))
>  
>    (mapc (lambda (part) (notmuch-show-insert-bodypart msg part depth)) body))
>  
> @@ -1218,13 +1223,13 @@ (defun notmuch-show-buttonise-links (start end)
>                     (url-unhex-string (match-string 0 mid-cid)))))
>         (push (list (match-beginning 0) (match-end 0)
>                     (notmuch-id-to-query mid)) links)))
> -      (dolist (link links)
> +      (pcase-dolist (`(,beg ,end ,link) links)
>       ;; Remove the overlay created by goto-address-mode
> -     (remove-overlays (first link) (second link) 'goto-address t)
> -     (make-text-button (first link) (second link)
> +     (remove-overlays beg end 'goto-address t)
> +     (make-text-button beg end
>                         :type 'notmuch-button-type
>                         'action `(lambda (arg)
> -                                  (notmuch-show ,(third link) 
> current-prefix-arg))
> +                                  (notmuch-show ,link current-prefix-arg))
>                         'follow-link t
>                         'help-echo "Mouse-1, RET: search for this message"
>                         'face goto-address-mail-face)))))
> @@ -1385,9 +1390,9 @@ (defun notmuch-show-get-query ()
>  (defun notmuch-show-goto-message (msg-id)
>    "Go to message with msg-id."
>    (goto-char (point-min))
> -  (unless (loop if (string= msg-id (notmuch-show-get-message-id))
> -             return t
> -             until (not (notmuch-show-goto-message-next)))
> +  (unless (cl-loop if (string= msg-id (notmuch-show-get-message-id))
> +                return t
> +                until (not (notmuch-show-goto-message-next)))
>      (goto-char (point-min))
>      (message "Message-id not found."))
>    (notmuch-show-message-adjust))
> @@ -1404,9 +1409,9 @@ (defun notmuch-show-apply-state (state)
>  
>      ;; Open those that were open.
>      (goto-char (point-min))
> -    (loop do (notmuch-show-message-visible 
> (notmuch-show-get-message-properties)
> -                                        (member 
> (notmuch-show-get-message-id) open))
> -       until (not (notmuch-show-goto-message-next)))
> +    (cl-loop do (notmuch-show-message-visible 
> (notmuch-show-get-message-properties)
> +                                           (member 
> (notmuch-show-get-message-id) open))
> +          until (not (notmuch-show-goto-message-next)))
>  
>      (dolist (win-msg-pair win-msg-alist)
>        (with-selected-window (car win-msg-pair)
> @@ -1610,8 +1615,8 @@ (defun notmuch-show-mapc (function)
>  effects."
>    (save-excursion
>      (goto-char (point-min))
> -    (loop do (funcall function)
> -       while (notmuch-show-goto-message-next))))
> +    (cl-loop do (funcall function)
> +          while (notmuch-show-goto-message-next))))
>  
>  ;; Functions relating to the visibility of messages and their
>  ;; components.
> @@ -2167,9 +2172,9 @@ (defun notmuch-show-open-or-close-all ()
>    (interactive)
>    (save-excursion
>      (goto-char (point-min))
> -    (loop do (notmuch-show-message-visible 
> (notmuch-show-get-message-properties)
> -                                        (not current-prefix-arg))
> -       until (not (notmuch-show-goto-message-next))))
> +    (cl-loop do (notmuch-show-message-visible 
> (notmuch-show-get-message-properties)
> +                                           (not current-prefix-arg))
> +          until (not (notmuch-show-goto-message-next))))
>    (force-window-update))
>  
>  (defun notmuch-show-next-button ()
> diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
> index 0500927d..bc83e3de 100644
> --- a/emacs/notmuch-tag.el
> +++ b/emacs/notmuch-tag.el
> @@ -24,8 +24,12 @@
>  ;;; Code:
>  ;;
>  
> -(require 'cl)
> +(require 'cl-lib)
> +(eval-when-compile
> +  (require 'pcase))
> +
>  (require 'crm)
> +
>  (require 'notmuch-lib)
>  
>  (declare-function notmuch-search-tag "notmuch" tag-changes)
> @@ -277,10 +281,10 @@ (defun notmuch-tag--get-formats (tag format-alist)
>    (save-match-data
>      ;; Don't use assoc-default since there's no way to distinguish a
>      ;; missing key from a present key with a null cdr.
> -    (assoc* tag format-alist
> -         :test (lambda (tag key)
> -                 (and (eq (string-match key tag) 0)
> -                      (= (match-end 0) (length tag)))))))
> +    (cl-assoc tag format-alist
> +           :test (lambda (tag key)
> +                   (and (eq (string-match key tag) 0)
> +                        (= (match-end 0) (length tag)))))))
>  
>  (defun notmuch-tag--do-format (tag formatted-tag formats)
>    "Apply a tag-formats entry to TAG."
> @@ -315,7 +319,7 @@ (defun notmuch-tag-format-tag (tags orig-tags tag)
>        (formatted-tag (gethash (cons tag tag-state) notmuch-tag--format-cache 
> 'missing)))
>      (when (eq formatted-tag 'missing)
>        (let ((base (notmuch-tag--get-formats tag notmuch-tag-formats))
> -         (over (case tag-state
> +         (over (cl-case tag-state
>                   (deleted (notmuch-tag--get-formats
>                             tag notmuch-tag-deleted-formats))
>                   (added (notmuch-tag--get-formats
> @@ -436,7 +440,7 @@ (defun notmuch-update-tags (tags tag-changes)
>      (dolist (tag-change tag-changes)
>        (let ((op (string-to-char tag-change))
>           (tag (unless (string= tag-change "") (substring tag-change 1))))
> -     (case op
> +     (cl-case op
>         (?+ (unless (member tag result-tags)
>               (push tag result-tags)))
>         (?- (setq result-tags (delete tag result-tags)))
> @@ -511,22 +515,21 @@ (defun notmuch-tag-jump (reverse)
>    ;; REVERSE is specified.
>    (interactive "P")
>    (let (action-map)
> -    (dolist (binding notmuch-tagging-keys)
> -      (let* ((tag-function (case major-mode
> +    (pcase-dolist (`(,key ,tag ,name) notmuch-tagging-keys)
> +      (let* ((tag-function (cl-case major-mode
>                            (notmuch-search-mode #'notmuch-search-tag)
>                            (notmuch-show-mode #'notmuch-show-tag)
>                            (notmuch-tree-mode #'notmuch-tree-tag)))
> -          (key (first binding))
> -          (forward-tag-change (if (symbolp (second binding))
> -                                  (symbol-value (second binding))
> -                                (second binding)))
> +          (tag (if (symbolp tag)
> +                   (symbol-value tag)
> +                 tag))
>            (tag-change (if reverse
> -                          (notmuch-tag-change-list forward-tag-change 't)
> -                        forward-tag-change))
> -          (name (or (and (not (string= (third binding) ""))
> -                         (third binding))
> -                    (and (symbolp (second binding))
> -                         (symbol-name (second binding)))))
> +                          (notmuch-tag-change-list tag 't)
> +                        tag))
> +          (name (or (and (not (string= name ""))
> +                         name)
> +                    (and (symbolp name)
> +                         (symbol-name name))))
>            (name-string (if name
>                             (if reverse (concat "Reverse " name)
>                               name)
> @@ -546,7 +549,3 @@ (defun notmuch-tag-jump (reverse)
>  ;;
>  
>  (provide 'notmuch-tag)
> -
> -;; Local Variables:
> -;; byte-compile-warnings: (not cl-functions)
> -;; End:
> diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
> index c00315e8..5e6b9c5b 100644
> --- a/emacs/notmuch-tree.el
> +++ b/emacs/notmuch-tree.el
> @@ -24,6 +24,8 @@
>  
>  ;;; Code:
>  
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'mail-parse)
>  
>  (require 'notmuch-lib)
> @@ -32,7 +34,6 @@ (require 'notmuch-show)
>  (require 'notmuch-tag)
>  (require 'notmuch-parser)
>  
> -(eval-when-compile (require 'cl))
>  (declare-function notmuch-search "notmuch" (&optional query oldest-first 
> target-thread target-line))
>  (declare-function notmuch-call-notmuch-process "notmuch" (&rest args))
>  (declare-function notmuch-read-query "notmuch" (prompt))
> @@ -630,10 +631,10 @@ (defun notmuch-tree-thread-mapcar (function)
>   and call FUNCTION for side effects."
>    (save-excursion
>      (notmuch-tree-thread-top)
> -    (loop collect (funcall function)
> -       do (forward-line)
> -       while (and (notmuch-tree-get-message-properties)
> -                  (not (notmuch-tree-get-prop :first))))))
> +    (cl-loop collect (funcall function)
> +          do (forward-line)
> +          while (and (notmuch-tree-get-message-properties)
> +                     (not (notmuch-tree-get-prop :first))))))
>  
>  (defun notmuch-tree-get-messages-ids-thread-search ()
>    "Return a search string for all message ids of messages in the current 
> thread."
> @@ -814,10 +815,11 @@ (defun notmuch-tree-insert-tree (tree depth tree-status 
> first last)
>  (defun notmuch-tree-insert-thread (thread depth tree-status)
>    "Insert the collection of sibling sub-threads THREAD at depth DEPTH in the 
> current forest."
>    (let ((n (length thread)))
> -    (loop for tree in thread
> -       for count from 1 to n
> -
> -       do (notmuch-tree-insert-tree tree depth tree-status (eq count 1) (eq 
> count n)))))
> +    (cl-loop for tree in thread
> +          for count from 1 to n
> +          do (notmuch-tree-insert-tree tree depth tree-status
> +                                       (eq count 1)
> +                                       (eq count n)))))
>  
>  (defun notmuch-tree-insert-forest-thread (forest-thread)
>    "Insert a single complete thread."
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index 0d68d123..faff8308 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -65,7 +65,8 @@
>  ;;
>  ;;; Code:
>  
> -(eval-when-compile (require 'cl))
> +(eval-when-compile (require 'cl-lib))
> +
>  (require 'mm-view)
>  (require 'message)
>  
> @@ -132,7 +133,7 @@ (defun notmuch-count-attachments (mm-handle)
>                (or (equal (car disposition) "attachment")
>                    (and (equal (car disposition) "inline")
>                         (assq 'filename disposition)))
> -              (incf count))))
> +              (cl-incf count))))
>       mm-handle)
>      count))
>  
> @@ -428,14 +429,13 @@ (defun notmuch-search-foreach-result (beg end fn)
>  the region between points BEG and END.  As a special case, if (=
>  BEG END), FN will be applied to the result containing point
>  BEG."
> -
> -  (lexical-let ((pos (notmuch-search-result-beginning beg))
> -             ;; End must be a marker in case fn changes the
> -             ;; text.
> -             (end (copy-marker end))
> -             ;; Make sure we examine at least one result, even if
> -             ;; (= beg end).
> -             (first t))
> +  (let ((pos (notmuch-search-result-beginning beg))
> +     ;; End must be a marker in case fn changes the
> +     ;; text.
> +     (end (copy-marker end))
> +     ;; Make sure we examine at least one result, even if
> +     ;; (= beg end).
> +     (first t))
>      ;; We have to be careful if the region extends beyond the results.
>      ;; In this case, pos could be null or there could be no result at
>      ;; pos.
> @@ -477,10 +477,10 @@ (defun notmuch-search-find-stable-query-region (beg end 
> &optional only-matched)
>  no messages in the region then return nil."
>    (let ((query-list nil) (all (not only-matched)))
>      (dolist (queries (notmuch-search-properties-in-region :query beg end))
> -      (when (first queries)
> -     (push (first queries) query-list))
> -      (when (and all (second queries))
> -     (push (second queries) query-list)))
> +      (when (car queries)
> +     (push (car queries) query-list))
> +      (when (and all (cadr queries))
> +     (push (cadr queries) query-list)))
>      (when query-list
>        (concat "(" (mapconcat 'identity query-list ") or (") ")"))))
>  
> @@ -562,12 +562,11 @@ (defun notmuch-search-interactive-tag-changes 
> (&optional initial-input)
>    "Prompt for tag changes for the current thread or region.
>  
>  Returns (TAG-CHANGES REGION-BEGIN REGION-END)."
> -  (let* ((region (notmuch-interactive-region))
> -      (beg (first region)) (end (second region))
> -      (prompt (if (= beg end) "Tag thread" "Tag region")))
> -    (cons (notmuch-read-tag-changes
> -        (notmuch-search-get-tags-region beg end) prompt initial-input)
> -       region)))
> +  (pcase-let ((`(,beg ,end) (notmuch-interactive-region)))
> +    (list (notmuch-read-tag-changes (notmuch-search-get-tags-region beg end)
> +                                 (if (= beg end) "Tag thread" "Tag region")
> +                                 initial-input)
> +       beg end)))
>  
>  (defun notmuch-search-tag (tag-changes &optional beg end only-matched)
>    "Change tags for the currently selected thread or region.
> @@ -885,12 +884,13 @@ (defun notmuch-search-buffer-title (query)
>    (let* ((saved-search
>         (let (longest
>               (longest-length 0))
> -         (loop for tuple in notmuch-saved-searches
> -               if (let ((quoted-query (regexp-quote 
> (notmuch-saved-search-get tuple :query))))
> -                    (and (string-match (concat "^" quoted-query) query)
> -                         (> (length (match-string 0 query))
> -                            longest-length)))
> -               do (setq longest tuple))
> +         (cl-loop for tuple in notmuch-saved-searches
> +                  if (let ((quoted-query
> +                            (regexp-quote (notmuch-saved-search-get tuple 
> :query))))
> +                       (and (string-match (concat "^" quoted-query) query)
> +                            (> (length (match-string 0 query))
> +                               longest-length)))
> +                  do (setq longest tuple))
>           longest))
>        (saved-search-name (notmuch-saved-search-get saved-search :name))
>        (saved-search-query (notmuch-saved-search-get saved-search :query)))
> @@ -911,7 +911,7 @@ (defun notmuch-read-query (prompt)
>    "Read a notmuch-query from the minibuffer with completion.
>  
>  PROMPT is the string to prompt with."
> -  (lexical-let*
> +  (let*
>        ((all-tags
>          (mapcar (lambda (tag) (notmuch-escape-boolean-term tag))
>                  (process-lines notmuch-command "search" "--output=tags" 
> "*")))
> @@ -922,7 +922,7 @@ (defun notmuch-read-query (prompt)
>                (mapcar (lambda (tag) (concat "is:" tag)) all-tags)
>                (mapcar (lambda (mimetype) (concat "mimetype:" mimetype)) 
> (mailcap-mime-types)))))
>      (let ((keymap (copy-keymap minibuffer-local-map))
> -       (current-query (case major-mode
> +       (current-query (cl-case major-mode
>                          (notmuch-search-mode (notmuch-search-get-query))
>                          (notmuch-show-mode (notmuch-show-get-query))
>                          (notmuch-tree-mode (notmuch-tree-get-query))))
> @@ -1102,9 +1102,9 @@ (defun notmuch-cycle-notmuch-buffers ()
>        (bury-buffer))
>  
>      ;; Find the first notmuch buffer.
> -    (setq first (loop for buffer in (buffer-list)
> -                   if (notmuch-interesting-buffer buffer)
> -                   return buffer))
> +    (setq first (cl-loop for buffer in (buffer-list)
> +                      if (notmuch-interesting-buffer buffer)
> +                      return buffer))
>  
>      (if first
>       ;; If the first one we found is any other than the starting
> diff --git a/test/test-lib.el b/test/test-lib.el
> index 9946010b..14082d3c 100644
> --- a/test/test-lib.el
> +++ b/test/test-lib.el
> @@ -20,7 +20,7 @@
>  ;;
>  ;; Authors: Dmitry Kurochkin <dmitry.kuroch...@gmail.com>
>  
> -(require 'cl)        ;; This code is generally used uncompiled.
> +(require 'cl-lib)
>  
>  ;; `read-file-name' by default uses `completing-read' function to read
>  ;; user input.  It does not respect `standard-input' variable which we
> -- 
> 2.26.0
>
>
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch

dme.
-- 
I just bite it, it's for the look I don't light it.
_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to