Merge pull request #1484 from thierryvolpiatto/lexical-binding

mu4e: Completely use cl-lib and lexical-binding (rebase #1471)
This commit is contained in:
Dirk-Jan C. Binnema 2019-09-14 14:49:36 +03:00 committed by GitHub
commit 76e6ea256f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 78 additions and 82 deletions

View File

@ -1,4 +1,4 @@
;; mu4e-compose.el -- part of mu4e, the mu mail user agent for emacs ;; mu4e-compose.el -- part of mu4e, the mu mail user agent for emacs -*- lexical-binding: t -*-
;; ;;
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
@ -66,8 +66,7 @@
;; ;;
;;; Code: ;;; Code:
(eval-when-compile (require 'cl-lib)
(require 'cl))
(require 'message) (require 'message)
(require 'mail-parse) (require 'mail-parse)
(require 'smtpmail) (require 'smtpmail)
@ -270,7 +269,8 @@ If needed, set the Fcc header, and register the handler function."
;; etc. if you run it after mu4e so, (hack hack) we reset it to the old ;; etc. if you run it after mu4e so, (hack hack) we reset it to the old
;; handler after we've done our thing. ;; handler after we've done our thing.
(setq message-fcc-handler-function (setq message-fcc-handler-function
(lexical-let ((maildir mdir) (old-handler message-fcc-handler-function)) (let ((maildir mdir)
(old-handler message-fcc-handler-function))
(lambda (file) (lambda (file)
(setq message-fcc-handler-function old-handler) ;; reset the fcc handler (setq message-fcc-handler-function old-handler) ;; reset the fcc handler
(let ((mdir-path (concat mu4e-maildir maildir))) (let ((mdir-path (concat mu4e-maildir maildir)))
@ -278,8 +278,8 @@ If needed, set the Fcc header, and register the handler function."
;; `mu4e~proc-mkdir` runs asynchronously but no matter whether it runs before or after ;; `mu4e~proc-mkdir` runs asynchronously but no matter whether it runs before or after
;; `write-file`, the sent maildir ends up in the correct state. ;; `write-file`, the sent maildir ends up in the correct state.
(unless (file-exists-p mdir-path) (unless (file-exists-p mdir-path)
(mu4e~proc-mkdir mdir-path))) (mu4e~proc-mkdir mdir-path)))
(write-file file) ;; writing maildirs files is easy (write-file file) ;; writing maildirs files is easy
(mu4e~proc-add file (or maildir "/")))))))) ;; update the database (mu4e~proc-add file (or maildir "/")))))))) ;; update the database
(defvar mu4e-compose-hidden-headers (defvar mu4e-compose-hidden-headers
@ -734,7 +734,7 @@ buffer."
(while (re-search-forward "<[^ <]+@[^ <]+>" nil t) (while (re-search-forward "<[^ <]+@[^ <]+>" nil t)
(push (match-string 0) refs)) (push (match-string 0) refs))
;; the last will be the first ;; the last will be the first
(setq forwarded-from (first refs)))))) (setq forwarded-from (cl-first refs))))))
;; remove the <> ;; remove the <>
(when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to)) (when (and in-reply-to (string-match "<\\(.*\\)>" in-reply-to))
(mu4e~proc-move (match-string 1 in-reply-to) nil "+R-N")) (mu4e~proc-move (match-string 1 in-reply-to) nil "+R-N"))

View File

