:group 'coolj
:type 'regexp)
-(defvar coolj-wrap-point nil)
-
-(make-variable-buffer-local 'coolj-wrap-point)
+(defvar-local coolj-wrap-point nil)
(defun coolj-determine-prefix ()
"Determine the prefix for the current line."
This variable is set by calling `notmuch-address-harvest'.")
(defvar notmuch-address-full-harvest-finished nil
- "t indicates that full completion address harvesting has been finished.
-Use notmuch-address--harvest-ready to access as that will load a
-saved hash if necessary (and available).")
+ "Whether full completion address harvesting has finished.
+Use `notmuch-address--harvest-ready' to access as that will load
+a saved hash if necessary (and available).")
(defun notmuch-address--harvest-ready ()
"Return t if there is a full address hash available.
(ding))))
(t nil)))
-;; Copied from `w3m-which-command'.
-(defun notmuch-address-locate-command (command)
- "Return non-nil if `command' is an executable either on
-`exec-path' or an absolute pathname."
- (and (stringp command)
- (if (and (file-name-absolute-p command)
- (file-executable-p command))
- command
- (setq command (file-name-nondirectory command))
- (catch 'found-command
- (let (bin)
- (dolist (dir exec-path)
- (setq bin (expand-file-name command dir))
- (when (or (and (file-executable-p bin)
- (not (file-directory-p bin)))
- (and (file-executable-p (setq bin (concat bin ".exe")))
- (not (file-directory-p bin))))
- (throw 'found-command bin))))))))
-
(defun notmuch-address-harvest-addr (result)
(let ((name-addr (plist-get result :name-addr)))
(puthash name-addr t notmuch-address-completions)))
"Collect addresses completion candidates.
It queries the notmuch database for messages sent/received (as
-configured with `notmuch-address-command`) by the user, collects
+configured with `notmuch-address-command') by the user, collects
destination/source addresses from those messages and stores them
in `notmuch-address-completions'.
(require 'notmuch-lib)
-(defvar notmuch-company-last-prefix nil)
-(make-variable-buffer-local 'notmuch-company-last-prefix)
+(defvar-local notmuch-company-last-prefix nil)
+
(declare-function company-begin-backend "company")
(declare-function company-grab "company")
(declare-function company-mode "company")
;;;###autoload
(defun notmuch-company-setup ()
(company-mode)
- (make-local-variable 'company-backends)
- (setq company-backends '(notmuch-company))
+ (setq-local company-backends '(notmuch-company))
;; Disable automatic company completion unless an internal
;; completion method is configured. Company completion (using
;; internal completion) can still be accessed via standard company
;;; Code:
-;; emacs master has a bugfix for folding long headers when sending
-;; messages. Include the fix for earlier versions of emacs. To avoid
-;; interfering with gnus we only run the hook when called from
-;; notmuch-message-mode.
+;; Before Emacs 26.1 lines that are longer than 998 octets were not.
+;; folded. Commit 77bbca8c82f6e553c42abbfafca28f55fc995d00 fixed
+;; that. Until we drop support for Emacs 25 we have to backport that
+;; fix. To avoid interfering with Gnus we only run the hook when
+;; called from notmuch-message-mode.
(declare-function mail-header-fold-field "mail-parse" nil)
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
(defcustom notmuch-crypto-process-mime t
- "Should cryptographic MIME parts be processed?
+ "Whether to process cryptographic MIME parts.
If this variable is non-nil signatures in multipart/signed
messages will be verified and multipart/encrypted parts will be
:group 'notmuch-crypto)
(defcustom notmuch-crypto-get-keys-asynchronously t
- "Retrieve gpg keys asynchronously."
+ "Whether to retrieve openpgp keys asynchronously."
:type 'boolean
:group 'notmuch-crypto)
:supertype 'notmuch-button-type)
(defun notmuch-crypto-insert-sigstatus-button (sigstatus from)
- "Insert a button describing the signature status SIGSTATUS sent
-by user FROM."
+ "Insert a button describing the signature status SIGSTATUS sent by user FROM."
(let* ((status (plist-get sigstatus :status))
(show-button t)
(face 'notmuch-crypto-signature-unknown)
"<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
"Regular expression matching mml tags indicating encryption of part or message.")
-(defvar notmuch-draft-id nil
+(defvar-local notmuch-draft-id nil
"Message-id of the most recent saved draft of this message.")
-(make-variable-buffer-local 'notmuch-draft-id)
(defun notmuch-draft--mark-deleted ()
"Tag the last saved draft deleted.
(notmuch-tag notmuch-draft-id '("+deleted"))))
(defun notmuch-draft-quote-some-mml ()
- "Quote the mml tags in `notmuch-draft-quoted-tags`."
+ "Quote the mml tags in `notmuch-draft-quoted-tags'."
(save-excursion
;; First we deal with any secure tag separately.
(message-goto-body)
(insert "!"))))))
(defun notmuch-draft-unquote-some-mml ()
- "Unquote the mml tags in `notmuch-draft-quoted-tags`."
+ "Unquote the mml tags in `notmuch-draft-quoted-tags'."
(save-excursion
(when notmuch-draft-quoted-tags
(let ((re (concat "<#!+/?\\("
(let (secure-tag)
(save-restriction
(message-narrow-to-headers)
- (setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't))
+ (setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" t))
(message-remove-header "X-Notmuch-Emacs-Secure"))
(message-goto-body)
(when secure-tag
"Returns t if there is an mml secure tag."
(save-excursion
(message-goto-body)
- (re-search-forward notmuch-draft-encryption-tag-regex nil 't)))
+ (re-search-forward notmuch-draft-encryption-tag-regex nil t)))
(defun notmuch-draft--query-encryption ()
"Checks if we should save a message that should be encrypted.
"Save the current draft message in the notmuch database.
This saves the current message in the database with tags
-`notmuch-draft-tags` (in addition to any default tags
+`notmuch-draft-tags' (in addition to any default tags
applied to newly inserted messages)."
(interactive)
(when (notmuch-draft--has-encryption-tag)
;; so that it is easier to search for the message, and the
;; latter so we have a way of accessing the saved message (for
;; example to delete it at a later time). We check that the
- ;; user has these in `message-deletable-headers` (the default)
+ ;; user has these in `message-deletable-headers' (the default)
;; as otherwise they are doing something strange and we
;; shouldn't interfere. Note, since we are doing this in a new
;; buffer we don't change the version in the compose buffer.
(notmuch-draft-quote-some-mml)
(notmuch-maildir-setup-message-for-saving)
(notmuch-maildir-notmuch-insert-current-buffer
- notmuch-draft-folder 't notmuch-draft-tags))
+ notmuch-draft-folder t notmuch-draft-tags))
;; We are now back in the original compose buffer. Note the
;; function notmuch-call-notmuch-process (called by
;; notmuch-maildir-notmuch-insert-current-buffer) signals an error
;;; Code:
-(eval-when-compile (require 'cl-lib))
-
+(require 'cl-lib)
(require 'widget)
(require 'wid-edit) ; For `widget-forward'.
shown. If not present then the :query property
is used.
:sort-order Specify the sort order to be used for the search.
- Possible values are 'oldest-first 'newest-first or
- nil. Nil means use the default sort order.
+ Possible values are `oldest-first', `newest-first'
+ or nil. Nil means use the default sort order.
:search-type Specify whether to run the search in search-mode,
tree mode or unthreaded mode. Set to 'tree to specify tree
mode, 'unthreaded to specify unthreaded mode, and set to nil
:group 'notmuch-hello
:group 'notmuch-hooks)
-(defvar notmuch-hello-url "https://notmuchmail.org"
+(defconst notmuch-hello-url "https://notmuchmail.org"
"The `notmuch' web site.")
(defvar notmuch-hello-custom-section-options
"List of sections titles whose contents are hidden.")
(defvar notmuch-hello-first-run t
- "True if `notmuch-hello' is run for the first time, set to nil
-afterwards.")
+ "True if `notmuch-hello' is run for the first time, set to nil afterwards.")
(defun notmuch-hello-nice-number (n)
(let (result)
(format "%s%03d" notmuch-hello-thousands-separator elem))
(cdr result)))))
-(defun notmuch-hello-trim (search)
- "Trim whitespace."
- (if (string-match "^[[:space:]]*\\(.*[^[:space:]]\\)[[:space:]]*$" search)
- (match-string 1 search)
- search))
-
(defun notmuch-hello-search (&optional search)
(unless (null search)
- (setq search (notmuch-hello-trim search))
+ (setq search (string-trim search))
(let ((history-delete-duplicates t))
(add-to-history 'notmuch-search-history search)))
(notmuch-search search notmuch-search-oldest-first))
--batch'. In general we recommend running matching versions of
the CLI and emacs interface."))
(goto-char (point-min))
- (notmuch-remove-if-not
- #'identity
- (mapcar
- (lambda (elem)
- (let* ((elem-plist (notmuch-hello-saved-search-to-plist elem))
- (search-query (plist-get elem-plist :query))
- (filtered-query (notmuch-hello-filtered-query
- search-query (plist-get options :filter)))
- (message-count (prog1 (read (current-buffer))
- (forward-line 1))))
- (when (and filtered-query (or (plist-get options :show-empty-searches)
- (> message-count 0)))
- (setq elem-plist (plist-put elem-plist :query filtered-query))
- (plist-put elem-plist :count message-count))))
- query-list))))
+ (cl-mapcan
+ (lambda (elem)
+ (let* ((elem-plist (notmuch-hello-saved-search-to-plist elem))
+ (search-query (plist-get elem-plist :query))
+ (filtered-query (notmuch-hello-filtered-query
+ search-query (plist-get options :filter)))
+ (message-count (prog1 (read (current-buffer))
+ (forward-line 1))))
+ (when (and filtered-query (or (plist-get options :show-empty-searches)
+ (> message-count 0)))
+ (setq elem-plist (plist-put elem-plist :query filtered-query))
+ (list (plist-put elem-plist :count message-count)))))
+ query-list)))
(defun notmuch-hello-insert-buttons (searches)
"Insert buttons for SEARCHES.
;; Refresh hello as soon as we get back to redisplay. On Emacs
;; 24, we can't do it right here because something in this
;; hook's call stack overrides hello's point placement.
+ ;; FIXME And on Emacs releases that we still support?
(run-at-time nil nil #'notmuch-hello t))
(unless hello-buf
;; Clean up hook
(remove-hook 'window-configuration-change-hook
#'notmuch-hello-window-configuration-change))))
-;; the following variable is defined as being defconst in notmuch-version.el
-(defvar notmuch-emacs-version)
-
-(defun notmuch-hello-versions ()
- "Display the notmuch version(s)."
- (interactive)
- (let ((notmuch-cli-version (notmuch-cli-version)))
- (message "notmuch version %s"
- (if (string= notmuch-emacs-version notmuch-cli-version)
- notmuch-cli-version
- (concat notmuch-cli-version
- " (emacs mua version " notmuch-emacs-version ")")))))
-
(defvar notmuch-hello-mode-map
- (let ((map (if (fboundp 'make-composed-keymap)
- ;; Inherit both widget-keymap and
- ;; notmuch-common-keymap. We have to use
- ;; make-sparse-keymap to force this to be a new
- ;; keymap (so that when we modify map it does not
- ;; modify widget-keymap).
- (make-composed-keymap (list (make-sparse-keymap) widget-keymap))
- ;; Before Emacs 24, keymaps didn't support multiple
- ;; inheritance,, so just copy the widget keymap since
- ;; it's unlikely to change.
- (copy-keymap widget-keymap))))
+ ;; Inherit both widget-keymap and notmuch-common-keymap. We have
+ ;; to use make-sparse-keymap to force this to be a new keymap (so
+ ;; that when we modify map it does not modify widget-keymap).
+ (let ((map (make-composed-keymap (list (make-sparse-keymap) widget-keymap))))
(set-keymap-parent map notmuch-common-keymap)
- (define-key map "v" 'notmuch-hello-versions)
(define-key map (kbd "<C-tab>") 'widget-backward)
map)
"Keymap for \"notmuch hello\" buffers.")
(defun notmuch-hello-generate-tag-alist (&optional hide-tags)
"Return an alist from tags to queries to display in the all-tags section."
- (mapcar (lambda (tag)
- (cons tag (concat "tag:" (notmuch-escape-boolean-term tag))))
- (notmuch-remove-if-not
- (lambda (tag)
- (not (member tag hide-tags)))
- (process-lines notmuch-command "search" "--output=tags" "*"))))
+ (cl-mapcan (lambda (tag)
+ (and (not (member tag hide-tags))
+ (list (cons tag
+ (concat "tag:"
+ (notmuch-escape-boolean-term tag))))))
+ (process-lines notmuch-command "search" "--output=tags" "*")))
(defun notmuch-hello-insert-header ()
"Insert the default notmuch-hello header."
(run-hooks 'notmuch-hello-refresh-hook)
(setq notmuch-hello-first-run nil))
-(defun notmuch-folder ()
- "Deprecated function for invoking notmuch---calling `notmuch' is preferred now."
- (interactive)
- (notmuch-hello))
-
;;
(provide 'notmuch-hello)
(require 'notmuch-lib)
(require 'notmuch-hello)
-(eval-and-compile
- (unless (fboundp 'window-body-width)
- ;; Compatibility for Emacs pre-24
- (defalias 'window-body-width 'window-width)))
-
;;;###autoload
(defun notmuch-jump-search ()
"Jump to a saved search by shortcut key.
(defvar notmuch-common-keymap
(let ((map (make-sparse-keymap)))
(define-key map "?" 'notmuch-help)
+ (define-key map "v" 'notmuch-version)
(define-key map "q" 'notmuch-bury-or-kill-this-buffer)
(define-key map "s" 'notmuch-search)
(define-key map "t" 'notmuch-search-by-tag)
(match-string 2 long-string)
"unknown")))
+(defvar notmuch-emacs-version)
+
+(defun notmuch-version ()
+ "Display the notmuch version.
+The versions of the Emacs package and the `notmuch' executable
+should match, but if and only if they don't, then this command
+displays both values separately."
+ (interactive)
+ (let ((cli-version (notmuch-cli-version)))
+ (message "notmuch version %s"
+ (if (string= notmuch-emacs-version cli-version)
+ cli-version
+ (concat cli-version
+ " (emacs mua version " notmuch-emacs-version ")")))))
+
(defun notmuch-config-get (item)
"Return a value from the notmuch configuration."
(let* ((val (notmuch-command-to-string "config" "get" item))
(bury-buffer)
(kill-buffer)))
-(defun notmuch-documentation-first-line (symbol)
- "Return the first line of the documentation string for SYMBOL."
- (let ((doc (documentation symbol)))
- (if doc
- (with-temp-buffer
- (insert (documentation symbol t))
- (goto-char (point-min))
- (let ((beg (point)))
- (end-of-line)
- (buffer-substring beg (point))))
- "")))
-
(defun notmuch-prefix-key-description (key)
"Given a prefix key code, return a human-readable string representation.
(or (and (symbolp binding)
(get binding 'notmuch-doc))
(and (functionp binding)
- (notmuch-documentation-first-line binding))))
+ (let ((doc (documentation binding)))
+ (and doc
+ (string-match "\\`.+" doc)
+ (match-string 0 doc))))))
tail)))
tail)
(insert desc)))
(pop-to-buffer (help-buffer)))))
-(defvar notmuch-buffer-refresh-function nil
+(defvar-local notmuch-buffer-refresh-function nil
"Function to call to refresh the current buffer.")
-(make-variable-buffer-local 'notmuch-buffer-refresh-function)
(defun notmuch-refresh-this-buffer ()
"Refresh the current buffer."
;;
-(defun notmuch-remove-if-not (predicate list)
- "Return a copy of LIST with all items not satisfying PREDICATE removed."
- (let (out)
- (while list
- (when (funcall predicate (car list))
- (push (car list) out))
- (setq list (cdr list)))
- (nreverse out)))
-
(defun notmuch-plist-delete (plist property)
(let* ((xplist (cons nil plist))
(pred xplist))
(setq pred (cddr pred)))
(cdr xplist)))
-(defun notmuch-split-content-type (content-type)
- "Split content/type into 'content' and 'type'."
- (split-string content-type "/"))
-
(defun notmuch-match-content-type (t1 t2)
"Return t if t1 and t2 are matching content types, taking wildcards into account."
- (let ((st1 (notmuch-split-content-type t1))
- (st2 (notmuch-split-content-type t2)))
+ (let ((st1 (split-string t1 "/"))
+ (st2 (split-string t2 "/")))
(if (or (string= (cadr st1) "*")
(string= (cadr st2) "*"))
;; Comparison of content types should be case insensitive.
MSG (if it isn't already)."
(notmuch--get-bodypart-raw msg part process-crypto nil cache))
-;; Workaround: The call to `mm-display-part' below triggers a bug in
-;; Emacs 24 if it attempts to use the shr renderer to display an HTML
-;; part with images in it (demonstrated in 24.1 and 24.2 on Debian and
-;; Fedora 17, though unreproducible in other configurations).
-;; `mm-shr' references the variable `gnus-inhibit-images' without
-;; first loading gnus-art, which defines it, resulting in a
-;; void-variable error. Hence, we advise `mm-shr' to ensure gnus-art
-;; is loaded.
-(define-advice mm-shr (:before (_handle) notmuch--load-gnus-args)
- "Require `gnus-art' since we use its variables."
- (require 'gnus-art nil t))
-
(defun notmuch-mm-display-part-inline (msg part content-type process-crypto)
"Use the mm-decode/mm-view functions to display a part in the
current buffer, if possible."
(find-file-noselect err-file))))
(when err-buffer (kill-buffer err-buffer))))
-;; This variable is used only buffer local, but it needs to be
-;; declared globally first to avoid compiler warnings.
-(defvar notmuch-show-process-crypto nil)
-(make-variable-buffer-local 'notmuch-show-process-crypto)
+(defvar-local notmuch-show-process-crypto nil)
(defun notmuch-interactive-region ()
"Return the bounds of the current interactive region.
:require 'notmuch-fcc-initialization
:group 'notmuch-send)
-(defcustom notmuch-maildir-use-notmuch-insert 't
+(defcustom notmuch-maildir-use-notmuch-insert t
"Should fcc use notmuch insert instead of simple fcc."
:type '(choice :tag "Fcc Method"
(const :tag "Use notmuch insert" t)
(defun notmuch-fcc-handler (fcc-header)
"Store message with notmuch insert or normal (file) fcc.
-If `notmuch-maildir-use-notmuch-insert` is set then store the
+If `notmuch-maildir-use-notmuch-insert' is set then store the
message using notmuch insert. Otherwise store the message using
normal fcc."
(message "Doing Fcc...")
\(r)etry, (c)reate folder, (i)gnore, or (e)dit the header? " '(?r ?c ?i ?e))))
(cl-case response
(?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header))
- (?c (notmuch-maildir-fcc-with-notmuch-insert fcc-header 't))
- (?i 't)
+ (?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)))))))))
It offers the user a chance to correct the header, or filesystem,
if needed."
(if (notmuch-maildir-fcc-dir-is-maildir-p fcc-header)
- (notmuch-maildir-fcc-write-buffer-to-maildir fcc-header 't)
+ (notmuch-maildir-fcc-write-buffer-to-maildir fcc-header t)
;; The fcc-header is not a valid maildir see if the user wants to
;; fix it in some way.
(let* ((prompt (format "Fcc %s is not a maildir: \
(message "No permission to create %s." fcc-header)
(sit-for 2))
(notmuch-maildir-fcc-file-fcc fcc-header))
- (?i 't)
+ (?i t)
(?e (notmuch-maildir-fcc-file-fcc
(read-from-minibuffer "Fcc header: " fcc-header)))))))
:group 'notmuch-hooks)
(defcustom notmuch-mua-compose-in 'current-window
- (concat
- "Where to create the mail buffer used to compose a new message.
+ "Where to create the mail buffer used to compose a new message.
Possible values are `current-window' (default), `new-window' and
`new-frame'. If set to `current-window', the mail buffer will be
displayed in the current window, so the old buffer will be
window/frame that will be destroyed when the buffer is killed.
You may want to customize `message-kill-buffer-on-exit'
accordingly."
- (when (< emacs-major-version 24)
- " Due to a known bug in Emacs 23, you should not set
-this to `new-window' if `message-kill-buffer-on-exit' is
-disabled: this would result in an incorrect behavior."))
:group 'notmuch-send
:type '(choice (const :tag "Compose in the current window" current-window)
(const :tag "Compose mail in a new window" new-window)
(const :tag "Compose mail in a new frame" new-frame)))
(defcustom notmuch-mua-user-agent-function nil
- "Function used to generate a `User-Agent:' string. If this is
-`nil' then no `User-Agent:' will be generated."
+ "Function used to generate a `User-Agent:' string.
+If this is `nil' then no `User-Agent:' will be generated."
:type '(choice (const :tag "No user agent string" nil)
(const :tag "Full" notmuch-mua-user-agent-full)
(const :tag "Notmuch" notmuch-mua-user-agent-notmuch)
:group 'notmuch-send)
(defcustom notmuch-mua-hidden-headers nil
- "Headers that are added to the `message-mode' hidden headers
-list."
+ "Headers that are added to the `message-mode' hidden headers list."
:type '(repeat string)
:group 'notmuch-send)
:group 'notmuch)
(defcustom notmuch-mua-cite-function 'message-cite-original
- "*Function for citing an original message.
+ "Function for citing an original message.
+
Predefined functions include `message-cite-original' and
-`message-cite-original-without-signature'.
-Note that these functions use `mail-citation-hook' if that is non-nil."
+`message-cite-original-without-signature'. Note that these
+functions use `mail-citation-hook' if that is non-nil."
:type '(radio (function-item message-cite-original)
(function-item message-cite-original-without-signature)
(function-item sc-cite-original)
(t (error "Invalid value for `notmuch-mua-compose-in'"))))
(defun notmuch-mua-maybe-set-window-dedicated ()
- "Set the selected window as dedicated according to
-`notmuch-mua-compose-in'."
+ "Set the selected window as dedicated according to `notmuch-mua-compose-in'."
(when (or (eq notmuch-mua-compose-in 'new-frame)
(eq notmuch-mua-compose-in 'new-window))
(set-window-dedicated-p (selected-window) t)))
"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
+;; There is a bug in Emacs' message.el that results in a newline
;; not being inserted after the References header, so the next header
;; is concatenated to the end of it. This function fixes the problem,
;; while guarding against the possibility that some current or future
(message-goto-body)
(set-buffer-modified-p nil))
+(defvar notmuch-message-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c C-c") #'notmuch-mua-send-and-exit)
+ (define-key map (kbd "C-c C-s") #'notmuch-mua-send)
+ (define-key map (kbd "C-c C-p") #'notmuch-draft-postpone)
+ (define-key map (kbd "C-x C-s") #'notmuch-draft-save)
+ map)
+ "Keymap for `notmuch-message-mode'.")
+
(define-derived-mode notmuch-message-mode message-mode "Message[Notmuch]"
"Notmuch message composition mode. Mostly like `message-mode'."
(notmuch-address-setup))
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
-(define-key notmuch-message-mode-map (kbd "C-c C-c") #'notmuch-mua-send-and-exit)
-(define-key notmuch-message-mode-map (kbd "C-c C-s") #'notmuch-mua-send)
-(define-key notmuch-message-mode-map (kbd "C-c C-p") #'notmuch-draft-postpone)
-(define-key notmuch-message-mode-map (kbd "C-x C-s") #'notmuch-draft-save)
-
(defun notmuch-mua-pop-to-buffer (name switch-function)
- "Pop to buffer NAME, and warn if it already exists and is
-modified. This function is notmuch adaptation of
-`message-pop-to-buffer'."
+ "Pop to buffer NAME, and warn if it already exists and is modified.
+Like `message-pop-to-buffer' but enable `notmuch-message-mode'
+instead of `message-mode' and SWITCH-FUNCTION is mandatory."
(let ((buffer (get-buffer name)))
(if (and buffer
(buffer-name buffer))
(dolist (h other-headers other-headers)
(when (stringp (car h))
(setcar h (intern (capitalize (car h))))))))
- (args (list yank-action send-actions))
;; Cause `message-setup-1' to do things relevant for mail,
;; such as observe `message-default-mail-headers'.
(message-this-is-mail t))
- ;; message-setup-1 in Emacs 23 does not accept return-action
- ;; argument. Pass it only if it is supplied by the caller. This
- ;; will never be the case when we're called by `compose-mail' in
- ;; Emacs 23.
- (when return-action (nconc args '(return-action)))
- (apply 'message-setup-1 headers args))
+ (message-setup-1 headers yank-action send-actions return-action))
(notmuch-fcc-header-setup)
(message-sort-headers)
(message-hide-headers)
If PROMPT-FOR-SENDER is non-nil, the user will be prompted for
the From: address first. If REPLY-ALL is non-nil, the message
will be addressed to all recipients of the source message."
- ;; In current emacs (24.3) select-active-regions is set to t by
- ;; default. The reply insertion code sets the region to the quoted
- ;; message to make it easy to delete (kill-region or C-w). These two
- ;; things combine to put the quoted message in the primary selection.
+ ;; `select-active-regions' is t by default. The reply insertion code
+ ;; sets the region to the quoted message to make it easy to delete
+ ;; (kill-region or C-w). These two things combine to put the quoted
+ ;; message in the primary selection.
;;
;; This is not what the user wanted and is a privacy risk (accidental
;; pasting of the quoted message). We can avoid some of the problems
(goto-char (point-max))
(or
;; We are always fine if there is no secure tag.
- (not (search-backward "<#secure" nil 't))
+ (not (search-backward "<#secure" nil t))
;; There is a secure tag, so it must be at the start of the
;; body, with no secure tag earlier (i.e., in the headers).
(and (= (point) body-start)
- (not (search-backward "<#secure" nil 't)))
+ (not (search-backward "<#secure" nil t)))
;; The user confirms they means it.
(yes-or-no-p "\
There is a <#secure> tag not at the start of the body. It is
(defun notmuch-mua-send-and-exit (&optional arg)
(interactive "P")
- (notmuch-mua-send-common arg 't))
+ (notmuch-mua-send-common arg t))
(defun notmuch-mua-send (&optional arg)
(interactive "P")
move point in the input buffer."
;; Set up the initial state
(unless (local-variable-p 'notmuch-sexp--parser)
- (set (make-local-variable 'notmuch-sexp--parser)
- (notmuch-sexp-create-parser))
- (set (make-local-variable 'notmuch-sexp--state) 'begin))
+ (setq-local notmuch-sexp--parser (notmuch-sexp-create-parser))
+ (setq-local notmuch-sexp--state 'begin))
(let (done)
(while (not done)
(cl-case notmuch-sexp--state
:type '(choice (const nil) regexp)
:group 'notmuch-show)
-(defvar notmuch-show-thread-id nil)
-(make-variable-buffer-local 'notmuch-show-thread-id)
+(defvar-local notmuch-show-thread-id nil)
-(defvar notmuch-show-parent-buffer nil)
-(make-variable-buffer-local 'notmuch-show-parent-buffer)
+(defvar-local notmuch-show-parent-buffer nil)
-(defvar notmuch-show-query-context nil)
-(make-variable-buffer-local 'notmuch-show-query-context)
+(defvar-local notmuch-show-query-context nil)
-(defvar notmuch-show-process-crypto nil)
-(make-variable-buffer-local 'notmuch-show-process-crypto)
+(defvar-local notmuch-show-process-crypto nil)
-(defvar notmuch-show-elide-non-matching-messages nil)
-(make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)
+(defvar-local notmuch-show-elide-non-matching-messages nil)
-(defvar notmuch-show-indent-content t)
-(make-variable-buffer-local 'notmuch-show-indent-content)
+(defvar-local notmuch-show-indent-content t)
(defvar notmuch-show-attachment-debug nil
"If t log stdout and stderr from attachment handlers.
When set to nil (the default) stdout and stderr from attachment
handlers is discarded. When set to t the stdout and stderr from
each attachment handler is logged in buffers with names beginning
-\" *notmuch-part*\". This option requires emacs version at least
-24.3 to work.")
+\" *notmuch-part*\".")
(defcustom notmuch-show-stash-mlarchive-link-alist
'(("Gmane" . "https://mid.gmane.org/")
;; alternative (even if we can't render it).
(push (list content-id msg part) notmuch-show--cids)))
;; Recurse on sub-parts
- (let ((ctype (notmuch-split-content-type
- (downcase (plist-get part :content-type)))))
- (cond ((equal (car ctype) "multipart")
+ (pcase-let ((`(,content ,type)
+ (split-string (downcase (plist-get part :content-type)) "/")))
+ (cond ((equal content "multipart")
(mapc (apply-partially #'notmuch-show--register-cids msg)
(plist-get part :content)))
- ((equal ctype '("message" "rfc822"))
+ ((and (equal content "message")
+ (equal type "rfc822"))
(notmuch-show--register-cids
msg
(car (plist-get (car (plist-get part :content)) :body)))))))
(push func result)))
;; Reverse order of prefrence.
(list (intern (concat "notmuch-show-insert-part-*/*"))
- (intern (concat
- "notmuch-show-insert-part-"
- (car (notmuch-split-content-type content-type))
- "/*"))
+ (intern (concat "notmuch-show-insert-part-"
+ (car (split-string content-type "/"))
+ "/*"))
(intern (concat "notmuch-show-insert-part-" content-type))))
result))
(define-key map "B" 'notmuch-show-browse-urls)
map)
"Keymap for \"notmuch show\" buffers.")
-(fset 'notmuch-show-mode-map notmuch-show-mode-map)
(define-derived-mode notmuch-show-mode fundamental-mode "notmuch-show"
"Major mode for viewing a thread with notmuch.
(funcall notmuch-show-mark-read-function (window-start) (window-end))
((debug error)
(unless notmuch-show--seen-has-errored
- (setq notmuch-show--seen-has-errored 't)
+ (setq notmuch-show--seen-has-errored t)
(setq header-line-format
(concat header-line-format
(propertize
(browse-url (current-kill 0 t)))
(defun notmuch-show-stash-git-helper (addresses prefix)
- "Escape, trim, quote, and add PREFIX to each address in list of ADDRESSES, and return the result as a single string."
+ "Normalize all ADDRESSES while adding PREFIX.
+Escape, trim, quote and add PREFIX to each address in list
+of ADDRESSES, and return the result as a single string."
(mapconcat (lambda (x)
(concat prefix "\""
;; escape double-quotes
addresses " "))
(put 'notmuch-show-stash-git-send-email 'notmuch-prefix-doc
- "Copy From/To/Cc of current message to kill-ring in a form suitable for pasting to git send-email command line.")
+ "Copy From/To/Cc of current message to kill-ring.
+Use a form suitable for pasting to git send-email command line.")
(defun notmuch-show-stash-git-send-email (&optional no-in-reply-to)
- "Copy From/To/Cc/Message-Id of current message to kill-ring in a form suitable for pasting to git send-email command line.
+ "Copy From/To/Cc/Message-Id of current message to kill-ring.
+Use a form suitable for pasting to git send-email command line.
If invoked with a prefix argument (or NO-IN-REPLY-TO is non-nil),
omit --in-reply-to=<Message-Id>."
is destroyed when FN returns. If MIME-TYPE is given then force
part to be treated as if it had that mime-type."
(let ((handle (notmuch-show-current-part-handle mime-type)))
- ;; emacs 24.3+ puts stdout/stderr into the calling buffer so we
- ;; call it from a temp-buffer, unless
- ;; notmuch-show-attachment-debug is non-nil in which case we put
- ;; it in " *notmuch-part*".
+ ;; Emacs puts stdout/stderr into the calling buffer so we call
+ ;; it from a temp-buffer, unless notmuch-show-attachment-debug
+ ;; is non-nil, in which case we put it in " *notmuch-part*".
(unwind-protect
(if notmuch-show-attachment-debug
(with-current-buffer (generate-new-buffer " *notmuch-part*")
be used (either as a key, or as the start of a key sequence) as
it is already bound: it switches the menu to a menu of the
reverse tagging operations. The reverse of a tagging operation is
-the same list of individual tag-ops but with `+tag` replaced by
-`-tag` and vice versa.
+the same list of individual tag-ops but with `+tag' replaced by
+`-tag' and vice versa.
If setting this variable outside of customize then it should be a
list of triples (lists of three elements). Each triple should be
of the form (key-binding tagging-operations name). KEY-BINDING
can be a single character or a key sequence; TAGGING-OPERATIONS
should either be a list of individual tag operations each of the
-form `+tag` or `-tag`, or the variable name of a variable that is
+form `+tag' or `-tag', or the variable name of a variable that is
a list of tagging operations; NAME should be a name for the
tagging operation, if omitted or empty than then name is taken
from TAGGING-OPERATIONS."
'((t :foreground "red"))
"Default face used for the unread tag.
-Used in the default value of `notmuch-tag-formats`."
+Used in the default value of `notmuch-tag-formats'."
:group 'notmuch-faces)
(defface notmuch-tag-flagged
(:foreground "blue")))
"Face used for the flagged tag.
-Used in the default value of `notmuch-tag-formats`."
+Used in the default value of `notmuch-tag-formats'."
:group 'notmuch-faces)
(defcustom notmuch-tag-formats
(t :inverse-video t))
"Face used to display deleted tags.
-Used in the default value of `notmuch-tag-deleted-formats`."
+Used in the default value of `notmuch-tag-deleted-formats'."
:group 'notmuch-faces)
(defcustom notmuch-tag-deleted-formats
(".*" (notmuch-apply-face tag `notmuch-tag-deleted)))
"Custom formats for tags when deleted.
-For deleted tags the formats in `notmuch-tag-formats` are applied
+For deleted tags the formats in `notmuch-tag-formats' are applied
first and then these formats are applied on top; that is `tag'
passed to the function is the tag with all these previous
formattings applied. The formatted can access the original
'((t :underline "green"))
"Default face used for added tags.
-Used in the default value for `notmuch-tag-added-formats`."
+Used in the default value for `notmuch-tag-added-formats'."
:group 'notmuch-faces)
(defcustom notmuch-tag-added-formats
'((".*" (notmuch-apply-face tag 'notmuch-tag-added)))
"Custom formats for tags when added.
-For added tags the formats in `notmuch-tag-formats` are applied
+For added tags the formats in `notmuch-tag-formats' are applied
first and then these formats are applied on top.
To disable special formatting of added tags, set this variable to
Creates and displays a jump menu for the tagging operations
specified in `notmuch-tagging-keys'. If REVERSE is set then it
offers a menu of the reverses of the operations specified in
-`notmuch-tagging-keys'; i.e. each `+tag` is replaced by `-tag`
+`notmuch-tagging-keys'; i.e. each `+tag' is replaced by `-tag'
and vice versa."
;; In principle this function is simple, but it has to deal with
;; lots of cases: different modes (search/show/tree), whether a name
(symbol-value tag)
tag))
(tag-change (if reverse
- (notmuch-tag-change-list tag 't)
+ (notmuch-tag-change-list tag t)
tag))
(name (or (and (not (string= name ""))
name)
(declare-function notmuch-search-find-thread-id "notmuch" (&optional bare))
(declare-function notmuch-search-find-subject "notmuch" ())
+;; For `notmuch-tree-next-thread-from-search'.
+(declare-function notmuch-search-next-thread "notmuch" ())
+(declare-function notmuch-search-previous-thread "notmuch" ())
+(declare-function notmuch-tree-from-search-thread "notmuch" ())
+
;; the following variable is defined in notmuch.el
(defvar notmuch-search-query-string)
;; this variable distinguishes the unthreaded display from the normal tree display
-(defvar notmuch-tree-unthreaded nil
+(defvar-local notmuch-tree-unthreaded nil
"A buffer local copy of argument unthreaded to the function notmuch-tree.")
-(make-variable-buffer-local 'notmuch-tree-unthreaded)
(defgroup notmuch-tree nil
"Showing message and thread structure."
:group 'notmuch-tree
:group 'notmuch-faces)
-(defvar notmuch-tree-previous-subject
+(defvar-local notmuch-tree-previous-subject
"The subject of the most recent result shown during the async display.")
-(make-variable-buffer-local 'notmuch-tree-previous-subject)
-(defvar notmuch-tree-basic-query nil
+(defvar-local notmuch-tree-basic-query nil
"A buffer local copy of argument query to the function notmuch-tree.")
-(make-variable-buffer-local 'notmuch-tree-basic-query)
-(defvar notmuch-tree-query-context nil
+(defvar-local notmuch-tree-query-context nil
"A buffer local copy of argument query-context to the function notmuch-tree.")
-(make-variable-buffer-local 'notmuch-tree-query-context)
-(defvar notmuch-tree-target-msg nil
+(defvar-local notmuch-tree-target-msg nil
"A buffer local copy of argument target to the function notmuch-tree.")
-(make-variable-buffer-local 'notmuch-tree-target-msg)
-(defvar notmuch-tree-open-target nil
+(defvar-local notmuch-tree-open-target nil
"A buffer local copy of argument open-target to the function notmuch-tree.")
-(make-variable-buffer-local 'notmuch-tree-open-target)
-(defvar notmuch-tree-parent-buffer nil)
-(make-variable-buffer-local 'notmuch-tree-parent-buffer)
+(defvar-local notmuch-tree-parent-buffer nil)
-(defvar notmuch-tree-message-window nil
+(defvar-local notmuch-tree-message-window nil
"The window of the message pane.
It is set in both the tree buffer and the child show buffer. It
is used to try and close the message pane when quitting tree view
or the child show buffer.")
-(make-variable-buffer-local 'notmuch-tree-message-window)
(put 'notmuch-tree-message-window 'permanent-local t)
-(defvar notmuch-tree-message-buffer nil
+(defvar-local notmuch-tree-message-buffer nil
"The buffer name of the show buffer in the message pane.
This is used to try and make sure we don't close the message pane
if the user has loaded a different buffer in that window.")
-(make-variable-buffer-local 'notmuch-tree-message-buffer)
(put 'notmuch-tree-message-buffer 'permanent-local t)
-(defun notmuch-tree-to-message-pane (func)
- "Execute FUNC in message pane.
-
-This function returns a function (so can be used as a keybinding)
-which executes function FUNC in the message pane if it is
-open (if the message pane is closed it does nothing)."
- `(lambda ()
- ,(concat "(In message pane) " (documentation func t))
+(defmacro notmuch-tree--define-do-in-message-window (name cmd)
+ "Define NAME as a command that calls CMD interactively in the message window.
+If the message pane is closed then this command does nothing.
+Avoid using this macro in new code; it will be removed."
+ `(defun ,name ()
+ ,(concat "(In message window) " (documentation cmd t))
(interactive)
(when (window-live-p notmuch-tree-message-window)
(with-selected-window notmuch-tree-message-window
- (call-interactively #',func)))))
-
-(defun notmuch-tree-inherit-from-message-pane (sym)
- "Return value of SYM in message-pane if open, or tree-pane if not."
+ (call-interactively #',cmd)))))
+
+(notmuch-tree--define-do-in-message-window
+ notmuch-tree-previous-message-button
+ notmuch-show-previous-button)
+(notmuch-tree--define-do-in-message-window
+ notmuch-tree-next-message-button
+ notmuch-show-next-button)
+(notmuch-tree--define-do-in-message-window
+ notmuch-tree-toggle-message-process-crypto
+ notmuch-show-toggle-process-crypto)
+
+(defun notmuch-tree--message-process-crypto ()
+ "Return value of `notmuch-show-process-crypto' in the message window.
+If that window isn't alive, then return the current value.
+Avoid using this function in new code; it will be removed."
(if (window-live-p notmuch-tree-message-window)
(with-selected-window notmuch-tree-message-window
- (symbol-value sym))
- (symbol-value sym)))
-
-(defun notmuch-tree-button-activate (&optional button)
- "Activate BUTTON or button at point.
-
-This function does not give an error if there is no button."
- (interactive)
- (let ((button (or button (button-at (point)))))
- (when button (button-activate button))))
-
-(defun notmuch-tree-close-message-pane-and (func)
- "Close message pane and execute FUNC.
-
-This function returns a function (so can be used as a keybinding)
-which closes the message pane if open and then executes function
-FUNC."
- `(lambda ()
- ,(concat "(Close message pane and) " (documentation func t))
+ notmuch-show-process-crypto)
+ notmuch-show-process-crypto))
+
+(defmacro notmuch-tree--define-close-message-window-and (name cmd)
+ "Define NAME as a variant of CMD.
+
+NAME determines the value of `notmuch-show-process-crypto' in the
+message window, closes the window, and then call CMD interactively
+with that value let-bound. If the message window does not exist,
+then NAME behaves like CMD."
+ `(defun ,name ()
+ ,(concat "(Close message pane and) " (documentation cmd t))
(interactive)
(let ((notmuch-show-process-crypto
- (notmuch-tree-inherit-from-message-pane 'notmuch-show-process-crypto)))
+ (notmuch-tree--message-process-crypto)))
(notmuch-tree-close-message-window)
- (call-interactively #',func))))
+ (call-interactively #',cmd))))
+
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-help
+ notmuch-help)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-new-mail
+ notmuch-mua-new-mail)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-jump-search
+ notmuch-jump-search)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-forward-message
+ notmuch-show-forward-message)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-reply-sender
+ notmuch-show-reply-sender)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-reply
+ notmuch-show-reply)
+(notmuch-tree--define-close-message-window-and
+ notmuch-tree-view-raw-message
+ notmuch-show-view-raw-message)
(defvar notmuch-tree-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map notmuch-common-keymap)
- ;; The following override the global keymap.
- ;; Override because we want to close message pane first.
- (define-key map [remap notmuch-help]
- (notmuch-tree-close-message-pane-and #'notmuch-help))
- ;; Override because we first close message pane and then close tree buffer.
+ ;; These bindings shadow common bindings with variants
+ ;; that additionally close the message window.
(define-key map [remap notmuch-bury-or-kill-this-buffer] 'notmuch-tree-quit)
- ;; Override because we close message pane after the search query is entered.
- (define-key map [remap notmuch-search] 'notmuch-tree-to-search)
- ;; Override because we want to close message pane first.
- (define-key map [remap notmuch-mua-new-mail]
- (notmuch-tree-close-message-pane-and #'notmuch-mua-new-mail))
- ;; Override because we want to close message pane first.
- (define-key map [remap notmuch-jump-search]
- (notmuch-tree-close-message-pane-and #'notmuch-jump-search))
+ (define-key map [remap notmuch-search] 'notmuch-tree-to-search)
+ (define-key map [remap notmuch-help] 'notmuch-tree-help)
+ (define-key map [remap notmuch-mua-new-mail] 'notmuch-tree-new-mail)
+ (define-key map [remap notmuch-jump-search] 'notmuch-tree-jump-search)
(define-key map "S" 'notmuch-search-from-tree-current-query)
(define-key map "U" 'notmuch-unthreaded-from-tree-current-query)
(define-key map "b" 'notmuch-show-resend-message)
;; these apply to the message pane
- (define-key map (kbd "M-TAB")
- (notmuch-tree-to-message-pane #'notmuch-show-previous-button))
- (define-key map (kbd "<backtab>")
- (notmuch-tree-to-message-pane #'notmuch-show-previous-button))
- (define-key map (kbd "TAB")
- (notmuch-tree-to-message-pane #'notmuch-show-next-button))
- (define-key map "$"
- (notmuch-tree-to-message-pane #'notmuch-show-toggle-process-crypto))
+ (define-key map (kbd "M-TAB") 'notmuch-tree-previous-message-button)
+ (define-key map (kbd "<backtab>") 'notmuch-tree-previous-message-button)
+ (define-key map (kbd "TAB") 'notmuch-tree-next-message-button)
+ (define-key map "$" 'notmuch-tree-toggle-message-process-crypto)
;; bindings from show (or elsewhere) but we close the message pane first.
- (define-key map "f"
- (notmuch-tree-close-message-pane-and #'notmuch-show-forward-message))
- (define-key map "r"
- (notmuch-tree-close-message-pane-and #'notmuch-show-reply-sender))
- (define-key map "R"
- (notmuch-tree-close-message-pane-and #'notmuch-show-reply))
- (define-key map "V"
- (notmuch-tree-close-message-pane-and #'notmuch-show-view-raw-message))
+ (define-key map "f" 'notmuch-tree-forward-message)
+ (define-key map "r" 'notmuch-tree-reply-sender)
+ (define-key map "R" 'notmuch-tree-reply)
+ (define-key map "V" 'notmuch-tree-view-raw-message)
;; The main tree view bindings
(define-key map (kbd "RET") 'notmuch-tree-show-message)
(define-key map " " 'notmuch-tree-scroll-or-next)
(define-key map (kbd "DEL") 'notmuch-tree-scroll-message-window-back)
(define-key map "e" 'notmuch-tree-resume-message)
- map))
-(fset 'notmuch-tree-mode-map notmuch-tree-mode-map)
+ map)
+ "Keymap for \"notmuch tree\" buffers.")
(defun notmuch-tree-get-message-properties ()
"Return the properties of the current message as a plist.
(let ((buffer (current-buffer)))
(when (and (window-live-p notmuch-tree-message-window)
(eq (window-buffer notmuch-tree-message-window) buffer))
- ;; We do not want an error if this is the sole window in the
- ;; frame and I do not know how to test for that in emacs pre
- ;; 24. Hence we just ignore-errors.
+ ;; We could check whether this is the only window in its frame,
+ ;; but simply ignoring the error that is thrown otherwise is
+ ;; what we had to do for Emacs 24 and we stick to that because
+ ;; it is still the simplest approach.
(ignore-errors
(delete-window notmuch-tree-message-window)))))
(define-key map "U" 'notmuch-unthreaded-from-search-current-query)
map)
"Keymap for \"notmuch search\" buffers.")
-(fset 'notmuch-search-mode-map notmuch-search-mode-map)
(defvar notmuch-search-stash-map
(let ((map (make-sparse-keymap)))
"Face used in search mode face for flagged threads.
This face is the default value for the \"flagged\" tag in
-`notmuch-search-line-faces`."
+`notmuch-search-line-faces'."
:group 'notmuch-search
:group 'notmuch-faces)
"Face used in search mode for unread threads.
This face is the default value for the \"unread\" tag in
-`notmuch-search-line-faces`."
+`notmuch-search-line-faces'."
:group 'notmuch-search
:group 'notmuch-faces)
(make-local-variable 'notmuch-search-target-thread)
(make-local-variable 'notmuch-search-target-line)
(setq notmuch-buffer-refresh-function #'notmuch-search-refresh-view)
- (set (make-local-variable 'scroll-preserve-screen-position) t)
+ (setq-local scroll-preserve-screen-position t)
(add-to-invisibility-spec (cons 'ellipsis t))
(setq truncate-lines t)
(setq buffer-read-only t)