mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-25 04:18:08 +01:00
emacs: make headings outline-minor-mode compatible
`outline-minor-mode' treats comments that begin with three or more semicolons as headings. That makes it very convenient to navigate code and to show/hide parts of a file. Elips libraries typically have four top-level sections, e.g.: ;;; notmuch.el --- run notmuch within emacs... ;;; Commentary:... ;;; Code:... ;;; notmuch.el ends here In this package many libraries lack a "Commentary:" section, which is not optimal but okay for most libraries, except major entry points. Depending on how one chooses to look at it, the "... ends here" line is not really a heading that begins a section, because it should never have a "section" body (after all it marks eof). If the file is rather short, then I left "Code:" as the only section that contains code. Otherwise I split the file into multiple sibling sections. The "Code:" section continues to contain `require' and `declare-function' forms and other such "front matter". If and only if I have split the code into multiple sections anyway, then I also added an additional section named just "_" before the `provide' form and shortly before the "...end here" line. This section could also be called "Back matter", but I feel it would be distracting to be that explicit about it. (The IMO unnecessary but unfortunately still obligatory "... ends here" line is already distracting enough as far as I am concerned.) Before this commit some libraries already uses section headings, some of them consistently. When a library already had some headings, then this commit often sticks to that style, even at the cost inconsistent styling across all libraries. A very limited number of variable and function definitions have to be moved around because they would otherwise end up in sections they do not belong into. Sections, including but not limited to their heading, can and should be further improved in the future.
This commit is contained in:
parent
adc123e4fd
commit
2ca941163d
19 changed files with 263 additions and 98 deletions
|
@ -25,13 +25,13 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;;; This is a simple derivative of some functionality from
|
;; This is a simple derivative of some functionality from
|
||||||
;;; `longlines.el'. The key difference is that this version will
|
;; `longlines.el'. The key difference is that this version will
|
||||||
;;; insert a prefix at the head of each wrapped line. The prefix is
|
;; insert a prefix at the head of each wrapped line. The prefix is
|
||||||
;;; calculated from the originating long line.
|
;; calculated from the originating long line.
|
||||||
|
|
||||||
;;; No minor-mode is provided, the caller is expected to call
|
;; No minor-mode is provided, the caller is expected to call
|
||||||
;;; `coolj-wrap-region' to wrap the region of interest.
|
;; `coolj-wrap-region' to wrap the region of interest.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
(require 'notmuch-parser)
|
(require 'notmuch-parser)
|
||||||
(require 'notmuch-lib)
|
(require 'notmuch-lib)
|
||||||
(require 'notmuch-company)
|
(require 'notmuch-company)
|
||||||
;;
|
|
||||||
(declare-function company-manual-begin "company")
|
(declare-function company-manual-begin "company")
|
||||||
|
|
||||||
|
;;; Cache internals
|
||||||
|
|
||||||
(defvar notmuch-address-last-harvest 0
|
(defvar notmuch-address-last-harvest 0
|
||||||
"Time of last address harvest.")
|
"Time of last address harvest.")
|
||||||
|
|
||||||
|
@ -47,6 +49,8 @@ If the hash is not present it attempts to load a saved hash."
|
||||||
(or notmuch-address-full-harvest-finished
|
(or notmuch-address-full-harvest-finished
|
||||||
(notmuch-address--load-address-hash)))
|
(notmuch-address--load-address-hash)))
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-address-command 'internal
|
(defcustom notmuch-address-command 'internal
|
||||||
"Determines how address completion candidates are generated.
|
"Determines how address completion candidates are generated.
|
||||||
|
|
||||||
|
@ -133,6 +137,14 @@ matching `notmuch-address-completion-headers-regexp'."
|
||||||
:group 'notmuch-address
|
:group 'notmuch-address
|
||||||
:group 'notmuch-hooks)
|
:group 'notmuch-hooks)
|
||||||
|
|
||||||
|
(defcustom notmuch-address-use-company t
|
||||||
|
"If available, use company mode for address completion."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'notmuch-send
|
||||||
|
:group 'notmuch-address)
|
||||||
|
|
||||||
|
;;; Setup
|
||||||
|
|
||||||
(defun notmuch-address-selection-function (prompt collection initial-input)
|
(defun notmuch-address-selection-function (prompt collection initial-input)
|
||||||
"Call (`completing-read'
|
"Call (`completing-read'
|
||||||
PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
|
PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
|
||||||
|
@ -147,12 +159,6 @@ matching `notmuch-address-completion-headers-regexp'."
|
||||||
(defun notmuch-address-message-insinuate ()
|
(defun notmuch-address-message-insinuate ()
|
||||||
(message "calling notmuch-address-message-insinuate is no longer needed"))
|
(message "calling notmuch-address-message-insinuate is no longer needed"))
|
||||||
|
|
||||||
(defcustom notmuch-address-use-company t
|
|
||||||
"If available, use company mode for address completion."
|
|
||||||
:type 'boolean
|
|
||||||
:group 'notmuch-send
|
|
||||||
:group 'notmuch-address)
|
|
||||||
|
|
||||||
(defun notmuch-address-setup ()
|
(defun notmuch-address-setup ()
|
||||||
(let* ((setup-company (and notmuch-address-use-company
|
(let* ((setup-company (and notmuch-address-use-company
|
||||||
(require 'company nil t)))
|
(require 'company nil t)))
|
||||||
|
@ -178,6 +184,8 @@ toggles the setting in this buffer."
|
||||||
(kill-local-variable 'company-idle-delay)
|
(kill-local-variable 'company-idle-delay)
|
||||||
(setq-local company-idle-delay nil))))
|
(setq-local company-idle-delay nil))))
|
||||||
|
|
||||||
|
;;; Completion
|
||||||
|
|
||||||
(defun notmuch-address-matching (substring)
|
(defun notmuch-address-matching (substring)
|
||||||
"Returns a list of completion candidates matching SUBSTRING.
|
"Returns a list of completion candidates matching SUBSTRING.
|
||||||
The candidates are taken from `notmuch-address-completions'."
|
The candidates are taken from `notmuch-address-completions'."
|
||||||
|
@ -250,6 +258,8 @@ requiring external commands."
|
||||||
(ding))))
|
(ding))))
|
||||||
(t nil)))
|
(t nil)))
|
||||||
|
|
||||||
|
;;; Harvest
|
||||||
|
|
||||||
(defun notmuch-address-harvest-addr (result)
|
(defun notmuch-address-harvest-addr (result)
|
||||||
(let ((name-addr (plist-get result :name-addr)))
|
(let ((name-addr (plist-get result :name-addr)))
|
||||||
(puthash name-addr t notmuch-address-completions)))
|
(puthash name-addr t notmuch-address-completions)))
|
||||||
|
@ -406,7 +416,7 @@ appear to be an address savefile. Not overwriting."
|
||||||
(setq notmuch-address-full-harvest-finished t))
|
(setq notmuch-address-full-harvest-finished t))
|
||||||
(setq notmuch-address-last-harvest 0)))))))
|
(setq notmuch-address-last-harvest 0)))))))
|
||||||
|
|
||||||
;;
|
;;; Standalone completion
|
||||||
|
|
||||||
(defun notmuch-address-from-minibuffer (prompt)
|
(defun notmuch-address-from-minibuffer (prompt)
|
||||||
(if (not notmuch-address-command)
|
(if (not notmuch-address-command)
|
||||||
|
@ -425,7 +435,7 @@ appear to be an address savefile. Not overwriting."
|
||||||
(let ((minibuffer-local-map rmap))
|
(let ((minibuffer-local-map rmap))
|
||||||
(read-string prompt)))))
|
(read-string prompt)))))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-address)
|
(provide 'notmuch-address)
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,6 @@
|
||||||
(run-hook-with-args 'notmuch-address-post-completion-functions arg))
|
(run-hook-with-args 'notmuch-address-post-completion-functions arg))
|
||||||
(no-cache t))))
|
(no-cache t))))
|
||||||
|
|
||||||
|
|
||||||
(provide 'notmuch-company)
|
(provide 'notmuch-company)
|
||||||
|
|
||||||
;;; notmuch-company.el ends here
|
;;; notmuch-company.el ends here
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
(unless (fboundp 'message--fold-long-headers)
|
(unless (fboundp 'message--fold-long-headers)
|
||||||
(add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
|
(add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
|
||||||
|
|
||||||
;; End of compatibility functions
|
|
||||||
|
|
||||||
(provide 'notmuch-compat)
|
(provide 'notmuch-compat)
|
||||||
|
|
||||||
;;; notmuch-compat.el ends here
|
;;; notmuch-compat.el ends here
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
|
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-crypto-process-mime t
|
(defcustom notmuch-crypto-process-mime t
|
||||||
"Whether to process cryptographic MIME parts.
|
"Whether to process cryptographic MIME parts.
|
||||||
|
|
||||||
|
@ -55,6 +57,8 @@ mode."
|
||||||
:type 'string
|
:type 'string
|
||||||
:group 'notmuch-crypto)
|
:group 'notmuch-crypto)
|
||||||
|
|
||||||
|
;;; Faces
|
||||||
|
|
||||||
(defface notmuch-crypto-part-header
|
(defface notmuch-crypto-part-header
|
||||||
'((((class color)
|
'((((class color)
|
||||||
(background dark))
|
(background dark))
|
||||||
|
@ -96,6 +100,8 @@ mode."
|
||||||
:group 'notmuch-crypto
|
:group 'notmuch-crypto
|
||||||
:group 'notmuch-faces)
|
:group 'notmuch-faces)
|
||||||
|
|
||||||
|
;;; Functions
|
||||||
|
|
||||||
(define-button-type 'notmuch-crypto-status-button-type
|
(define-button-type 'notmuch-crypto-status-button-type
|
||||||
'action (lambda (button) (message (button-get button 'help-echo)))
|
'action (lambda (button) (message (button-get button 'help-echo)))
|
||||||
'follow-link t
|
'follow-link t
|
||||||
|
@ -259,7 +265,7 @@ corresponding key when the status button is pressed."
|
||||||
'mouse-face 'notmuch-crypto-decryption)
|
'mouse-face 'notmuch-crypto-decryption)
|
||||||
(insert "\n"))
|
(insert "\n"))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-crypto)
|
(provide 'notmuch-crypto)
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
|
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
|
||||||
(declare-function notmuch-message-mode "notmuch-mua")
|
(declare-function notmuch-message-mode "notmuch-mua")
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defgroup notmuch-draft nil
|
(defgroup notmuch-draft nil
|
||||||
"Saving and editing drafts in Notmuch."
|
"Saving and editing drafts in Notmuch."
|
||||||
:group 'notmuch)
|
:group 'notmuch)
|
||||||
|
@ -85,6 +87,8 @@ like they are intended to be sent encrypted
|
||||||
:group 'notmuch-draft
|
:group 'notmuch-draft
|
||||||
:group 'notmuch-crypto)
|
:group 'notmuch-crypto)
|
||||||
|
|
||||||
|
;;; Internal
|
||||||
|
|
||||||
(defvar notmuch-draft-encryption-tag-regex
|
(defvar notmuch-draft-encryption-tag-regex
|
||||||
"<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
|
"<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
|
||||||
"Regular expression matching mml tags indicating encryption of part or message.")
|
"Regular expression matching mml tags indicating encryption of part or message.")
|
||||||
|
@ -169,6 +173,8 @@ Really save and index an unencrypted copy? ")
|
||||||
;; but notmuch doesn't want that form, so remove them.
|
;; but notmuch doesn't want that form, so remove them.
|
||||||
(concat "draft-" (substring (message-make-message-id) 1 -1)))
|
(concat "draft-" (substring (message-make-message-id) 1 -1)))
|
||||||
|
|
||||||
|
;;; Commands
|
||||||
|
|
||||||
(defun notmuch-draft-save ()
|
(defun notmuch-draft-save ()
|
||||||
"Save the current draft message in the notmuch database.
|
"Save the current draft message in the notmuch database.
|
||||||
|
|
||||||
|
@ -226,6 +232,7 @@ applied to newly inserted messages)."
|
||||||
|
|
||||||
(defun notmuch-draft-resume (id)
|
(defun notmuch-draft-resume (id)
|
||||||
"Resume editing of message with id ID."
|
"Resume editing of message with id ID."
|
||||||
|
;; Used by command `notmuch-show-resume-message'.
|
||||||
(let* ((tags (process-lines notmuch-command "search" "--output=tags"
|
(let* ((tags (process-lines notmuch-command "search" "--output=tags"
|
||||||
"--exclude=false" id))
|
"--exclude=false" id))
|
||||||
(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags))))
|
(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags))))
|
||||||
|
@ -265,10 +272,10 @@ applied to newly inserted messages)."
|
||||||
;; message is resaved or sent.
|
;; message is resaved or sent.
|
||||||
(setq notmuch-draft-id (and draft id)))))
|
(setq notmuch-draft-id (and draft id)))))
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
|
(add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
|
||||||
|
|
||||||
|
|
||||||
(provide 'notmuch-draft)
|
(provide 'notmuch-draft)
|
||||||
|
|
||||||
;;; notmuch-draft.el ends here
|
;;; notmuch-draft.el ends here
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
(&optional query query-context target buffer-name open-target))
|
(&optional query query-context target buffer-name open-target))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defun notmuch-saved-search-get (saved-search field)
|
(defun notmuch-saved-search-get (saved-search field)
|
||||||
"Get FIELD from SAVED-SEARCH.
|
"Get FIELD from SAVED-SEARCH.
|
||||||
|
|
||||||
|
@ -192,6 +194,8 @@ fields of the search."
|
||||||
(defvar notmuch-hello-indent 4
|
(defvar notmuch-hello-indent 4
|
||||||
"How much to indent non-headers.")
|
"How much to indent non-headers.")
|
||||||
|
|
||||||
|
(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
|
||||||
|
|
||||||
(defcustom notmuch-show-logo t
|
(defcustom notmuch-show-logo t
|
||||||
"Should the notmuch logo be shown?"
|
"Should the notmuch logo be shown?"
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
|
@ -367,23 +371,15 @@ supported for \"Customized queries section\" items."
|
||||||
:group 'notmuch-hello
|
:group 'notmuch-hello
|
||||||
:type 'boolean)
|
:type 'boolean)
|
||||||
|
|
||||||
|
;;; Internal variables
|
||||||
|
|
||||||
(defvar notmuch-hello-hidden-sections nil
|
(defvar notmuch-hello-hidden-sections nil
|
||||||
"List of sections titles whose contents are hidden.")
|
"List of sections titles whose contents are hidden.")
|
||||||
|
|
||||||
(defvar notmuch-hello-first-run t
|
(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)
|
;;; Widgets for inserters
|
||||||
(let (result)
|
|
||||||
(while (> n 0)
|
|
||||||
(push (% n 1000) result)
|
|
||||||
(setq n (/ n 1000)))
|
|
||||||
(setq result (or result '(0)))
|
|
||||||
(apply #'concat
|
|
||||||
(number-to-string (car result))
|
|
||||||
(mapcar (lambda (elem)
|
|
||||||
(format "%s%03d" notmuch-hello-thousands-separator elem))
|
|
||||||
(cdr result)))))
|
|
||||||
|
|
||||||
(define-widget 'notmuch-search-item 'item
|
(define-widget 'notmuch-search-item 'item
|
||||||
"A recent search."
|
"A recent search."
|
||||||
|
@ -419,6 +415,8 @@ supported for \"Customized queries section\" items."
|
||||||
1 ; for the space before the [del] button
|
1 ; for the space before the [del] button
|
||||||
5))) ; for the [del] button
|
5))) ; for the [del] button
|
||||||
|
|
||||||
|
;;; Widget actions
|
||||||
|
|
||||||
(defun notmuch-hello-search (widget &rest _event)
|
(defun notmuch-hello-search (widget &rest _event)
|
||||||
(let ((search (widget-value widget)))
|
(let ((search (widget-value widget)))
|
||||||
(when search
|
(when search
|
||||||
|
@ -451,6 +449,13 @@ supported for \"Customized queries section\" items."
|
||||||
(delete search notmuch-search-history)))
|
(delete search notmuch-search-history)))
|
||||||
(notmuch-hello-update)))
|
(notmuch-hello-update)))
|
||||||
|
|
||||||
|
;;; Button utilities
|
||||||
|
|
||||||
|
;; `notmuch-hello-query-counts', `notmuch-hello-nice-number' and
|
||||||
|
;; `notmuch-hello-insert-buttons' are used outside this section.
|
||||||
|
;; All other functions that are defined in this section are only
|
||||||
|
;; used by these two functions.
|
||||||
|
|
||||||
(defun notmuch-hello-longest-label (searches-alist)
|
(defun notmuch-hello-longest-label (searches-alist)
|
||||||
(or (cl-loop for elem in searches-alist
|
(or (cl-loop for elem in searches-alist
|
||||||
maximize (length (notmuch-saved-search-get elem :name)))
|
maximize (length (notmuch-saved-search-get elem :name)))
|
||||||
|
@ -585,6 +590,18 @@ the CLI and emacs interface."))
|
||||||
(list (plist-put elem-plist :count message-count)))))
|
(list (plist-put elem-plist :count message-count)))))
|
||||||
query-list)))
|
query-list)))
|
||||||
|
|
||||||
|
(defun notmuch-hello-nice-number (n)
|
||||||
|
(let (result)
|
||||||
|
(while (> n 0)
|
||||||
|
(push (% n 1000) result)
|
||||||
|
(setq n (/ n 1000)))
|
||||||
|
(setq result (or result '(0)))
|
||||||
|
(apply #'concat
|
||||||
|
(number-to-string (car result))
|
||||||
|
(mapcar (lambda (elem)
|
||||||
|
(format "%s%03d" notmuch-hello-thousands-separator elem))
|
||||||
|
(cdr result)))))
|
||||||
|
|
||||||
(defun notmuch-hello-insert-buttons (searches)
|
(defun notmuch-hello-insert-buttons (searches)
|
||||||
"Insert buttons for SEARCHES.
|
"Insert buttons for SEARCHES.
|
||||||
|
|
||||||
|
@ -639,7 +656,7 @@ with `notmuch-hello-query-counts'."
|
||||||
(unless (eq (% count tags-per-line) 0)
|
(unless (eq (% count tags-per-line) 0)
|
||||||
(widget-insert "\n"))))
|
(widget-insert "\n"))))
|
||||||
|
|
||||||
(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
|
;;; Mode
|
||||||
|
|
||||||
(defun notmuch-hello-update ()
|
(defun notmuch-hello-update ()
|
||||||
"Update the notmuch-hello buffer."
|
"Update the notmuch-hello buffer."
|
||||||
|
@ -723,6 +740,8 @@ Complete list of currently available key bindings:
|
||||||
;;(setq buffer-read-only t)
|
;;(setq buffer-read-only t)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
;;; Inserters
|
||||||
|
|
||||||
(defun notmuch-hello-generate-tag-alist (&optional hide-tags)
|
(defun notmuch-hello-generate-tag-alist (&optional hide-tags)
|
||||||
"Return an alist from tags to queries to display in the all-tags section."
|
"Return an alist from tags to queries to display in the all-tags section."
|
||||||
(cl-mapcan (lambda (tag)
|
(cl-mapcan (lambda (tag)
|
||||||
|
@ -922,6 +941,8 @@ following:
|
||||||
(let ((fill-column (- (window-width) notmuch-hello-indent)))
|
(let ((fill-column (- (window-width) notmuch-hello-indent)))
|
||||||
(center-region start (point)))))
|
(center-region start (point)))))
|
||||||
|
|
||||||
|
;;; Hello!
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun notmuch-hello (&optional no-display)
|
(defun notmuch-hello (&optional no-display)
|
||||||
"Run notmuch and display saved searches, known tags, etc."
|
"Run notmuch and display saved searches, known tags, etc."
|
||||||
|
@ -973,7 +994,7 @@ following:
|
||||||
(run-hooks 'notmuch-hello-refresh-hook)
|
(run-hooks 'notmuch-hello-refresh-hook)
|
||||||
(setq notmuch-hello-first-run nil))
|
(setq notmuch-hello-first-run nil))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-hello)
|
(provide 'notmuch-hello)
|
||||||
|
|
||||||
|
|
|
@ -198,8 +198,6 @@ buffer."
|
||||||
(exit-minibuffer)))))))
|
(exit-minibuffer)))))))
|
||||||
map))
|
map))
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(provide 'notmuch-jump)
|
(provide 'notmuch-jump)
|
||||||
|
|
||||||
;;; notmuch-jump.el ends here
|
;;; notmuch-jump.el ends here
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
(defconst notmuch-emacs-version "unknown"
|
(defconst notmuch-emacs-version "unknown"
|
||||||
"Placeholder variable when notmuch-version.el[c] is not available."))
|
"Placeholder variable when notmuch-version.el[c] is not available."))
|
||||||
|
|
||||||
|
;;; Groups
|
||||||
|
|
||||||
(defgroup notmuch nil
|
(defgroup notmuch nil
|
||||||
"Notmuch mail reader for Emacs."
|
"Notmuch mail reader for Emacs."
|
||||||
:group 'mail)
|
:group 'mail)
|
||||||
|
@ -78,6 +80,8 @@
|
||||||
"Graphical attributes for displaying text"
|
"Graphical attributes for displaying text"
|
||||||
:group 'notmuch)
|
:group 'notmuch)
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-command "notmuch"
|
(defcustom notmuch-command "notmuch"
|
||||||
"Name of the notmuch binary.
|
"Name of the notmuch binary.
|
||||||
|
|
||||||
|
@ -125,11 +129,6 @@ the user's needs:
|
||||||
(string :tag "Custom script"))
|
(string :tag "Custom script"))
|
||||||
:group 'notmuch-external)
|
:group 'notmuch-external)
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defvar notmuch-search-history nil
|
|
||||||
"Variable to store notmuch searches history.")
|
|
||||||
|
|
||||||
(defcustom notmuch-archive-tags '("-inbox")
|
(defcustom notmuch-archive-tags '("-inbox")
|
||||||
"List of tag changes to apply to a message or a thread when it is archived.
|
"List of tag changes to apply to a message or a thread when it is archived.
|
||||||
|
|
||||||
|
@ -144,6 +143,11 @@ For example, if you wanted to remove an \"inbox\" tag and add an
|
||||||
:group 'notmuch-search
|
:group 'notmuch-search
|
||||||
:group 'notmuch-show)
|
:group 'notmuch-show)
|
||||||
|
|
||||||
|
;;; Variables
|
||||||
|
|
||||||
|
(defvar notmuch-search-history nil
|
||||||
|
"Variable to store notmuch searches history.")
|
||||||
|
|
||||||
(defvar notmuch-common-keymap
|
(defvar notmuch-common-keymap
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map "?" 'notmuch-help)
|
(define-key map "?" 'notmuch-help)
|
||||||
|
@ -177,6 +181,8 @@ For example, if you wanted to remove an \"inbox\" tag and add an
|
||||||
(select-window (posn-window (event-start last-input-event)))
|
(select-window (posn-window (event-start last-input-event)))
|
||||||
(button-activate button)))
|
(button-activate button)))
|
||||||
|
|
||||||
|
;;; CLI Utilities
|
||||||
|
|
||||||
(defun notmuch-command-to-string (&rest args)
|
(defun notmuch-command-to-string (&rest args)
|
||||||
"Synchronously invoke \"notmuch\" with the given list of arguments.
|
"Synchronously invoke \"notmuch\" with the given list of arguments.
|
||||||
|
|
||||||
|
@ -234,6 +240,8 @@ displays both values separately."
|
||||||
(concat cli-version
|
(concat cli-version
|
||||||
" (emacs mua version " notmuch-emacs-version ")")))))
|
" (emacs mua version " notmuch-emacs-version ")")))))
|
||||||
|
|
||||||
|
;;; Notmuch Configuration
|
||||||
|
|
||||||
(defun notmuch-config-get (item)
|
(defun notmuch-config-get (item)
|
||||||
"Return a value from the notmuch configuration."
|
"Return a value from the notmuch configuration."
|
||||||
(let* ((val (notmuch-command-to-string "config" "get" item))
|
(let* ((val (notmuch-command-to-string "config" "get" item))
|
||||||
|
@ -263,6 +271,8 @@ displays both values separately."
|
||||||
(defun notmuch-user-emails ()
|
(defun notmuch-user-emails ()
|
||||||
(cons (notmuch-user-primary-email) (notmuch-user-other-email)))
|
(cons (notmuch-user-primary-email) (notmuch-user-other-email)))
|
||||||
|
|
||||||
|
;;; Commands
|
||||||
|
|
||||||
(defun notmuch-poll ()
|
(defun notmuch-poll ()
|
||||||
"Run \"notmuch new\" or an external script to import mail.
|
"Run \"notmuch new\" or an external script to import mail.
|
||||||
|
|
||||||
|
@ -287,6 +297,8 @@ it, in which case it is killed."
|
||||||
(bury-buffer)
|
(bury-buffer)
|
||||||
(kill-buffer)))
|
(kill-buffer)))
|
||||||
|
|
||||||
|
;;; Describe Key Bindings
|
||||||
|
|
||||||
(defun notmuch-prefix-key-description (key)
|
(defun notmuch-prefix-key-description (key)
|
||||||
"Given a prefix key code, return a human-readable string representation.
|
"Given a prefix key code, return a human-readable string representation.
|
||||||
|
|
||||||
|
@ -297,7 +309,6 @@ This is basically just `format-kbd-macro' but we also convert ESC to M-."
|
||||||
"M-"
|
"M-"
|
||||||
(concat desc " "))))
|
(concat desc " "))))
|
||||||
|
|
||||||
|
|
||||||
(defun notmuch-describe-key (actual-key binding prefix ua-keys tail)
|
(defun notmuch-describe-key (actual-key binding prefix ua-keys tail)
|
||||||
"Prepend cons cells describing prefix-arg ACTUAL-KEY and ACTUAL-KEY to TAIL.
|
"Prepend cons cells describing prefix-arg ACTUAL-KEY and ACTUAL-KEY to TAIL.
|
||||||
|
|
||||||
|
@ -435,6 +446,8 @@ of its command symbol."
|
||||||
(insert desc)))
|
(insert desc)))
|
||||||
(pop-to-buffer (help-buffer)))))
|
(pop-to-buffer (help-buffer)))))
|
||||||
|
|
||||||
|
;;; Refreshing Buffers
|
||||||
|
|
||||||
(defvar-local notmuch-buffer-refresh-function nil
|
(defvar-local notmuch-buffer-refresh-function nil
|
||||||
"Function to call to refresh the current buffer.")
|
"Function to call to refresh the current buffer.")
|
||||||
|
|
||||||
|
@ -466,6 +479,8 @@ be displayed."
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
(notmuch-refresh-this-buffer))))))
|
(notmuch-refresh-this-buffer))))))
|
||||||
|
|
||||||
|
;;; String Utilities
|
||||||
|
|
||||||
(defun notmuch-prettify-subject (subject)
|
(defun notmuch-prettify-subject (subject)
|
||||||
;; This function is used by `notmuch-search-process-filter' which
|
;; This function is used by `notmuch-search-process-filter' which
|
||||||
;; requires that we not disrupt its' matching state.
|
;; requires that we not disrupt its' matching state.
|
||||||
|
@ -509,8 +524,6 @@ This replaces spaces, percents, and double quotes in STR with
|
||||||
(replace-regexp-in-string
|
(replace-regexp-in-string
|
||||||
"[ %\"]" (lambda (match) (format "%%%02x" (aref match 0))) str))
|
"[ %\"]" (lambda (match) (format "%%%02x" (aref match 0))) str))
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun notmuch-common-do-stash (text)
|
(defun notmuch-common-do-stash (text)
|
||||||
"Common function to stash text in kill ring, and display in minibuffer."
|
"Common function to stash text in kill ring, and display in minibuffer."
|
||||||
(if text
|
(if text
|
||||||
|
@ -522,7 +535,7 @@ This replaces spaces, percents, and double quotes in STR with
|
||||||
(kill-new "")
|
(kill-new "")
|
||||||
(message "Nothing to stash!")))
|
(message "Nothing to stash!")))
|
||||||
|
|
||||||
;;
|
;;; Generic Utilities
|
||||||
|
|
||||||
(defun notmuch-plist-delete (plist property)
|
(defun notmuch-plist-delete (plist property)
|
||||||
(let* ((xplist (cons nil plist))
|
(let* ((xplist (cons nil plist))
|
||||||
|
@ -533,6 +546,8 @@ This replaces spaces, percents, and double quotes in STR with
|
||||||
(setq pred (cddr pred)))
|
(setq pred (cddr pred)))
|
||||||
(cdr xplist)))
|
(cdr xplist)))
|
||||||
|
|
||||||
|
;;; MML Utilities
|
||||||
|
|
||||||
(defun notmuch-match-content-type (t1 t2)
|
(defun notmuch-match-content-type (t1 t2)
|
||||||
"Return t if t1 and t2 are matching content types, taking wildcards into account."
|
"Return t if t1 and t2 are matching content types, taking wildcards into account."
|
||||||
(let ((st1 (split-string t1 "/"))
|
(let ((st1 (split-string t1 "/"))
|
||||||
|
@ -673,6 +688,8 @@ current buffer, if possible."
|
||||||
(mm-display-part handle)
|
(mm-display-part handle)
|
||||||
t))))))
|
t))))))
|
||||||
|
|
||||||
|
;;; Generic Utilities
|
||||||
|
|
||||||
;; Converts a plist of headers to an alist of headers. The input plist should
|
;; Converts a plist of headers to an alist of headers. The input plist should
|
||||||
;; have symbols of the form :Header as keys, and the resulting alist will have
|
;; have symbols of the form :Header as keys, and the resulting alist will have
|
||||||
;; symbols of the form 'Header as keys.
|
;; symbols of the form 'Header as keys.
|
||||||
|
@ -739,6 +756,8 @@ returned by FUNC."
|
||||||
(put-text-property start next prop (funcall func value) object)
|
(put-text-property start next prop (funcall func value) object)
|
||||||
(setq start next))))
|
(setq start next))))
|
||||||
|
|
||||||
|
;;; Running Notmuch
|
||||||
|
|
||||||
(defun notmuch-logged-error (msg &optional extra)
|
(defun notmuch-logged-error (msg &optional extra)
|
||||||
"Log MSG and EXTRA to *Notmuch errors* and signal MSG.
|
"Log MSG and EXTRA to *Notmuch errors* and signal MSG.
|
||||||
|
|
||||||
|
@ -967,6 +986,8 @@ status."
|
||||||
|
|
||||||
(defvar-local notmuch-show-process-crypto nil)
|
(defvar-local notmuch-show-process-crypto nil)
|
||||||
|
|
||||||
|
;;; Generic Utilities
|
||||||
|
|
||||||
(defun notmuch-interactive-region ()
|
(defun notmuch-interactive-region ()
|
||||||
"Return the bounds of the current interactive region.
|
"Return the bounds of the current interactive region.
|
||||||
|
|
||||||
|
@ -981,6 +1002,8 @@ region if the region is active, or both `point' otherwise."
|
||||||
'notmuch-interactive-region
|
'notmuch-interactive-region
|
||||||
"notmuch 0.29")
|
"notmuch 0.29")
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-lib)
|
(provide 'notmuch-lib)
|
||||||
|
|
||||||
;;; notmuch-lib.el ends here
|
;;; notmuch-lib.el ends here
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
(defvar notmuch-maildir-fcc-count 0)
|
(defvar notmuch-maildir-fcc-count 0)
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-fcc-dirs "sent"
|
(defcustom notmuch-fcc-dirs "sent"
|
||||||
"Determines the Fcc Header which says where to save outgoing mail.
|
"Determines the Fcc Header which says where to save outgoing mail.
|
||||||
|
|
||||||
|
@ -83,8 +85,7 @@ directory if it does not exist yet when sending a mail."
|
||||||
(const :tag "Use simple fcc" nil))
|
(const :tag "Use simple fcc" nil))
|
||||||
:group 'notmuch-send)
|
:group 'notmuch-send)
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Functions which set up the fcc header in the message buffer.
|
||||||
;; Functions which set up the fcc header in the message buffer.
|
|
||||||
|
|
||||||
(defun notmuch-fcc-header-setup ()
|
(defun notmuch-fcc-header-setup ()
|
||||||
"Add an Fcc header to the current message buffer.
|
"Add an Fcc header to the current message buffer.
|
||||||
|
@ -142,9 +143,7 @@ Insert header anyway? " subdir)))
|
||||||
subdir
|
subdir
|
||||||
(concat (notmuch-database-path) "/" subdir))))))
|
(concat (notmuch-database-path) "/" subdir))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Functions for saving a message using either method.
|
||||||
;; Functions for saving a message either using notmuch insert or file
|
|
||||||
;; fcc. First functions common to the two cases.
|
|
||||||
|
|
||||||
(defmacro with-temporary-notmuch-message-buffer (&rest body)
|
(defmacro with-temporary-notmuch-message-buffer (&rest body)
|
||||||
"Set-up a temporary copy of the current message-mode buffer."
|
"Set-up a temporary copy of the current message-mode buffer."
|
||||||
|
@ -204,8 +203,7 @@ normal fcc."
|
||||||
(notmuch-maildir-fcc-with-notmuch-insert fcc-header)
|
(notmuch-maildir-fcc-with-notmuch-insert fcc-header)
|
||||||
(notmuch-maildir-fcc-file-fcc fcc-header)))
|
(notmuch-maildir-fcc-file-fcc fcc-header)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Functions for saving a message using notmuch insert.
|
||||||
;; Functions for saving a message using notmuch insert.
|
|
||||||
|
|
||||||
(defun notmuch-maildir-notmuch-insert-current-buffer (folder &optional create tags)
|
(defun notmuch-maildir-notmuch-insert-current-buffer (folder &optional create tags)
|
||||||
"Use notmuch insert to put the current buffer in the database.
|
"Use notmuch insert to put the current buffer in the database.
|
||||||
|
@ -251,9 +249,7 @@ If CREATE is non-nil then create the folder if necessary."
|
||||||
(?e (notmuch-maildir-fcc-with-notmuch-insert
|
(?e (notmuch-maildir-fcc-with-notmuch-insert
|
||||||
(read-from-minibuffer "Fcc header: " fcc-header)))))))))
|
(read-from-minibuffer "Fcc header: " fcc-header)))))))))
|
||||||
|
|
||||||
|
;;; Functions for saving a message using file fcc.
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Functions for saving a message using file fcc.
|
|
||||||
|
|
||||||
(defun notmuch-maildir-fcc-host-fixer (hostname)
|
(defun notmuch-maildir-fcc-host-fixer (hostname)
|
||||||
(replace-regexp-in-string "/\\|:"
|
(replace-regexp-in-string "/\\|:"
|
||||||
|
@ -362,6 +358,8 @@ return t if successful, and nil otherwise."
|
||||||
(delete-file (concat destdir "/tmp/" msg-id))))
|
(delete-file (concat destdir "/tmp/" msg-id))))
|
||||||
t)))
|
t)))
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-maildir-fcc)
|
(provide 'notmuch-maildir-fcc)
|
||||||
|
|
||||||
;;; notmuch-maildir-fcc.el ends here
|
;;; notmuch-maildir-fcc.el ends here
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
(declare-function notmuch-draft-postpone "notmuch-draft" ())
|
(declare-function notmuch-draft-postpone "notmuch-draft" ())
|
||||||
(declare-function notmuch-draft-save "notmuch-draft" ())
|
(declare-function notmuch-draft-save "notmuch-draft" ())
|
||||||
|
|
||||||
;;
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-mua-send-hook nil
|
(defcustom notmuch-mua-send-hook nil
|
||||||
"Hook run before sending messages."
|
"Hook run before sending messages."
|
||||||
|
@ -120,7 +120,7 @@ to `notmuch-mua-send-hook'."
|
||||||
:type 'regexp
|
:type 'regexp
|
||||||
:group 'notmuch-send)
|
:group 'notmuch-send)
|
||||||
|
|
||||||
;;
|
;;; Various functions
|
||||||
|
|
||||||
(defun notmuch-mua-attachment-check ()
|
(defun notmuch-mua-attachment-check ()
|
||||||
"Signal an error if the message text indicates that an
|
"Signal an error if the message text indicates that an
|
||||||
|
@ -215,6 +215,8 @@ Typically this is added to `notmuch-mua-send-hook'."
|
||||||
(funcall original-func header references)
|
(funcall original-func header references)
|
||||||
(unless (bolp) (insert "\n")))
|
(unless (bolp) (insert "\n")))
|
||||||
|
|
||||||
|
;;; Mua reply
|
||||||
|
|
||||||
(defun notmuch-mua-reply (query-string &optional sender reply-all)
|
(defun notmuch-mua-reply (query-string &optional sender reply-all)
|
||||||
(let ((args '("reply" "--format=sexp" "--format-version=4"))
|
(let ((args '("reply" "--format=sexp" "--format-version=4"))
|
||||||
(process-crypto notmuch-show-process-crypto)
|
(process-crypto notmuch-show-process-crypto)
|
||||||
|
@ -318,6 +320,8 @@ Typically this is added to `notmuch-mua-send-hook'."
|
||||||
(message-goto-body)
|
(message-goto-body)
|
||||||
(set-buffer-modified-p nil))
|
(set-buffer-modified-p nil))
|
||||||
|
|
||||||
|
;;; Mode and keymap
|
||||||
|
|
||||||
(defvar notmuch-message-mode-map
|
(defvar notmuch-message-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(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-c") #'notmuch-mua-send-and-exit)
|
||||||
|
@ -333,6 +337,8 @@ Typically this is added to `notmuch-mua-send-hook'."
|
||||||
|
|
||||||
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
|
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
|
||||||
|
|
||||||
|
;;; New messages
|
||||||
|
|
||||||
(defun notmuch-mua-pop-to-buffer (name switch-function)
|
(defun notmuch-mua-pop-to-buffer (name switch-function)
|
||||||
"Pop to buffer NAME, and warn if it already exists and is modified.
|
"Pop to buffer NAME, and warn if it already exists and is modified.
|
||||||
Like `message-pop-to-buffer' but enable `notmuch-message-mode'
|
Like `message-pop-to-buffer' but enable `notmuch-message-mode'
|
||||||
|
@ -528,6 +534,8 @@ will be addressed to all recipients of the source message."
|
||||||
(notmuch-mua-reply query-string sender reply-all)
|
(notmuch-mua-reply query-string sender reply-all)
|
||||||
(deactivate-mark)))
|
(deactivate-mark)))
|
||||||
|
|
||||||
|
;;; Checks
|
||||||
|
|
||||||
(defun notmuch-mua-check-no-misplaced-secure-tag ()
|
(defun notmuch-mua-check-no-misplaced-secure-tag ()
|
||||||
"Query user if there is a misplaced secure mml tag.
|
"Query user if there is a misplaced secure mml tag.
|
||||||
|
|
||||||
|
@ -570,6 +578,8 @@ The <#secure> tag at the start of the body is not followed by a
|
||||||
newline. It is likely that the message will be sent unsigned and
|
newline. It is likely that the message will be sent unsigned and
|
||||||
unencrypted. Really send? "))))
|
unencrypted. Really send? "))))
|
||||||
|
|
||||||
|
;;; Finishing commands
|
||||||
|
|
||||||
(defun notmuch-mua-send-common (arg &optional exit)
|
(defun notmuch-mua-send-common (arg &optional exit)
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(run-hooks 'notmuch-mua-send-hook)
|
(run-hooks 'notmuch-mua-send-hook)
|
||||||
|
@ -593,7 +603,7 @@ unencrypted. Really send? "))))
|
||||||
(interactive)
|
(interactive)
|
||||||
(message-kill-buffer))
|
(message-kill-buffer))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(define-mail-user-agent 'notmuch-user-agent
|
(define-mail-user-agent 'notmuch-user-agent
|
||||||
'notmuch-mua-mail 'notmuch-mua-send-and-exit
|
'notmuch-mua-mail 'notmuch-mua-send-and-exit
|
||||||
|
@ -603,8 +613,6 @@ unencrypted. Really send? "))))
|
||||||
;; composing a message.
|
;; composing a message.
|
||||||
(notmuch-mua-add-more-hidden-headers)
|
(notmuch-mua-add-more-hidden-headers)
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(provide 'notmuch-mua)
|
(provide 'notmuch-mua)
|
||||||
|
|
||||||
;;; notmuch-mua.el ends here
|
;;; notmuch-mua.el ends here
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
(declare-function notmuch-show-get-prop "notmuch-show" (prop &optional props))
|
(declare-function notmuch-show-get-prop "notmuch-show" (prop &optional props))
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-print-mechanism 'notmuch-print-lpr
|
(defcustom notmuch-print-mechanism 'notmuch-print-lpr
|
||||||
"How should printing be done?"
|
"How should printing be done?"
|
||||||
:group 'notmuch-show
|
:group 'notmuch-show
|
||||||
|
@ -36,7 +38,7 @@
|
||||||
(function :tag "Use muttprint then evince" notmuch-print-muttprint/evince)
|
(function :tag "Use muttprint then evince" notmuch-print-muttprint/evince)
|
||||||
(function :tag "Using a custom function")))
|
(function :tag "Using a custom function")))
|
||||||
|
|
||||||
;; Utility functions:
|
;;; Utility functions
|
||||||
|
|
||||||
(defun notmuch-print-run-evince (file)
|
(defun notmuch-print-run-evince (file)
|
||||||
"View FILE using 'evince'."
|
"View FILE using 'evince'."
|
||||||
|
@ -54,7 +56,7 @@ Optional OUTPUT allows passing a list of flags to muttprint."
|
||||||
"--printed-headers" "Date_To_From_CC_Newsgroups_*Subject*_/Tags/"
|
"--printed-headers" "Date_To_From_CC_Newsgroups_*Subject*_/Tags/"
|
||||||
output))
|
output))
|
||||||
|
|
||||||
;; User-visible functions:
|
;;; User-visible functions
|
||||||
|
|
||||||
(defun notmuch-print-lpr (msg)
|
(defun notmuch-print-lpr (msg)
|
||||||
"Print a message buffer using lpr."
|
"Print a message buffer using lpr."
|
||||||
|
@ -91,6 +93,8 @@ Optional OUTPUT allows passing a list of flags to muttprint."
|
||||||
(set-buffer-modified-p nil)
|
(set-buffer-modified-p nil)
|
||||||
(funcall notmuch-print-mechanism msg))
|
(funcall notmuch-print-mechanism msg))
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-print)
|
(provide 'notmuch-print)
|
||||||
|
|
||||||
;;; notmuch-print.el ends here
|
;;; notmuch-print.el ends here
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
(require 'notmuch-lib)
|
(require 'notmuch-lib)
|
||||||
|
|
||||||
|
;;; Basic query function
|
||||||
|
|
||||||
(defun notmuch-query-get-threads (search-terms)
|
(defun notmuch-query-get-threads (search-terms)
|
||||||
"Return a list of threads of messages matching SEARCH-TERMS.
|
"Return a list of threads of messages matching SEARCH-TERMS.
|
||||||
|
|
||||||
|
@ -35,8 +37,7 @@ is a possibly empty forest of replies."
|
||||||
(setq args (append args search-terms))
|
(setq args (append args search-terms))
|
||||||
(apply #'notmuch-call-notmuch-sexp args)))
|
(apply #'notmuch-call-notmuch-sexp args)))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Mapping functions across collections of messages
|
||||||
;; Mapping functions across collections of messages.
|
|
||||||
|
|
||||||
(defun notmuch-query-map-aux (mapper function seq)
|
(defun notmuch-query-map-aux (mapper function seq)
|
||||||
"Private function to do the actual mapping and flattening."
|
"Private function to do the actual mapping and flattening."
|
||||||
|
@ -64,8 +65,7 @@ Flatten results to a list. See the function
|
||||||
`notmuch-query-get-threads' for more information."
|
`notmuch-query-get-threads' for more information."
|
||||||
(cons (funcall fn (car tree)) (notmuch-query-map-forest fn (cadr tree))))
|
(cons (funcall fn (car tree)) (notmuch-query-map-forest fn (cadr tree))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;; Predefined queries
|
||||||
;; Predefined queries
|
|
||||||
|
|
||||||
(defun notmuch-query-get-message-ids (&rest search-terms)
|
(defun notmuch-query-get-message-ids (&rest search-terms)
|
||||||
"Return a list of message-ids of messages that match SEARCH-TERMS."
|
"Return a list of message-ids of messages that match SEARCH-TERMS."
|
||||||
|
|
|
@ -59,6 +59,8 @@
|
||||||
(declare-function notmuch-read-query "notmuch" (prompt))
|
(declare-function notmuch-read-query "notmuch" (prompt))
|
||||||
(declare-function notmuch-draft-resume "notmuch-draft" (id))
|
(declare-function notmuch-draft-resume "notmuch-draft" (id))
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
|
(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
|
||||||
"Headers that should be shown in a message, in this order.
|
"Headers that should be shown in a message, in this order.
|
||||||
|
|
||||||
|
@ -162,6 +164,8 @@ indentation."
|
||||||
:type '(choice (const nil) regexp)
|
:type '(choice (const nil) regexp)
|
||||||
:group 'notmuch-show)
|
:group 'notmuch-show)
|
||||||
|
|
||||||
|
;;; Variables
|
||||||
|
|
||||||
(defvar-local notmuch-show-thread-id nil)
|
(defvar-local notmuch-show-thread-id nil)
|
||||||
|
|
||||||
(defvar-local notmuch-show-parent-buffer nil)
|
(defvar-local notmuch-show-parent-buffer nil)
|
||||||
|
@ -182,6 +186,8 @@ handlers is discarded. When set to t the stdout and stderr from
|
||||||
each attachment handler is logged in buffers with names beginning
|
each attachment handler is logged in buffers with names beginning
|
||||||
\" *notmuch-part*\".")
|
\" *notmuch-part*\".")
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-show-stash-mlarchive-link-alist
|
(defcustom notmuch-show-stash-mlarchive-link-alist
|
||||||
'(("Gmane" . "https://mid.gmane.org/")
|
'(("Gmane" . "https://mid.gmane.org/")
|
||||||
("MARC" . "https://marc.info/?i=")
|
("MARC" . "https://marc.info/?i=")
|
||||||
|
@ -260,6 +266,8 @@ position of the message in the thread."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'notmuch-show)
|
:group 'notmuch-show)
|
||||||
|
|
||||||
|
;;; Utilities
|
||||||
|
|
||||||
(defmacro with-current-notmuch-show-message (&rest body)
|
(defmacro with-current-notmuch-show-message (&rest body)
|
||||||
"Evaluate body with current buffer set to the text of current message."
|
"Evaluate body with current buffer set to the text of current message."
|
||||||
`(save-excursion
|
`(save-excursion
|
||||||
|
@ -275,6 +283,8 @@ position of the message in the thread."
|
||||||
"Enable Visual Line mode."
|
"Enable Visual Line mode."
|
||||||
(visual-line-mode t))
|
(visual-line-mode t))
|
||||||
|
|
||||||
|
;;; Commands
|
||||||
|
|
||||||
;; DEPRECATED in Notmuch 0.16 since we now have convenient part
|
;; DEPRECATED in Notmuch 0.16 since we now have convenient part
|
||||||
;; commands. We'll keep the command around for a version or two in
|
;; commands. We'll keep the command around for a version or two in
|
||||||
;; case people want to bind it themselves.
|
;; case people want to bind it themselves.
|
||||||
|
@ -355,6 +365,8 @@ operation on the contents of the current buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(notmuch-show-with-message-as-text 'notmuch-print-message))
|
(notmuch-show-with-message-as-text 'notmuch-print-message))
|
||||||
|
|
||||||
|
;;; Headers
|
||||||
|
|
||||||
(defun notmuch-show-fontify-header ()
|
(defun notmuch-show-fontify-header ()
|
||||||
(let ((face (cond
|
(let ((face (cond
|
||||||
((looking-at "[Tt]o:")
|
((looking-at "[Tt]o:")
|
||||||
|
@ -493,6 +505,8 @@ message at DEPTH in the current thread."
|
||||||
(narrow-to-region start (point-max))
|
(narrow-to-region start (point-max))
|
||||||
(run-hooks 'notmuch-show-markup-headers-hook)))))
|
(run-hooks 'notmuch-show-markup-headers-hook)))))
|
||||||
|
|
||||||
|
;;; Parts
|
||||||
|
|
||||||
(define-button-type 'notmuch-show-part-button-type
|
(define-button-type 'notmuch-show-part-button-type
|
||||||
'action 'notmuch-show-part-button-default
|
'action 'notmuch-show-part-button-default
|
||||||
'follow-link t
|
'follow-link t
|
||||||
|
@ -548,7 +562,7 @@ message at DEPTH in the current thread."
|
||||||
(overlay-put overlay 'invisible (not show))
|
(overlay-put overlay 'invisible (not show))
|
||||||
t)))))))
|
t)))))))
|
||||||
|
|
||||||
;; Part content ID handling
|
;;; Part content ID handling
|
||||||
|
|
||||||
(defvar notmuch-show--cids nil
|
(defvar notmuch-show--cids nil
|
||||||
"Alist from raw content ID to (MSG PART).")
|
"Alist from raw content ID to (MSG PART).")
|
||||||
|
@ -811,7 +825,8 @@ will return nil if the CID is unknown or cannot be retrieved."
|
||||||
(gnus-blocked-images notmuch-show-text/html-blocked-images))
|
(gnus-blocked-images notmuch-show-text/html-blocked-images))
|
||||||
(notmuch-show-insert-part-*/* msg part content-type nth depth button))))
|
(notmuch-show-insert-part-*/* msg part content-type nth depth button))))
|
||||||
|
|
||||||
;; These functions are used by notmuch-show--insert-part-text/html-shr
|
;;; Functions used by notmuch-show--insert-part-text/html-shr
|
||||||
|
|
||||||
(declare-function libxml-parse-html-region "xml.c")
|
(declare-function libxml-parse-html-region "xml.c")
|
||||||
(declare-function shr-insert-document "shr")
|
(declare-function shr-insert-document "shr")
|
||||||
|
|
||||||
|
@ -836,7 +851,7 @@ will return nil if the CID is unknown or cannot be retrieved."
|
||||||
(notmuch-mm-display-part-inline msg part content-type notmuch-show-process-crypto)
|
(notmuch-mm-display-part-inline msg part content-type notmuch-show-process-crypto)
|
||||||
t)
|
t)
|
||||||
|
|
||||||
;; Functions for determining how to handle MIME parts.
|
;;; Functions for determining how to handle MIME parts.
|
||||||
|
|
||||||
(defun notmuch-show-handlers-for (content-type)
|
(defun notmuch-show-handlers-for (content-type)
|
||||||
"Return a list of content handlers for a part of type CONTENT-TYPE."
|
"Return a list of content handlers for a part of type CONTENT-TYPE."
|
||||||
|
@ -852,7 +867,7 @@ will return nil if the CID is unknown or cannot be retrieved."
|
||||||
(intern (concat "notmuch-show-insert-part-" content-type))))
|
(intern (concat "notmuch-show-insert-part-" content-type))))
|
||||||
result))
|
result))
|
||||||
|
|
||||||
;;
|
;;; Parts
|
||||||
|
|
||||||
(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth button)
|
(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth button)
|
||||||
;; Run the handlers until one of them succeeds.
|
;; Run the handlers until one of them succeeds.
|
||||||
|
@ -1098,6 +1113,8 @@ is t, hide the part initially and show the button."
|
||||||
(notmuch-show-message-visible msg (and (plist-get msg :match)
|
(notmuch-show-message-visible msg (and (plist-get msg :match)
|
||||||
(not (plist-get msg :excluded))))))
|
(not (plist-get msg :excluded))))))
|
||||||
|
|
||||||
|
;;; Toggle commands
|
||||||
|
|
||||||
(defun notmuch-show-toggle-process-crypto ()
|
(defun notmuch-show-toggle-process-crypto ()
|
||||||
"Toggle the processing of cryptographic MIME parts."
|
"Toggle the processing of cryptographic MIME parts."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -1126,6 +1143,8 @@ is t, hide the part initially and show the button."
|
||||||
"Content is not indented."))
|
"Content is not indented."))
|
||||||
(notmuch-show-refresh-view))
|
(notmuch-show-refresh-view))
|
||||||
|
|
||||||
|
;;; Main insert functions
|
||||||
|
|
||||||
(defun notmuch-show-insert-tree (tree depth)
|
(defun notmuch-show-insert-tree (tree depth)
|
||||||
"Insert the message tree TREE at depth DEPTH in the current thread."
|
"Insert the message tree TREE at depth DEPTH in the current thread."
|
||||||
(let ((msg (car tree))
|
(let ((msg (car tree))
|
||||||
|
@ -1143,6 +1162,8 @@ is t, hide the part initially and show the button."
|
||||||
"Insert the forest of threads FOREST."
|
"Insert the forest of threads FOREST."
|
||||||
(mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))
|
(mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))
|
||||||
|
|
||||||
|
;;; Link buttons
|
||||||
|
|
||||||
(defvar notmuch-id-regexp
|
(defvar notmuch-id-regexp
|
||||||
(concat
|
(concat
|
||||||
;; Match the id: prefix only if it begins a word (to disallow, for
|
;; Match the id: prefix only if it begins a word (to disallow, for
|
||||||
|
@ -1203,6 +1224,8 @@ buttons for a corresponding notmuch search."
|
||||||
'help-echo "Mouse-1, RET: search for this message"
|
'help-echo "Mouse-1, RET: search for this message"
|
||||||
'face goto-address-mail-face)))))
|
'face goto-address-mail-face)))))
|
||||||
|
|
||||||
|
;;; Show command
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun notmuch-show (thread-id &optional elide-toggle parent-buffer query-context buffer-name)
|
(defun notmuch-show (thread-id &optional elide-toggle parent-buffer query-context buffer-name)
|
||||||
"Run \"notmuch show\" with the given thread ID and display results.
|
"Run \"notmuch show\" with the given thread ID and display results.
|
||||||
|
@ -1325,6 +1348,8 @@ If no messages match the query return NIL."
|
||||||
;; Report back to the caller whether any messages matched.
|
;; Report back to the caller whether any messages matched.
|
||||||
forest))
|
forest))
|
||||||
|
|
||||||
|
;;; Refresh command
|
||||||
|
|
||||||
(defun notmuch-show-capture-state ()
|
(defun notmuch-show-capture-state ()
|
||||||
"Capture the state of the current buffer.
|
"Capture the state of the current buffer.
|
||||||
|
|
||||||
|
@ -1399,6 +1424,8 @@ reset based on the original query."
|
||||||
(ding)
|
(ding)
|
||||||
(message "Refreshing the buffer resulted in no messages!"))))
|
(message "Refreshing the buffer resulted in no messages!"))))
|
||||||
|
|
||||||
|
;;; Keymaps
|
||||||
|
|
||||||
(defvar notmuch-show-stash-map
|
(defvar notmuch-show-stash-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map "c" 'notmuch-show-stash-cc)
|
(define-key map "c" 'notmuch-show-stash-cc)
|
||||||
|
@ -1479,6 +1506,8 @@ reset based on the original query."
|
||||||
map)
|
map)
|
||||||
"Keymap for \"notmuch show\" buffers.")
|
"Keymap for \"notmuch show\" buffers.")
|
||||||
|
|
||||||
|
;;; Mode
|
||||||
|
|
||||||
(define-derived-mode notmuch-show-mode fundamental-mode "notmuch-show"
|
(define-derived-mode notmuch-show-mode fundamental-mode "notmuch-show"
|
||||||
"Major mode for viewing a thread with notmuch.
|
"Major mode for viewing a thread with notmuch.
|
||||||
|
|
||||||
|
@ -1515,6 +1544,8 @@ All currently available key bindings:
|
||||||
(setq imenu-extract-index-name-function
|
(setq imenu-extract-index-name-function
|
||||||
#'notmuch-show-imenu-extract-index-name-function))
|
#'notmuch-show-imenu-extract-index-name-function))
|
||||||
|
|
||||||
|
;;; Tree commands
|
||||||
|
|
||||||
(defun notmuch-tree-from-show-current-query ()
|
(defun notmuch-tree-from-show-current-query ()
|
||||||
"Call notmuch tree with the current query."
|
"Call notmuch tree with the current query."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -1529,17 +1560,14 @@ All currently available key bindings:
|
||||||
notmuch-show-query-context
|
notmuch-show-query-context
|
||||||
(notmuch-show-get-message-id)))
|
(notmuch-show-get-message-id)))
|
||||||
|
|
||||||
|
;;; Movement related functions.
|
||||||
|
|
||||||
(defun notmuch-show-move-to-message-top ()
|
(defun notmuch-show-move-to-message-top ()
|
||||||
(goto-char (notmuch-show-message-top)))
|
(goto-char (notmuch-show-message-top)))
|
||||||
|
|
||||||
(defun notmuch-show-move-to-message-bottom ()
|
(defun notmuch-show-move-to-message-bottom ()
|
||||||
(goto-char (notmuch-show-message-bottom)))
|
(goto-char (notmuch-show-message-bottom)))
|
||||||
|
|
||||||
(defun notmuch-show-message-adjust ()
|
|
||||||
(recenter 0))
|
|
||||||
|
|
||||||
;; Movement related functions.
|
|
||||||
|
|
||||||
;; There's some strangeness here where a text property applied to a
|
;; There's some strangeness here where a text property applied to a
|
||||||
;; region a->b is not found when point is at b. We walk backwards
|
;; region a->b is not found when point is at b. We walk backwards
|
||||||
;; until finding the property.
|
;; until finding the property.
|
||||||
|
@ -1583,8 +1611,7 @@ effects."
|
||||||
(cl-loop do (funcall function)
|
(cl-loop do (funcall function)
|
||||||
while (notmuch-show-goto-message-next))))
|
while (notmuch-show-goto-message-next))))
|
||||||
|
|
||||||
;; Functions relating to the visibility of messages and their
|
;;; Functions relating to the visibility of messages and their components.
|
||||||
;; components.
|
|
||||||
|
|
||||||
(defun notmuch-show-message-visible (props visible-p)
|
(defun notmuch-show-message-visible (props visible-p)
|
||||||
(overlay-put (plist-get props :message-overlay) 'invisible (not visible-p))
|
(overlay-put (plist-get props :message-overlay) 'invisible (not visible-p))
|
||||||
|
@ -1594,8 +1621,7 @@ effects."
|
||||||
(overlay-put (plist-get props :headers-overlay) 'invisible (not visible-p))
|
(overlay-put (plist-get props :headers-overlay) 'invisible (not visible-p))
|
||||||
(notmuch-show-set-prop :headers-visible visible-p props))
|
(notmuch-show-set-prop :headers-visible visible-p props))
|
||||||
|
|
||||||
;; Functions for setting and getting attributes of the current
|
;;; Functions for setting and getting attributes of the current message.
|
||||||
;; message.
|
|
||||||
|
|
||||||
(defun notmuch-show-set-message-properties (props)
|
(defun notmuch-show-set-message-properties (props)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
|
@ -1768,8 +1794,7 @@ Reshows the current thread with matches defined by the new query-string."
|
||||||
(notmuch-show-refresh-view t)
|
(notmuch-show-refresh-view t)
|
||||||
(notmuch-show-goto-message msg-id)))
|
(notmuch-show-goto-message msg-id)))
|
||||||
|
|
||||||
;; Functions for getting attributes of several messages in the current
|
;;; Functions for getting attributes of several messages in the current thread.
|
||||||
;; thread.
|
|
||||||
|
|
||||||
(defun notmuch-show-get-message-ids-for-open-messages ()
|
(defun notmuch-show-get-message-ids-for-open-messages ()
|
||||||
"Return a list of all id: queries for open messages in the current thread."
|
"Return a list of all id: queries for open messages in the current thread."
|
||||||
|
@ -1783,7 +1808,7 @@ Reshows the current thread with matches defined by the new query-string."
|
||||||
(setq done (not (notmuch-show-goto-message-next))))
|
(setq done (not (notmuch-show-goto-message-next))))
|
||||||
message-ids)))
|
message-ids)))
|
||||||
|
|
||||||
;; Commands typically bound to keys.
|
;;; Commands typically bound to keys.
|
||||||
|
|
||||||
(defun notmuch-show-advance ()
|
(defun notmuch-show-advance ()
|
||||||
"Advance through thread.
|
"Advance through thread.
|
||||||
|
@ -1911,6 +1936,9 @@ any effects from previous calls to
|
||||||
(message-resend addresses)
|
(message-resend addresses)
|
||||||
(notmuch-bury-or-kill-this-buffer)))
|
(notmuch-bury-or-kill-this-buffer)))
|
||||||
|
|
||||||
|
(defun notmuch-show-message-adjust ()
|
||||||
|
(recenter 0))
|
||||||
|
|
||||||
(defun notmuch-show-next-message (&optional pop-at-end)
|
(defun notmuch-show-next-message (&optional pop-at-end)
|
||||||
"Show the next message.
|
"Show the next message.
|
||||||
|
|
||||||
|
@ -2381,7 +2409,7 @@ omit --in-reply-to=<Message-Id>."
|
||||||
(list (notmuch-show-get-message-id t)) "--in-reply-to="))))
|
(list (notmuch-show-get-message-id t)) "--in-reply-to="))))
|
||||||
" ")))
|
" ")))
|
||||||
|
|
||||||
;; Interactive part functions and their helpers
|
;;; Interactive part functions and their helpers
|
||||||
|
|
||||||
(defun notmuch-show-generate-part-buffer (msg part)
|
(defun notmuch-show-generate-part-buffer (msg part)
|
||||||
"Return a temporary buffer containing the specified part's content."
|
"Return a temporary buffer containing the specified part's content."
|
||||||
|
@ -2528,6 +2556,8 @@ browsing."
|
||||||
(funcall fn (completing-read prompt urls nil nil nil nil (car urls)))
|
(funcall fn (completing-read prompt urls nil nil nil nil (car urls)))
|
||||||
(message "No URLs found."))))
|
(message "No URLs found."))))
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-show)
|
(provide 'notmuch-show)
|
||||||
|
|
||||||
;;; notmuch-show.el ends here
|
;;; notmuch-show.el ends here
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
|
(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
|
||||||
(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
|
(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
|
||||||
|
|
||||||
|
;;; Keys
|
||||||
|
|
||||||
(define-widget 'notmuch-tag-key-type 'list
|
(define-widget 'notmuch-tag-key-type 'list
|
||||||
"A single key tagging binding."
|
"A single key tagging binding."
|
||||||
:format "%v"
|
:format "%v"
|
||||||
|
@ -84,6 +86,8 @@ from TAGGING-OPERATIONS."
|
||||||
:type '(repeat notmuch-tag-key-type)
|
:type '(repeat notmuch-tag-key-type)
|
||||||
:group 'notmuch-tag)
|
:group 'notmuch-tag)
|
||||||
|
|
||||||
|
;;; Faces and Formats
|
||||||
|
|
||||||
(define-widget 'notmuch-tag-format-type 'lazy
|
(define-widget 'notmuch-tag-format-type 'lazy
|
||||||
"Customize widget for notmuch-tag-format and friends."
|
"Customize widget for notmuch-tag-format and friends."
|
||||||
:type '(alist :key-type (regexp :tag "Tag")
|
:type '(alist :key-type (regexp :tag "Tag")
|
||||||
|
@ -217,6 +221,8 @@ See `notmuch-tag-formats' for full documentation."
|
||||||
:group 'notmuch-faces
|
:group 'notmuch-faces
|
||||||
:type 'notmuch-tag-format-type)
|
:type 'notmuch-tag-format-type)
|
||||||
|
|
||||||
|
;;; Icons
|
||||||
|
|
||||||
(defun notmuch-tag-format-image-data (tag data)
|
(defun notmuch-tag-format-image-data (tag data)
|
||||||
"Replace TAG with image DATA, if available.
|
"Replace TAG with image DATA, if available.
|
||||||
|
|
||||||
|
@ -270,6 +276,8 @@ This can be used with `notmuch-tag-format-image-data'."
|
||||||
</g>
|
</g>
|
||||||
</svg>")
|
</svg>")
|
||||||
|
|
||||||
|
;;; Format Handling
|
||||||
|
|
||||||
(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
|
(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
|
||||||
"Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
|
"Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
|
||||||
|
|
||||||
|
@ -347,6 +355,8 @@ changed (the normal case) are shown using formats from
|
||||||
face
|
face
|
||||||
t)))
|
t)))
|
||||||
|
|
||||||
|
;;; Hooks
|
||||||
|
|
||||||
(defcustom notmuch-before-tag-hook nil
|
(defcustom notmuch-before-tag-hook nil
|
||||||
"Hooks that are run before tags of a message are modified.
|
"Hooks that are run before tags of a message are modified.
|
||||||
|
|
||||||
|
@ -369,6 +379,8 @@ the messages that were tagged."
|
||||||
:options '(notmuch-hl-line-mode)
|
:options '(notmuch-hl-line-mode)
|
||||||
:group 'notmuch-hooks)
|
:group 'notmuch-hooks)
|
||||||
|
|
||||||
|
;;; User Input
|
||||||
|
|
||||||
(defvar notmuch-select-tag-history nil
|
(defvar notmuch-select-tag-history nil
|
||||||
"Variable to store minibuffer history for
|
"Variable to store minibuffer history for
|
||||||
`notmuch-select-tag-with-completion' function.")
|
`notmuch-select-tag-with-completion' function.")
|
||||||
|
@ -429,6 +441,8 @@ initial input in the minibuffer."
|
||||||
nil nil initial-input
|
nil nil initial-input
|
||||||
'notmuch-read-tag-changes-history))))
|
'notmuch-read-tag-changes-history))))
|
||||||
|
|
||||||
|
;;; Tagging
|
||||||
|
|
||||||
(defun notmuch-update-tags (tags tag-changes)
|
(defun notmuch-update-tags (tags tag-changes)
|
||||||
"Return a copy of TAGS with additions and removals from TAG-CHANGES.
|
"Return a copy of TAGS with additions and removals from TAG-CHANGES.
|
||||||
|
|
||||||
|
@ -547,7 +561,7 @@ and vice versa."
|
||||||
(setq action-map (nreverse action-map))
|
(setq action-map (nreverse action-map))
|
||||||
(notmuch-jump action-map "Tag: ")))
|
(notmuch-jump action-map "Tag: ")))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-tag)
|
(provide 'notmuch-tag)
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@
|
||||||
(defvar-local notmuch-tree-unthreaded nil
|
(defvar-local notmuch-tree-unthreaded nil
|
||||||
"A buffer local copy of argument unthreaded to the function notmuch-tree.")
|
"A buffer local copy of argument unthreaded to the function notmuch-tree.")
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defgroup notmuch-tree nil
|
(defgroup notmuch-tree nil
|
||||||
"Showing message and thread structure."
|
"Showing message and thread structure."
|
||||||
:group 'notmuch)
|
:group 'notmuch)
|
||||||
|
@ -118,7 +120,9 @@ For example:
|
||||||
notmuch-unthreaded-result-format
|
notmuch-unthreaded-result-format
|
||||||
notmuch-tree-result-format))
|
notmuch-tree-result-format))
|
||||||
|
|
||||||
;; Faces for messages that match the query.
|
;;; Faces
|
||||||
|
;;;; Faces for messages that match the query
|
||||||
|
|
||||||
(defface notmuch-tree-match-face
|
(defface notmuch-tree-match-face
|
||||||
'((t :inherit default))
|
'((t :inherit default))
|
||||||
"Default face used in tree mode face for matching messages"
|
"Default face used in tree mode face for matching messages"
|
||||||
|
@ -169,7 +173,8 @@ For example:
|
||||||
:group 'notmuch-tree
|
:group 'notmuch-tree
|
||||||
:group 'notmuch-faces)
|
:group 'notmuch-faces)
|
||||||
|
|
||||||
;; Faces for messages that do not match the query.
|
;;;; Faces for messages that do not match the query
|
||||||
|
|
||||||
(defface notmuch-tree-no-match-face
|
(defface notmuch-tree-no-match-face
|
||||||
'((t (:foreground "gray")))
|
'((t (:foreground "gray")))
|
||||||
"Default face used in tree mode face for non-matching messages."
|
"Default face used in tree mode face for non-matching messages."
|
||||||
|
@ -206,6 +211,8 @@ For example:
|
||||||
:group 'notmuch-tree
|
:group 'notmuch-tree
|
||||||
:group 'notmuch-faces)
|
:group 'notmuch-faces)
|
||||||
|
|
||||||
|
;;; Variables
|
||||||
|
|
||||||
(defvar-local notmuch-tree-previous-subject
|
(defvar-local notmuch-tree-previous-subject
|
||||||
"The subject of the most recent result shown during the async display.")
|
"The subject of the most recent result shown during the async display.")
|
||||||
|
|
||||||
|
@ -238,6 +245,8 @@ 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.")
|
if the user has loaded a different buffer in that window.")
|
||||||
(put 'notmuch-tree-message-buffer 'permanent-local t)
|
(put 'notmuch-tree-message-buffer 'permanent-local t)
|
||||||
|
|
||||||
|
;;; Tree wrapper commands
|
||||||
|
|
||||||
(defmacro notmuch-tree--define-do-in-message-window (name cmd)
|
(defmacro notmuch-tree--define-do-in-message-window (name cmd)
|
||||||
"Define NAME as a command that calls CMD interactively in the message window.
|
"Define NAME as a command that calls CMD interactively in the message window.
|
||||||
If the message pane is closed then this command does nothing.
|
If the message pane is closed then this command does nothing.
|
||||||
|
@ -305,6 +314,8 @@ then NAME behaves like CMD."
|
||||||
notmuch-tree-view-raw-message
|
notmuch-tree-view-raw-message
|
||||||
notmuch-show-view-raw-message)
|
notmuch-show-view-raw-message)
|
||||||
|
|
||||||
|
;;; Keymap
|
||||||
|
|
||||||
(defvar notmuch-tree-mode-map
|
(defvar notmuch-tree-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(set-keymap-parent map notmuch-common-keymap)
|
(set-keymap-parent map notmuch-common-keymap)
|
||||||
|
@ -363,6 +374,8 @@ then NAME behaves like CMD."
|
||||||
map)
|
map)
|
||||||
"Keymap for \"notmuch tree\" buffers.")
|
"Keymap for \"notmuch tree\" buffers.")
|
||||||
|
|
||||||
|
;;; Message properties
|
||||||
|
|
||||||
(defun notmuch-tree-get-message-properties ()
|
(defun notmuch-tree-get-message-properties ()
|
||||||
"Return the properties of the current message as a plist.
|
"Return the properties of the current message as a plist.
|
||||||
|
|
||||||
|
@ -414,6 +427,8 @@ Some useful entries are:
|
||||||
(interactive)
|
(interactive)
|
||||||
(notmuch-tree-get-prop :match))
|
(notmuch-tree-get-prop :match))
|
||||||
|
|
||||||
|
;;; Update display
|
||||||
|
|
||||||
(defun notmuch-tree-refresh-result ()
|
(defun notmuch-tree-refresh-result ()
|
||||||
"Redisplay the current message line.
|
"Redisplay the current message line.
|
||||||
|
|
||||||
|
@ -456,6 +471,8 @@ NOT change the database."
|
||||||
(when (string= tree-msg-id (notmuch-show-get-message-id))
|
(when (string= tree-msg-id (notmuch-show-get-message-id))
|
||||||
(notmuch-show-update-tags new-tags)))))))
|
(notmuch-show-update-tags new-tags)))))))
|
||||||
|
|
||||||
|
;;; Commands (and some helper functions used by them)
|
||||||
|
|
||||||
(defun notmuch-tree-tag (tag-changes)
|
(defun notmuch-tree-tag (tag-changes)
|
||||||
"Change tags for the current message."
|
"Change tags for the current message."
|
||||||
(interactive
|
(interactive
|
||||||
|
@ -835,7 +852,7 @@ buffer."
|
||||||
(notmuch-tree-tag-thread
|
(notmuch-tree-tag-thread
|
||||||
(notmuch-tag-change-list notmuch-archive-tags unarchive))))
|
(notmuch-tag-change-list notmuch-archive-tags unarchive))))
|
||||||
|
|
||||||
;; Functions below here display the tree buffer itself.
|
;;; Functions for displaying the tree buffer itself
|
||||||
|
|
||||||
(defun notmuch-tree-clean-address (address)
|
(defun notmuch-tree-clean-address (address)
|
||||||
"Try to clean a single email ADDRESS for display. Return
|
"Try to clean a single email ADDRESS for display. Return
|
||||||
|
@ -1142,7 +1159,7 @@ The arguments are:
|
||||||
(interactive)
|
(interactive)
|
||||||
(notmuch-tree query query-context target buffer-name open-target t))
|
(notmuch-tree query query-context target buffer-name open-target t))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-tree)
|
(provide 'notmuch-tree)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
(msg part depth &optional hide))
|
(msg part depth &optional hide))
|
||||||
(defvar notmuch-show-indent-messages-width)
|
(defvar notmuch-show-indent-messages-width)
|
||||||
|
|
||||||
;;
|
;;; Options
|
||||||
|
|
||||||
(defgroup notmuch-wash nil
|
(defgroup notmuch-wash nil
|
||||||
"Cleaning up messages for display."
|
"Cleaning up messages for display."
|
||||||
|
@ -130,6 +130,8 @@ or at the window width (whichever one is lower)."
|
||||||
(integer :tag "number of characters"))
|
(integer :tag "number of characters"))
|
||||||
:group 'notmuch-wash)
|
:group 'notmuch-wash)
|
||||||
|
|
||||||
|
;;; Faces
|
||||||
|
|
||||||
(defface notmuch-wash-toggle-button
|
(defface notmuch-wash-toggle-button
|
||||||
'((t (:inherit font-lock-comment-face)))
|
'((t (:inherit font-lock-comment-face)))
|
||||||
"Face used for buttons toggling the visibility of washed away
|
"Face used for buttons toggling the visibility of washed away
|
||||||
|
@ -143,6 +145,8 @@ message parts."
|
||||||
:group 'notmuch-wash
|
:group 'notmuch-wash
|
||||||
:group 'notmuch-faces)
|
:group 'notmuch-faces)
|
||||||
|
|
||||||
|
;;; Buttons
|
||||||
|
|
||||||
(defun notmuch-wash-toggle-invisible-action (cite-button)
|
(defun notmuch-wash-toggle-invisible-action (cite-button)
|
||||||
;; Toggle overlay visibility
|
;; Toggle overlay visibility
|
||||||
(let ((overlay (button-get cite-button 'overlay)))
|
(let ((overlay (button-get cite-button 'overlay)))
|
||||||
|
@ -225,6 +229,8 @@ that PREFIX should not include a newline."
|
||||||
:type button-type)))
|
:type button-type)))
|
||||||
(overlay-put overlay 'notmuch-wash-button button))))))
|
(overlay-put overlay 'notmuch-wash-button button))))))
|
||||||
|
|
||||||
|
;;; Hook functions
|
||||||
|
|
||||||
(defun notmuch-wash-excerpt-citations (msg depth)
|
(defun notmuch-wash-excerpt-citations (msg depth)
|
||||||
"Excerpt citations and up to one signature."
|
"Excerpt citations and up to one signature."
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
|
@ -270,8 +276,6 @@ that PREFIX should not include a newline."
|
||||||
msg sig-start-marker sig-end-marker
|
msg sig-start-marker sig-end-marker
|
||||||
"signature"))))))
|
"signature"))))))
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun notmuch-wash-elide-blank-lines (msg depth)
|
(defun notmuch-wash-elide-blank-lines (msg depth)
|
||||||
"Elide leading, trailing and successive blank lines."
|
"Elide leading, trailing and successive blank lines."
|
||||||
;; Algorithm derived from `article-strip-multiple-blank-lines' in
|
;; Algorithm derived from `article-strip-multiple-blank-lines' in
|
||||||
|
@ -293,8 +297,6 @@ that PREFIX should not include a newline."
|
||||||
(when (looking-at "\n")
|
(when (looking-at "\n")
|
||||||
(delete-region (match-beginning 0) (match-end 0))))
|
(delete-region (match-beginning 0) (match-end 0))))
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun notmuch-wash-tidy-citations (msg depth)
|
(defun notmuch-wash-tidy-citations (msg depth)
|
||||||
"Improve the display of cited regions of a message.
|
"Improve the display of cited regions of a message.
|
||||||
|
|
||||||
|
@ -319,8 +321,6 @@ Perform several transformations on the message body:
|
||||||
(while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)
|
(while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)
|
||||||
(replace-match "\\2")))
|
(replace-match "\\2")))
|
||||||
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun notmuch-wash-wrap-long-lines (msg depth)
|
(defun notmuch-wash-wrap-long-lines (msg depth)
|
||||||
"Wrap long lines in the message.
|
"Wrap long lines in the message.
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ the wrapped text are maintained."
|
||||||
2)))
|
2)))
|
||||||
(coolj-wrap-region (point-min) (point-max))))
|
(coolj-wrap-region (point-min) (point-max))))
|
||||||
|
|
||||||
;;
|
;;;; Convert Inline Patches
|
||||||
|
|
||||||
(require 'diff-mode)
|
(require 'diff-mode)
|
||||||
|
|
||||||
|
@ -417,7 +417,7 @@ for error."
|
||||||
(delete-region (point-min) (point-max))
|
(delete-region (point-min) (point-max))
|
||||||
(notmuch-show-insert-bodypart nil part depth)))))
|
(notmuch-show-insert-bodypart nil part depth)))))
|
||||||
|
|
||||||
;;
|
;;; _
|
||||||
|
|
||||||
(provide 'notmuch-wash)
|
(provide 'notmuch-wash)
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@
|
||||||
(require 'notmuch-message)
|
(require 'notmuch-message)
|
||||||
(require 'notmuch-parser)
|
(require 'notmuch-parser)
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-search-result-format
|
(defcustom notmuch-search-result-format
|
||||||
`(("date" . "%12s ")
|
`(("date" . "%12s ")
|
||||||
("count" . "%-7s ")
|
("count" . "%-7s ")
|
||||||
|
@ -115,6 +117,8 @@ there will be called at other points of notmuch execution."
|
||||||
(defvar notmuch-query-history nil
|
(defvar notmuch-query-history nil
|
||||||
"Variable to store minibuffer history for notmuch queries.")
|
"Variable to store minibuffer history for notmuch queries.")
|
||||||
|
|
||||||
|
;;; Mime Utilities
|
||||||
|
|
||||||
(defun notmuch-foreach-mime-part (function mm-handle)
|
(defun notmuch-foreach-mime-part (function mm-handle)
|
||||||
(cond ((stringp (car mm-handle))
|
(cond ((stringp (car mm-handle))
|
||||||
(dolist (part (cdr mm-handle))
|
(dolist (part (cdr mm-handle))
|
||||||
|
@ -151,6 +155,8 @@ there will be called at other points of notmuch execution."
|
||||||
(mm-save-part p))))
|
(mm-save-part p))))
|
||||||
mm-handle))
|
mm-handle))
|
||||||
|
|
||||||
|
;;; Integrations
|
||||||
|
|
||||||
(require 'hl-line)
|
(require 'hl-line)
|
||||||
|
|
||||||
(defun notmuch-hl-line-mode ()
|
(defun notmuch-hl-line-mode ()
|
||||||
|
@ -158,6 +164,8 @@ there will be called at other points of notmuch execution."
|
||||||
(when hl-line-overlay
|
(when hl-line-overlay
|
||||||
(overlay-put hl-line-overlay 'priority 1))))
|
(overlay-put hl-line-overlay 'priority 1))))
|
||||||
|
|
||||||
|
;;; Options
|
||||||
|
|
||||||
(defcustom notmuch-search-hook '(notmuch-hl-line-mode)
|
(defcustom notmuch-search-hook '(notmuch-hl-line-mode)
|
||||||
"List of functions to call when notmuch displays the search results."
|
"List of functions to call when notmuch displays the search results."
|
||||||
:type 'hook
|
:type 'hook
|
||||||
|
@ -165,6 +173,8 @@ there will be called at other points of notmuch execution."
|
||||||
:group 'notmuch-search
|
:group 'notmuch-search
|
||||||
:group 'notmuch-hooks)
|
:group 'notmuch-hooks)
|
||||||
|
|
||||||
|
;;; Keymap
|
||||||
|
|
||||||
(defvar notmuch-search-mode-map
|
(defvar notmuch-search-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(set-keymap-parent map notmuch-common-keymap)
|
(set-keymap-parent map notmuch-common-keymap)
|
||||||
|
@ -195,6 +205,8 @@ there will be called at other points of notmuch execution."
|
||||||
map)
|
map)
|
||||||
"Keymap for \"notmuch search\" buffers.")
|
"Keymap for \"notmuch search\" buffers.")
|
||||||
|
|
||||||
|
;;; Stashing
|
||||||
|
|
||||||
(defvar notmuch-search-stash-map
|
(defvar notmuch-search-stash-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map "i" 'notmuch-search-stash-thread-id)
|
(define-key map "i" 'notmuch-search-stash-thread-id)
|
||||||
|
@ -214,12 +226,16 @@ there will be called at other points of notmuch execution."
|
||||||
(interactive)
|
(interactive)
|
||||||
(notmuch-common-do-stash (notmuch-search-get-query)))
|
(notmuch-common-do-stash (notmuch-search-get-query)))
|
||||||
|
|
||||||
|
;;; Variables
|
||||||
|
|
||||||
(defvar notmuch-search-query-string)
|
(defvar notmuch-search-query-string)
|
||||||
(defvar notmuch-search-target-thread)
|
(defvar notmuch-search-target-thread)
|
||||||
(defvar notmuch-search-target-line)
|
(defvar notmuch-search-target-line)
|
||||||
|
|
||||||
(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>")
|
(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>")
|
||||||
|
|
||||||
|
;;; Movement
|
||||||
|
|
||||||
(defun notmuch-search-scroll-up ()
|
(defun notmuch-search-scroll-up ()
|
||||||
"Move forward through search results by one window's worth."
|
"Move forward through search results by one window's worth."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -271,6 +287,8 @@ there will be called at other points of notmuch execution."
|
||||||
(interactive)
|
(interactive)
|
||||||
(goto-char (point-min)))
|
(goto-char (point-min)))
|
||||||
|
|
||||||
|
;;; Faces
|
||||||
|
|
||||||
(defface notmuch-message-summary-face
|
(defface notmuch-message-summary-face
|
||||||
`((((class color) (background light))
|
`((((class color) (background light))
|
||||||
,@(and (>= emacs-major-version 27) '(:extend t))
|
,@(and (>= emacs-major-version 27) '(:extend t))
|
||||||
|
@ -356,6 +374,8 @@ This face is the default value for the \"unread\" tag in
|
||||||
:group 'notmuch-search
|
:group 'notmuch-search
|
||||||
:group 'notmuch-faces)
|
:group 'notmuch-faces)
|
||||||
|
|
||||||
|
;;; Mode
|
||||||
|
|
||||||
(define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
|
(define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
|
||||||
"Major mode displaying results of a notmuch search.
|
"Major mode displaying results of a notmuch search.
|
||||||
|
|
||||||
|
@ -400,6 +420,8 @@ Complete list of currently available key bindings:
|
||||||
(setq imenu-extract-index-name-function
|
(setq imenu-extract-index-name-function
|
||||||
#'notmuch-search-imenu-extract-index-name-function))
|
#'notmuch-search-imenu-extract-index-name-function))
|
||||||
|
|
||||||
|
;;; Search Results
|
||||||
|
|
||||||
(defun notmuch-search-get-result (&optional pos)
|
(defun notmuch-search-get-result (&optional pos)
|
||||||
"Return the result object for the thread at POS (or point).
|
"Return the result object for the thread at POS (or point).
|
||||||
|
|
||||||
|
@ -558,6 +580,8 @@ thread."
|
||||||
(let ((message-id (notmuch-search-find-thread-id)))
|
(let ((message-id (notmuch-search-find-thread-id)))
|
||||||
(notmuch-mua-new-reply message-id prompt-for-sender nil)))
|
(notmuch-mua-new-reply message-id prompt-for-sender nil)))
|
||||||
|
|
||||||
|
;;; Tags
|
||||||
|
|
||||||
(defun notmuch-search-set-tags (tags &optional pos)
|
(defun notmuch-search-set-tags (tags &optional pos)
|
||||||
(let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
|
(let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
|
||||||
(notmuch-search-update-result new-result pos)))
|
(notmuch-search-update-result new-result pos)))
|
||||||
|
@ -639,6 +663,8 @@ This function advances the next thread when finished."
|
||||||
(when (eq beg end)
|
(when (eq beg end)
|
||||||
(notmuch-search-next-thread)))
|
(notmuch-search-next-thread)))
|
||||||
|
|
||||||
|
;;; Search Results
|
||||||
|
|
||||||
(defun notmuch-search-update-result (result &optional pos)
|
(defun notmuch-search-update-result (result &optional pos)
|
||||||
"Replace the result object of the thread at POS (or point) by
|
"Replace the result object of the thread at POS (or point) by
|
||||||
RESULT and redraw it.
|
RESULT and redraw it.
|
||||||
|
@ -881,6 +907,8 @@ sets the :orig-tag property."
|
||||||
(notmuch-sexp-parse-partial-list 'notmuch-search-append-result
|
(notmuch-sexp-parse-partial-list 'notmuch-search-append-result
|
||||||
results-buf)))))
|
results-buf)))))
|
||||||
|
|
||||||
|
;;; Commands (and some helper functions used by them)
|
||||||
|
|
||||||
(defun notmuch-search-tag-all (tag-changes)
|
(defun notmuch-search-tag-all (tag-changes)
|
||||||
"Add/remove tags from all messages in current search buffer.
|
"Add/remove tags from all messages in current search buffer.
|
||||||
|
|
||||||
|
@ -1132,7 +1160,7 @@ notmuch buffers exist, run `notmuch'."
|
||||||
(pop-to-buffer-same-window first))
|
(pop-to-buffer-same-window first))
|
||||||
(notmuch))))
|
(notmuch))))
|
||||||
|
|
||||||
;;;; Imenu Support
|
;;; Imenu Support
|
||||||
|
|
||||||
(defun notmuch-search-imenu-prev-index-position-function ()
|
(defun notmuch-search-imenu-prev-index-position-function ()
|
||||||
"Move point to previous message in notmuch-search buffer.
|
"Move point to previous message in notmuch-search buffer.
|
||||||
|
@ -1149,6 +1177,8 @@ beginning of the line."
|
||||||
(author (notmuch-search-find-authors)))
|
(author (notmuch-search-find-authors)))
|
||||||
(format "%s (%s)" subject author)))
|
(format "%s (%s)" subject author)))
|
||||||
|
|
||||||
|
;;; _
|
||||||
|
|
||||||
(setq mail-user-agent 'notmuch-user-agent)
|
(setq mail-user-agent 'notmuch-user-agent)
|
||||||
|
|
||||||
(provide 'notmuch)
|
(provide 'notmuch)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; test-lib.el --- auxiliary stuff for Notmuch Emacs tests.
|
;;; test-lib.el --- auxiliary stuff for Notmuch Emacs tests
|
||||||
;;
|
;;
|
||||||
;; Copyright © Carl Worth
|
;; Copyright © Carl Worth
|
||||||
;; Copyright © David Edmondson
|
;; Copyright © David Edmondson
|
||||||
|
@ -20,6 +20,8 @@
|
||||||
;;
|
;;
|
||||||
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
|
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
|
|
||||||
;; Ensure that the dynamic variables that are defined by this library
|
;; Ensure that the dynamic variables that are defined by this library
|
||||||
|
|
Loading…
Reference in a new issue