@ -1,4 +1,4 @@
;;; mu4e-headers.el -- part of mu4e, the mu mail user agent ;;; mu4e-headers.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; ;;
;; Copyright (C) 2011-2017 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2017 Dirk-Jan C. Binnema
@ -1809,10 +1809,10 @@ do nothing."
;; emacs has weird ideas about what horizontal, vertical means... ;; emacs has weird ideas about what horizontal, vertical means...
(horizontal (horizontal
(window-resize hwin n nil) (window-resize hwin n nil)
(incf mu4e-headers-visible-lines n)) (cl-incf mu4e-headers-visible-lines n))
(vertical (vertical
(window-resize hwin n t) (window-resize hwin n t)
(incf mu4e-headers-visible-columns n))))))) (cl-incf mu4e-headers-visible-columns n)))))))
(defun mu4e-headers-split-view-shrink (&optional n) (defun mu4e-headers-split-view-shrink (&optional n)
"In split-view, shrink the headers window. "In split-view, shrink the headers window.

View File

@ -41,8 +41,7 @@
(require 'mu4e) (require 'mu4e)
(require 'gnus-icalendar) (require 'gnus-icalendar)
(require 'cl-lib)
(eval-when-compile (require 'cl))
;;;###autoload ;;;###autoload
(defun mu4e-icalendar-setup () (defun mu4e-icalendar-setup ()

View File

@ -1,4 +1,4 @@
;;; mu4e-main.el -- part of mu4e, the mu mail user agent ;;; mu4e-main.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; ;;
;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema
@ -27,9 +27,7 @@
(require 'smtpmail) ;; the queing stuff (silence elint) (require 'smtpmail) ;; the queing stuff (silence elint)
(require 'mu4e-utils) ;; utility functions (require 'mu4e-utils) ;; utility functions
(require 'mu4e-context) ;; the context (require 'mu4e-context) ;; the context
(require 'cl-lib)
(eval-when-compile
(require 'cl))
(defconst mu4e~main-buffer-name " *mu4e-main*" (defconst mu4e~main-buffer-name " *mu4e-main*"
"*internal* Name of the mu4e main view buffer.") "*internal* Name of the mu4e main view buffer.")
@ -99,9 +97,8 @@ clicked."
(func (if (functionp func-or-shortcut) (func (if (functionp func-or-shortcut)
func-or-shortcut func-or-shortcut
(if (stringp func-or-shortcut) (if (stringp func-or-shortcut)
(lexical-let ((macro func-or-shortcut)) (lambda()(interactive)
(lambda()(interactive) (execute-kbd-macro func-or-shortcut))))))
(execute-kbd-macro macro)))))))
(define-key map [mouse-2] func) (define-key map [mouse-2] func)
(define-key map (kbd "RET") func) (define-key map (kbd "RET") func)
(put-text-property 0 (length newstr) 'keymap map newstr) (put-text-property 0 (length newstr) 'keymap map newstr)

View File

@ -1,4 +1,4 @@
;;; mu4e-utils.el -- part of mu4e, the mu mail user agent ;;; mu4e-utils.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; ;;
;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
@ -26,7 +26,6 @@
;;; Code: ;;; Code:
(eval-when-compile (eval-when-compile
(require 'cl)
(require 'org nil 'noerror)) (require 'org nil 'noerror))
(require 'cl-lib) (require 'cl-lib)
(require 'mu4e-vars) (require 'mu4e-vars)
@ -97,7 +96,7 @@ insensitive comparison is used."
`funcall'." `funcall'."
(declare (indent 2)) (declare (indent 2))
`(let* ((vars (and ,context (mu4e-context-vars ,context)))) `(let* ((vars (and ,context (mu4e-context-vars ,context))))
(progv ;; XXX: perhaps use eval's lexical environment instead of progv? (cl-progv ;; XXX: perhaps use eval's lexical environment instead of progv?
(mapcar (lambda(cell) (car cell)) vars) (mapcar (lambda(cell) (car cell)) vars)
(mapcar (lambda(cell) (cdr cell)) vars) (mapcar (lambda(cell) (cdr cell)) vars)
(eval ,@body)))) (eval ,@body))))
@ -143,9 +142,8 @@ return the result."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-remove-file-later (filename) (defun mu4e-remove-file-later (filename)
"Remove FILENAME in a few seconds." "Remove FILENAME in a few seconds."
(lexical-let ((filename filename)) (run-at-time "30 sec" nil
(run-at-time "30 sec" nil (lambda () (ignore-errors (delete-file filename)))))
(lambda () (ignore-errors (delete-file filename))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -469,11 +467,12 @@ replaces any existing bookmark with KEY."
(lambda (bm) (lambda (bm)
(= (mu4e-bookmark-key bm) key)) (= (mu4e-bookmark-key bm) key))
(mu4e-bookmarks))) (mu4e-bookmarks)))
(add-to-list 'mu4e-bookmarks (cl-pushnew (make-mu4e-bookmark
(make-mu4e-bookmark
:name name :name name
:query query :query query
:key key) t)) :key key)
mu4e-bookmarks
:test 'equal))
;;; converting flags->string and vice-versa ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; converting flags->string and vice-versa ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -702,7 +701,7 @@ This is used by the completion function in mu4e-compose."
(setq mu4e~contacts (make-hash-table :test 'equal :weakness nil (setq mu4e~contacts (make-hash-table :test 'equal :weakness nil
:size (length contacts)))) :size (length contacts))))
(dolist (contact contacts) (dolist (contact contacts)
(incf n) (cl-incf n)
(let ((address (let ((address
(if (functionp mu4e-contact-process-function) (if (functionp mu4e-contact-process-function)
(funcall mu4e-contact-process-function (car contact)) (funcall mu4e-contact-process-function (car contact))
@ -789,33 +788,32 @@ first. If mu4e is already running, execute function FUNC (if
non-nil). Otherwise, check various requireme`'nts, then start mu4e. non-nil). Otherwise, check various requireme`'nts, then start mu4e.
When successful, call FUNC (if non-nil) afterwards." When successful, call FUNC (if non-nil) afterwards."
;; if we're already running, simply go to the main view ;; if we're already running, simply go to the main view
(if (mu4e-running-p) ;; already running? (if (mu4e-running-p) ;; already running?
(when func (funcall func)) ;; yes! run func if defined (when func (funcall func)) ;; yes! run func if defined
(progn (progn
;; no! try to set a context, do some checks, set up pong handler and ping ;; no! try to set a context, do some checks, set up pong handler and ping
;; the server maybe switch the context ;; the server maybe switch the context
(mu4e~context-autoswitch nil mu4e-context-policy) (mu4e~context-autoswitch nil mu4e-context-policy)
(lexical-let ((func func)) (mu4e~check-requirements)
(mu4e~check-requirements) ;; set up the 'pong' handler func
;; set up the 'pong' handler func (setq mu4e-pong-func
(setq mu4e-pong-func (lambda (props)
(lambda (props) (setq mu4e~server-props props) ;; save props from the server
(setq mu4e~server-props props) ;; save props from the server (let ((version (plist-get props :version))
(let ((version (plist-get props :version)) (doccount (plist-get props :doccount)))
(doccount (plist-get props :doccount))) (mu4e~check-requirements)
(mu4e~check-requirements) (when func (funcall func))
(when func (funcall func)) (when (zerop doccount)
(when (zerop doccount) (mu4e-message "Store is empty; (re)indexing. This can take a while.") ;
(mu4e-message "Store is empty; (re)indexing. This can take a while."); (mu4e-update-index))
(mu4e-update-index)) (when (and mu4e-update-interval (null mu4e~update-timer))
(when (and mu4e-update-interval (null mu4e~update-timer)) (setq mu4e~update-timer
(setq mu4e~update-timer
(run-at-time (run-at-time
0 mu4e-update-interval 0 mu4e-update-interval
(lambda () (mu4e-update-mail-and-index (lambda () (mu4e-update-mail-and-index
mu4e-index-update-in-background))))) mu4e-index-update-in-background)))))
(mu4e-message "Started mu4e with %d message%s in store" (mu4e-message "Started mu4e with %d message%s in store"
doccount (if (= doccount 1) "" "s")))))) doccount (if (= doccount 1) "" "s")))))
;; wake up server ;; wake up server
(mu4e~proc-ping) (mu4e~proc-ping)
;; maybe request the list of contacts, automatically refresh after ;; maybe request the list of contacts, automatically refresh after
@ -1084,10 +1082,10 @@ This includes expanding e.g. 3-5 into 3,4,5. If the letter
(setq beg (string-to-number (match-string 1 elem)) (setq beg (string-to-number (match-string 1 elem))
end (string-to-number (match-string 2 elem))) end (string-to-number (match-string 2 elem)))
(while (<= beg end) (while (<= beg end)
(add-to-list 'list beg 'append) (cl-pushnew beg list :test 'equal)
(setq beg (1+ beg)))) (setq beg (1+ beg))))
;; else just a number ;; else just a number
(add-to-list 'list (string-to-number elem) 'append))) (cl-pushnew (string-to-number elem) list :test 'equal)))
;; Check that all numbers are valid. ;; Check that all numbers are valid.
(mapc (mapc
#'(lambda (x) #'(lambda (x)
@ -1167,15 +1165,15 @@ displaying it). Do _not_ bury the current buffer, though."
(interactive) (interactive)
(unless (file-exists-p path) (unless (file-exists-p path)
(mu4e-error "Cannot find %s" path)) (mu4e-error "Cannot find %s" path))
(lexical-let ((curbuf (current-buffer))) (let ((curbuf (current-buffer)))
(find-file path) (find-file path)
(mu4e-org-mode) (mu4e-org-mode)
(setq buffer-read-only t) (setq buffer-read-only t)
(define-key mu4e-org-mode-map (kbd "q") (define-key mu4e-org-mode-map (kbd "q")
(lambda () `(lambda ()
(interactive) (interactive)
(bury-buffer) (bury-buffer)
(switch-to-buffer curbuf))))) (switch-to-buffer ,curbuf)))))
(defun mu4e-about () (defun mu4e-about ()
"Show the mu4e 'about' page." "Show the mu4e 'about' page."

View File

@ -1,4 +1,4 @@
;;; mu4e-view.el -- part of mu4e, the mu mail user agent ;;; mu4e-view.el -- part of mu4e, the mu mail user agent -*- lexical-binding: t -*-
;; ;;
;; Copyright (C) 2011-2018 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2018 Dirk-Jan C. Binnema
@ -26,8 +26,6 @@
;; viewing e-mail messages ;; viewing e-mail messages
;;; Code: ;;; Code:
(eval-when-compile
(require 'cl))
(require 'cl-lib) (require 'cl-lib)
(require 'mu4e-utils) ;; utility functions (require 'mu4e-utils) ;; utility functions
(require 'mu4e-vars) (require 'mu4e-vars)
@ -47,6 +45,8 @@
(require 'calendar) (require 'calendar)
(declare-function mu4e-view-mode "mu4e-view") (declare-function mu4e-view-mode "mu4e-view")
(defvar gnus-icalendar-additional-identities)
(defvar mu4e~headers-view-win)
;; the message view ;; the message view
(defgroup mu4e-view nil (defgroup mu4e-view nil
@ -208,6 +208,12 @@ message extracted at some path.")
(defvar mu4e~view-attach-map nil (defvar mu4e~view-attach-map nil
"A mapping of user-visible attachment number to the actual part index.") "A mapping of user-visible attachment number to the actual part index.")
(put 'mu4e~view-attach-map 'permanent-local t) (put 'mu4e~view-attach-map 'permanent-local t)
(defvar mu4e~view-rendering nil)
(defvar mu4e~view-html-text nil
"Should we prefer html or text just this once? A symbol `text'
or `html' or nil.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-view-message-with-message-id (msgid) (defun mu4e-view-message-with-message-id (msgid)
@ -635,7 +641,7 @@ add text-properties to VAL."
(let ((index (mu4e-message-part-field part :index)) (let ((index (mu4e-message-part-field part :index))
(name (mu4e-message-part-field part :name)) (name (mu4e-message-part-field part :name))
(size (mu4e-message-part-field part :size))) (size (mu4e-message-part-field part :size)))
(incf id) (cl-incf id)
(puthash id index mu4e~view-attach-map) (puthash id index mu4e~view-attach-map)
(concat (concat
@ -921,14 +927,12 @@ The browser that is called depends on
`browse-url-browser-function' and `browse-url-mailto-function'." `browse-url-browser-function' and `browse-url-mailto-function'."
(save-match-data (save-match-data
(if (string-match "^mailto:" url) (if (string-match "^mailto:" url)
(lexical-let ((url url))
(lambda () (lambda ()
(interactive) (interactive)
(browse-url-mail url))) (browse-url-mail url))
(lexical-let ((url url)) (lambda ()
(lambda () (interactive)
(interactive) (browse-url url)))))
(browse-url url))))))
(defun mu4e~view-browse-url-from-binding (&optional url) (defun mu4e~view-browse-url-from-binding (&optional url)
"View in browser the url at point, or click location. "View in browser the url at point, or click location.
@ -945,7 +949,7 @@ If the url is mailto link, start writing an email to that address."
"Show attached images, if `mu4e-show-images' is non-nil." "Show attached images, if `mu4e-show-images' is non-nil."
(when (and (display-images-p) mu4e-view-show-images) (when (and (display-images-p) mu4e-view-show-images)
(mu4e-view-for-each-part msg (mu4e-view-for-each-part msg
(lambda (msg part) (lambda (_msg part)
(when (string-match "^image/" (when (string-match "^image/"
(or (mu4e-message-part-field part :mime-type) (or (mu4e-message-part-field part :mime-type)
"application/object-stream")) "application/object-stream"))
@ -976,7 +980,7 @@ Also number them so they can be opened using `mu4e-view-go-to-url'."
(when bounds (when bounds
(let* ((url (thing-at-point-url-at-point)) (let* ((url (thing-at-point-url-at-point))
(ov (make-overlay (car bounds) (cdr bounds)))) (ov (make-overlay (car bounds) (cdr bounds))))
(puthash (incf num) url mu4e~view-link-map) (puthash (cl-incf num) url mu4e~view-link-map)
(add-text-properties (add-text-properties
(car bounds) (car bounds)
(cdr bounds) (cdr bounds)
@ -1074,10 +1078,6 @@ the new docid. Otherwise, return nil."
(mu4e-view-refresh) (mu4e-view-refresh)
(mu4e~view-hide-cited))) (mu4e~view-hide-cited)))
(defvar mu4e~view-html-text nil
"Should we prefer html or text just this once? A symbol `text'
or `html' or nil.")
(defun mu4e-view-toggle-html () (defun mu4e-view-toggle-html ()
"Toggle html-display of the message body (if any)." "Toggle html-display of the message body (if any)."
(interactive) (interactive)
@ -1189,7 +1189,7 @@ Add this function to `mu4e-view-mode-hook' to enable this feature."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; attachment handling ;; attachment handling
(defun mu4e~view-get-attach-num (prompt msg &optional multi) (defun mu4e~view-get-attach-num (prompt _msg &optional multi)
"Ask the user with PROMPT for an attachment number for MSG, and "Ask the user with PROMPT for an attachment number for MSG, and
ensure it is valid. The number is [1..n] for attachments ensure it is valid. The number is [1..n] for attachments
\[0..(n-1)] in the message. If MULTI is nil, return the number for \[0..(n-1)] in the message. If MULTI is nil, return the number for
@ -1591,7 +1591,7 @@ this is the default, you may not need it."
(defun mu4e-view-for-each-uri (func) (defun mu4e-view-for-each-uri (func)
"Evaluate FUNC(uri) for each uri in the current message." "Evaluate FUNC(uri) for each uri in the current message."
(maphash (lambda (num uri) (funcall func uri)) mu4e~view-link-map)) (maphash (lambda (_num uri) (funcall func uri)) mu4e~view-link-map))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@ -197,9 +197,10 @@ and images in a multipart/related part."
url (file-name-directory current-file))) url (file-name-directory current-file)))
(ext (file-name-extension path)) (ext (file-name-extension path))
(id (replace-regexp-in-string "[\/\\\\]" "_" path))) (id (replace-regexp-in-string "[\/\\\\]" "_" path)))
(add-to-list 'html-images (cl-pushnew (org~mu4e-mime-file
(org~mu4e-mime-file (concat "image/" ext) path id)
(concat "image/" ext) path id)) html-images
:test 'equal)
id))) id)))
str) str)
html-images))) html-images)))

View File

@ -143,9 +143,10 @@ and images in a multipart/related part."
url (file-name-directory current-file))) url (file-name-directory current-file)))
(ext (file-name-extension path)) (ext (file-name-extension path))
(id (replace-regexp-in-string "[\/\\\\]" "_" path))) (id (replace-regexp-in-string "[\/\\\\]" "_" path)))
(add-to-list 'html-images (cl-pushnew (org~mu4e-mime-file
(org~mu4e-mime-file (concat "image/" ext) path id)
(concat "image/" ext) path id)) html-images
:test 'equal)
id))) id)))
str) str)
html-images))) html-images)))