`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.
19 files changed:
-;;; This is a simple derivative of some functionality from
-;;; `longlines.el'. The key difference is that this version will
-;;; insert a prefix at the head of each wrapped line. The prefix is
-;;; calculated from the originating long line.
+;; This is a simple derivative of some functionality from
+;; `longlines.el'. The key difference is that this version will
+;; insert a prefix at the head of each wrapped line. The prefix is
+;; calculated from the originating long line.
-;;; No minor-mode is provided, the caller is expected to call
-;;; `coolj-wrap-region' to wrap the region of interest.
+;; No minor-mode is provided, the caller is expected to call
+;; `coolj-wrap-region' to wrap the region of interest.
(require 'notmuch-parser)
(require 'notmuch-lib)
(require 'notmuch-company)
(require 'notmuch-parser)
(require 'notmuch-lib)
(require 'notmuch-company)
(declare-function company-manual-begin "company")
(declare-function company-manual-begin "company")
(defvar notmuch-address-last-harvest 0
"Time of last address harvest.")
(defvar notmuch-address-last-harvest 0
"Time of last address harvest.")
(or notmuch-address-full-harvest-finished
(notmuch-address--load-address-hash)))
(or notmuch-address-full-harvest-finished
(notmuch-address--load-address-hash)))
(defcustom notmuch-address-command 'internal
"Determines how address completion candidates are generated.
(defcustom notmuch-address-command 'internal
"Determines how address completion candidates are generated.
:group 'notmuch-address
:group 'notmuch-hooks)
:group 'notmuch-address
: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)
"Call (`completing-read'
PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
(defun notmuch-address-selection-function (prompt collection initial-input)
"Call (`completing-read'
PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
(defun notmuch-address-message-insinuate ()
(message "calling notmuch-address-message-insinuate is no longer needed"))
(defun notmuch-address-message-insinuate ()
(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 ()
(let* ((setup-company (and notmuch-address-use-company
(require 'company nil t)))
(defun notmuch-address-setup ()
(let* ((setup-company (and notmuch-address-use-company
(require 'company nil t)))
(kill-local-variable 'company-idle-delay)
(setq-local company-idle-delay nil))))
(kill-local-variable 'company-idle-delay)
(setq-local company-idle-delay nil))))
(defun notmuch-address-matching (substring)
"Returns a list of completion candidates matching SUBSTRING.
The candidates are taken from `notmuch-address-completions'."
(defun notmuch-address-matching (substring)
"Returns a list of completion candidates matching SUBSTRING.
The candidates are taken from `notmuch-address-completions'."
(defun notmuch-address-harvest-addr (result)
(let ((name-addr (plist-get result :name-addr)))
(puthash name-addr t notmuch-address-completions)))
(defun notmuch-address-harvest-addr (result)
(let ((name-addr (plist-get result :name-addr)))
(puthash name-addr t notmuch-address-completions)))
(setq notmuch-address-full-harvest-finished t))
(setq notmuch-address-last-harvest 0)))))))
(setq notmuch-address-full-harvest-finished t))
(setq notmuch-address-last-harvest 0)))))))
+;;; Standalone completion
(defun notmuch-address-from-minibuffer (prompt)
(if (not notmuch-address-command)
(defun notmuch-address-from-minibuffer (prompt)
(if (not notmuch-address-command)
(let ((minibuffer-local-map rmap))
(read-string prompt)))))
(let ((minibuffer-local-map rmap))
(read-string prompt)))))
(provide 'notmuch-address)
(provide 'notmuch-address)
(run-hook-with-args 'notmuch-address-post-completion-functions arg))
(no-cache t))))
(run-hook-with-args 'notmuch-address-post-completion-functions arg))
(no-cache t))))
(provide 'notmuch-company)
;;; notmuch-company.el ends here
(provide 'notmuch-company)
;;; notmuch-company.el ends here
(unless (fboundp 'message--fold-long-headers)
(add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
(unless (fboundp 'message--fold-long-headers)
(add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
-;; End of compatibility functions
-
(provide 'notmuch-compat)
;;; notmuch-compat.el ends here
(provide 'notmuch-compat)
;;; notmuch-compat.el ends here
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
(defcustom notmuch-crypto-process-mime t
"Whether to process cryptographic MIME parts.
(defcustom notmuch-crypto-process-mime t
"Whether to process cryptographic MIME parts.
:type 'string
:group 'notmuch-crypto)
:type 'string
:group 'notmuch-crypto)
(defface notmuch-crypto-part-header
'((((class color)
(background dark))
(defface notmuch-crypto-part-header
'((((class color)
(background dark))
:group 'notmuch-crypto
:group 'notmuch-faces)
:group 'notmuch-crypto
:group 'notmuch-faces)
(define-button-type 'notmuch-crypto-status-button-type
'action (lambda (button) (message (button-get button 'help-echo)))
'follow-link t
(define-button-type 'notmuch-crypto-status-button-type
'action (lambda (button) (message (button-get button 'help-echo)))
'follow-link t
'mouse-face 'notmuch-crypto-decryption)
(insert "\n"))
'mouse-face 'notmuch-crypto-decryption)
(insert "\n"))
(provide 'notmuch-crypto)
(provide 'notmuch-crypto)
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
(declare-function notmuch-message-mode "notmuch-mua")
(declare-function notmuch-show-get-message-id "notmuch-show" (&optional bare))
(declare-function notmuch-message-mode "notmuch-mua")
(defgroup notmuch-draft nil
"Saving and editing drafts in Notmuch."
:group 'notmuch)
(defgroup notmuch-draft nil
"Saving and editing drafts in Notmuch."
:group 'notmuch)
:group 'notmuch-draft
:group 'notmuch-crypto)
:group 'notmuch-draft
:group 'notmuch-crypto)
(defvar notmuch-draft-encryption-tag-regex
"<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
"Regular expression matching mml tags indicating encryption of part or message.")
(defvar notmuch-draft-encryption-tag-regex
"<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
"Regular expression matching mml tags indicating encryption of part or message.")
;; but notmuch doesn't want that form, so remove them.
(concat "draft-" (substring (message-make-message-id) 1 -1)))
;; but notmuch doesn't want that form, so remove them.
(concat "draft-" (substring (message-make-message-id) 1 -1)))
(defun notmuch-draft-save ()
"Save the current draft message in the notmuch database.
(defun notmuch-draft-save ()
"Save the current draft message in the notmuch database.
(defun notmuch-draft-resume (id)
"Resume editing of message with id ID."
(defun notmuch-draft-resume (id)
"Resume editing of message with id ID."
+ ;; Used by command `notmuch-show-resume-message'.
(let* ((tags (process-lines notmuch-command "search" "--output=tags"
"--exclude=false" id))
(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags))))
(let* ((tags (process-lines notmuch-command "search" "--output=tags"
"--exclude=false" id))
(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags))))
;; message is resaved or sent.
(setq notmuch-draft-id (and draft id)))))
;; message is resaved or sent.
(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)
;;; notmuch-draft.el ends here
(provide 'notmuch-draft)
;;; notmuch-draft.el ends here
(&optional query query-context target buffer-name open-target))
(&optional query query-context target buffer-name open-target))
(defun notmuch-saved-search-get (saved-search field)
"Get FIELD from SAVED-SEARCH.
(defun notmuch-saved-search-get (saved-search field)
"Get FIELD from SAVED-SEARCH.
(defvar notmuch-hello-indent 4
"How much to indent non-headers.")
(defvar notmuch-hello-indent 4
"How much to indent non-headers.")
+(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
+
(defcustom notmuch-show-logo t
"Should the notmuch logo be shown?"
:type 'boolean
(defcustom notmuch-show-logo t
"Should the notmuch logo be shown?"
:type 'boolean
:group 'notmuch-hello
:type 'boolean)
:group 'notmuch-hello
:type 'boolean)
+;;; Internal variables
+
(defvar notmuch-hello-hidden-sections nil
"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.")
(defvar notmuch-hello-hidden-sections nil
"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.")
-(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)))))
+;;; Widgets for inserters
(define-widget 'notmuch-search-item 'item
"A recent search."
(define-widget 'notmuch-search-item 'item
"A recent search."
1 ; for the space before the [del] button
5))) ; for the [del] button
1 ; for the space before the [del] button
5))) ; for the [del] button
(defun notmuch-hello-search (widget &rest _event)
(let ((search (widget-value widget)))
(when search
(defun notmuch-hello-search (widget &rest _event)
(let ((search (widget-value widget)))
(when search
(delete search notmuch-search-history)))
(notmuch-hello-update)))
(delete search notmuch-search-history)))
(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)
(or (cl-loop for elem in searches-alist
maximize (length (notmuch-saved-search-get elem :name)))
(defun notmuch-hello-longest-label (searches-alist)
(or (cl-loop for elem in searches-alist
maximize (length (notmuch-saved-search-get elem :name)))
(list (plist-put elem-plist :count message-count)))))
query-list)))
(list (plist-put elem-plist :count message-count)))))
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)
"Insert buttons for SEARCHES.
(defun notmuch-hello-insert-buttons (searches)
"Insert buttons for SEARCHES.
(unless (eq (% count tags-per-line) 0)
(widget-insert "\n"))))
(unless (eq (% count tags-per-line) 0)
(widget-insert "\n"))))
-(defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png")))
(defun notmuch-hello-update ()
"Update the notmuch-hello buffer."
(defun notmuch-hello-update ()
"Update the notmuch-hello buffer."
;;(setq buffer-read-only t)
)
;;(setq buffer-read-only t)
)
(defun notmuch-hello-generate-tag-alist (&optional hide-tags)
"Return an alist from tags to queries to display in the all-tags section."
(cl-mapcan (lambda (tag)
(defun notmuch-hello-generate-tag-alist (&optional hide-tags)
"Return an alist from tags to queries to display in the all-tags section."
(cl-mapcan (lambda (tag)
(let ((fill-column (- (window-width) notmuch-hello-indent)))
(center-region start (point)))))
(let ((fill-column (- (window-width) notmuch-hello-indent)))
(center-region start (point)))))
;;;###autoload
(defun notmuch-hello (&optional no-display)
"Run notmuch and display saved searches, known tags, etc."
;;;###autoload
(defun notmuch-hello (&optional no-display)
"Run notmuch and display saved searches, known tags, etc."
(run-hooks 'notmuch-hello-refresh-hook)
(setq notmuch-hello-first-run nil))
(run-hooks 'notmuch-hello-refresh-hook)
(setq notmuch-hello-first-run nil))
(exit-minibuffer)))))))
map))
(exit-minibuffer)))))))
map))
(provide 'notmuch-jump)
;;; notmuch-jump.el ends here
(provide 'notmuch-jump)
;;; notmuch-jump.el ends here
(defconst notmuch-emacs-version "unknown"
"Placeholder variable when notmuch-version.el[c] is not available."))
(defconst notmuch-emacs-version "unknown"
"Placeholder variable when notmuch-version.el[c] is not available."))
(defgroup notmuch nil
"Notmuch mail reader for Emacs."
:group 'mail)
(defgroup notmuch nil
"Notmuch mail reader for Emacs."
:group 'mail)
"Graphical attributes for displaying text"
:group 'notmuch)
"Graphical attributes for displaying text"
:group 'notmuch)
(defcustom notmuch-command "notmuch"
"Name of the notmuch binary.
(defcustom notmuch-command "notmuch"
"Name of the notmuch binary.
(string :tag "Custom script"))
:group 'notmuch-external)
(string :tag "Custom script"))
:group 'notmuch-external)
-;;
-
-(defvar notmuch-search-history nil
- "Variable to store notmuch searches history.")
-
(defcustom notmuch-archive-tags '("-inbox")
"List of tag changes to apply to a message or a thread when it is archived.
(defcustom notmuch-archive-tags '("-inbox")
"List of tag changes to apply to a message or a thread when it is archived.
:group 'notmuch-search
:group 'notmuch-show)
:group 'notmuch-search
:group 'notmuch-show)
+;;; Variables
+
+(defvar notmuch-search-history nil
+ "Variable to store notmuch searches history.")
+
(defvar notmuch-common-keymap
(let ((map (make-sparse-keymap)))
(define-key map "?" 'notmuch-help)
(defvar notmuch-common-keymap
(let ((map (make-sparse-keymap)))
(define-key map "?" 'notmuch-help)
(select-window (posn-window (event-start last-input-event)))
(button-activate button)))
(select-window (posn-window (event-start last-input-event)))
(button-activate button)))
(defun notmuch-command-to-string (&rest args)
"Synchronously invoke \"notmuch\" with the given list of arguments.
(defun notmuch-command-to-string (&rest args)
"Synchronously invoke \"notmuch\" with the given list of arguments.
(concat cli-version
" (emacs mua version " notmuch-emacs-version ")")))))
(concat cli-version
" (emacs mua version " notmuch-emacs-version ")")))))
+;;; Notmuch Configuration
+
(defun notmuch-config-get (item)
"Return a value from the notmuch configuration."
(let* ((val (notmuch-command-to-string "config" "get" item))
(defun notmuch-config-get (item)
"Return a value from the notmuch configuration."
(let* ((val (notmuch-command-to-string "config" "get" item))
(defun notmuch-user-emails ()
(cons (notmuch-user-primary-email) (notmuch-user-other-email)))
(defun notmuch-user-emails ()
(cons (notmuch-user-primary-email) (notmuch-user-other-email)))
(defun notmuch-poll ()
"Run \"notmuch new\" or an external script to import mail.
(defun notmuch-poll ()
"Run \"notmuch new\" or an external script to import mail.
(bury-buffer)
(kill-buffer)))
(bury-buffer)
(kill-buffer)))
+;;; Describe Key Bindings
+
(defun notmuch-prefix-key-description (key)
"Given a prefix key code, return a human-readable string representation.
(defun notmuch-prefix-key-description (key)
"Given a prefix key code, return a human-readable string representation.
"M-"
(concat desc " "))))
"M-"
(concat desc " "))))
(defun notmuch-describe-key (actual-key binding prefix ua-keys tail)
"Prepend cons cells describing prefix-arg ACTUAL-KEY and ACTUAL-KEY to 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.
(insert desc)))
(pop-to-buffer (help-buffer)))))
(insert desc)))
(pop-to-buffer (help-buffer)))))
+;;; Refreshing Buffers
+
(defvar-local notmuch-buffer-refresh-function nil
"Function to call to refresh the current buffer.")
(defvar-local notmuch-buffer-refresh-function nil
"Function to call to refresh the current buffer.")
(with-current-buffer buffer
(notmuch-refresh-this-buffer))))))
(with-current-buffer buffer
(notmuch-refresh-this-buffer))))))
(defun notmuch-prettify-subject (subject)
;; This function is used by `notmuch-search-process-filter' which
;; requires that we not disrupt its' matching state.
(defun notmuch-prettify-subject (subject)
;; This function is used by `notmuch-search-process-filter' which
;; requires that we not disrupt its' matching state.
(replace-regexp-in-string
"[ %\"]" (lambda (match) (format "%%%02x" (aref match 0))) str))
(replace-regexp-in-string
"[ %\"]" (lambda (match) (format "%%%02x" (aref match 0))) str))
(defun notmuch-common-do-stash (text)
"Common function to stash text in kill ring, and display in minibuffer."
(if text
(defun notmuch-common-do-stash (text)
"Common function to stash text in kill ring, and display in minibuffer."
(if text
(kill-new "")
(message "Nothing to stash!")))
(kill-new "")
(message "Nothing to stash!")))
(defun notmuch-plist-delete (plist property)
(let* ((xplist (cons nil plist))
(defun notmuch-plist-delete (plist property)
(let* ((xplist (cons nil plist))
(setq pred (cddr pred)))
(cdr xplist)))
(setq pred (cddr pred)))
(cdr xplist)))
(defun notmuch-match-content-type (t1 t2)
"Return t if t1 and t2 are matching content types, taking wildcards into account."
(let ((st1 (split-string t1 "/"))
(defun notmuch-match-content-type (t1 t2)
"Return t if t1 and t2 are matching content types, taking wildcards into account."
(let ((st1 (split-string t1 "/"))
(mm-display-part handle)
t))))))
(mm-display-part handle)
t))))))
;; 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
;; symbols of the form 'Header as keys.
;; 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
;; symbols of the form 'Header as keys.
(put-text-property start next prop (funcall func value) object)
(setq start next))))
(put-text-property start next prop (funcall func value) object)
(setq start next))))
(defun notmuch-logged-error (msg &optional extra)
"Log MSG and EXTRA to *Notmuch errors* and signal MSG.
(defun notmuch-logged-error (msg &optional extra)
"Log MSG and EXTRA to *Notmuch errors* and signal MSG.
(defvar-local notmuch-show-process-crypto nil)
(defvar-local notmuch-show-process-crypto nil)
(defun notmuch-interactive-region ()
"Return the bounds of the current interactive region.
(defun notmuch-interactive-region ()
"Return the bounds of the current interactive region.
'notmuch-interactive-region
"notmuch 0.29")
'notmuch-interactive-region
"notmuch 0.29")
(provide 'notmuch-lib)
;;; notmuch-lib.el ends here
(provide 'notmuch-lib)
;;; notmuch-lib.el ends here
(defvar notmuch-maildir-fcc-count 0)
(defvar notmuch-maildir-fcc-count 0)
(defcustom notmuch-fcc-dirs "sent"
"Determines the Fcc Header which says where to save outgoing mail.
(defcustom notmuch-fcc-dirs "sent"
"Determines the Fcc Header which says where to save outgoing mail.
(const :tag "Use simple fcc" nil))
:group 'notmuch-send)
(const :tag "Use simple fcc" nil))
: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 ()
"Add an Fcc header to the current message buffer.
(defun notmuch-fcc-header-setup ()
"Add an Fcc header to the current message buffer.
subdir
(concat (notmuch-database-path) "/" subdir))))))
subdir
(concat (notmuch-database-path) "/" subdir))))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Functions for saving a message either using notmuch insert or file
-;; fcc. First functions common to the two cases.
+;;; Functions for saving a message using either method.
(defmacro with-temporary-notmuch-message-buffer (&rest body)
"Set-up a temporary copy of the current message-mode buffer."
(defmacro with-temporary-notmuch-message-buffer (&rest body)
"Set-up a temporary copy of the current message-mode buffer."
(notmuch-maildir-fcc-with-notmuch-insert fcc-header)
(notmuch-maildir-fcc-file-fcc fcc-header)))
(notmuch-maildir-fcc-with-notmuch-insert 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)
"Use notmuch insert to put the current buffer in the database.
(defun notmuch-maildir-notmuch-insert-current-buffer (folder &optional create tags)
"Use notmuch insert to put the current buffer in the database.
(?e (notmuch-maildir-fcc-with-notmuch-insert
(read-from-minibuffer "Fcc header: " fcc-header)))))))))
(?e (notmuch-maildir-fcc-with-notmuch-insert
(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)
(replace-regexp-in-string "/\\|:"
(defun notmuch-maildir-fcc-host-fixer (hostname)
(replace-regexp-in-string "/\\|:"
(delete-file (concat destdir "/tmp/" msg-id))))
t)))
(delete-file (concat destdir "/tmp/" msg-id))))
t)))
(provide 'notmuch-maildir-fcc)
;;; notmuch-maildir-fcc.el ends here
(provide 'notmuch-maildir-fcc)
;;; notmuch-maildir-fcc.el ends here
(declare-function notmuch-draft-postpone "notmuch-draft" ())
(declare-function notmuch-draft-save "notmuch-draft" ())
(declare-function notmuch-draft-postpone "notmuch-draft" ())
(declare-function notmuch-draft-save "notmuch-draft" ())
(defcustom notmuch-mua-send-hook nil
"Hook run before sending messages."
(defcustom notmuch-mua-send-hook nil
"Hook run before sending messages."
:type 'regexp
:group 'notmuch-send)
:type 'regexp
:group 'notmuch-send)
(defun notmuch-mua-attachment-check ()
"Signal an error if the message text indicates that an
(defun notmuch-mua-attachment-check ()
"Signal an error if the message text indicates that an
(funcall original-func header references)
(unless (bolp) (insert "\n")))
(funcall original-func header references)
(unless (bolp) (insert "\n")))
(defun notmuch-mua-reply (query-string &optional sender reply-all)
(let ((args '("reply" "--format=sexp" "--format-version=4"))
(process-crypto notmuch-show-process-crypto)
(defun notmuch-mua-reply (query-string &optional sender reply-all)
(let ((args '("reply" "--format=sexp" "--format-version=4"))
(process-crypto notmuch-show-process-crypto)
(message-goto-body)
(set-buffer-modified-p nil))
(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)
(defvar notmuch-message-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-c C-c") #'notmuch-mua-send-and-exit)
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
(put 'notmuch-message-mode 'flyspell-mode-predicate 'mail-mode-flyspell-verify)
(defun notmuch-mua-pop-to-buffer (name switch-function)
"Pop to buffer NAME, and warn if it already exists and is modified.
Like `message-pop-to-buffer' but enable `notmuch-message-mode'
(defun notmuch-mua-pop-to-buffer (name switch-function)
"Pop to buffer NAME, and warn if it already exists and is modified.
Like `message-pop-to-buffer' but enable `notmuch-message-mode'
(notmuch-mua-reply query-string sender reply-all)
(deactivate-mark)))
(notmuch-mua-reply query-string sender reply-all)
(deactivate-mark)))
(defun notmuch-mua-check-no-misplaced-secure-tag ()
"Query user if there is a misplaced secure mml tag.
(defun notmuch-mua-check-no-misplaced-secure-tag ()
"Query user if there is a misplaced secure mml tag.
newline. It is likely that the message will be sent unsigned and
unencrypted. Really send? "))))
newline. It is likely that the message will be sent unsigned and
unencrypted. Really send? "))))
+;;; Finishing commands
+
(defun notmuch-mua-send-common (arg &optional exit)
(interactive "P")
(run-hooks 'notmuch-mua-send-hook)
(defun notmuch-mua-send-common (arg &optional exit)
(interactive "P")
(run-hooks 'notmuch-mua-send-hook)
(interactive)
(message-kill-buffer))
(interactive)
(message-kill-buffer))
(define-mail-user-agent 'notmuch-user-agent
'notmuch-mua-mail 'notmuch-mua-send-and-exit
(define-mail-user-agent 'notmuch-user-agent
'notmuch-mua-mail 'notmuch-mua-send-and-exit
;; composing a message.
(notmuch-mua-add-more-hidden-headers)
;; composing a message.
(notmuch-mua-add-more-hidden-headers)
(provide 'notmuch-mua)
;;; notmuch-mua.el ends here
(provide 'notmuch-mua)
;;; notmuch-mua.el ends here
(declare-function notmuch-show-get-prop "notmuch-show" (prop &optional props))
(declare-function notmuch-show-get-prop "notmuch-show" (prop &optional props))
(defcustom notmuch-print-mechanism 'notmuch-print-lpr
"How should printing be done?"
:group 'notmuch-show
(defcustom notmuch-print-mechanism 'notmuch-print-lpr
"How should printing be done?"
:group 'notmuch-show
(function :tag "Use muttprint then evince" notmuch-print-muttprint/evince)
(function :tag "Using a custom function")))
(function :tag "Use muttprint then evince" notmuch-print-muttprint/evince)
(function :tag "Using a custom function")))
(defun notmuch-print-run-evince (file)
"View FILE using 'evince'."
(defun notmuch-print-run-evince (file)
"View FILE using 'evince'."
"--printed-headers" "Date_To_From_CC_Newsgroups_*Subject*_/Tags/"
output))
"--printed-headers" "Date_To_From_CC_Newsgroups_*Subject*_/Tags/"
output))
-;; User-visible functions:
+;;; User-visible functions
(defun notmuch-print-lpr (msg)
"Print a message buffer using lpr."
(defun notmuch-print-lpr (msg)
"Print a message buffer using lpr."
(set-buffer-modified-p nil)
(funcall notmuch-print-mechanism msg))
(set-buffer-modified-p nil)
(funcall notmuch-print-mechanism msg))
(provide 'notmuch-print)
;;; notmuch-print.el ends here
(provide 'notmuch-print)
;;; notmuch-print.el ends here
+;;; Basic query function
+
(defun notmuch-query-get-threads (search-terms)
"Return a list of threads of messages matching SEARCH-TERMS.
(defun notmuch-query-get-threads (search-terms)
"Return a list of threads of messages matching SEARCH-TERMS.
(setq args (append args search-terms))
(apply #'notmuch-call-notmuch-sexp args)))
(setq args (append args search-terms))
(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)
"Private function to do the actual mapping and flattening."
(defun notmuch-query-map-aux (mapper function seq)
"Private function to do the actual mapping and flattening."
`notmuch-query-get-threads' for more information."
(cons (funcall fn (car tree)) (notmuch-query-map-forest fn (cadr tree))))
`notmuch-query-get-threads' for more information."
(cons (funcall fn (car tree)) (notmuch-query-map-forest fn (cadr tree))))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Predefined queries
(defun notmuch-query-get-message-ids (&rest search-terms)
"Return a list of message-ids of messages that match SEARCH-TERMS."
(defun notmuch-query-get-message-ids (&rest search-terms)
"Return a list of message-ids of messages that match SEARCH-TERMS."
(declare-function notmuch-read-query "notmuch" (prompt))
(declare-function notmuch-draft-resume "notmuch-draft" (id))
(declare-function notmuch-read-query "notmuch" (prompt))
(declare-function notmuch-draft-resume "notmuch-draft" (id))
(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
"Headers that should be shown in a message, in this order.
(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
"Headers that should be shown in a message, in this order.
:type '(choice (const nil) regexp)
:group 'notmuch-show)
:type '(choice (const nil) regexp)
:group 'notmuch-show)
(defvar-local notmuch-show-thread-id nil)
(defvar-local notmuch-show-parent-buffer nil)
(defvar-local notmuch-show-thread-id nil)
(defvar-local notmuch-show-parent-buffer nil)
each attachment handler is logged in buffers with names beginning
\" *notmuch-part*\".")
each attachment handler is logged in buffers with names beginning
\" *notmuch-part*\".")
(defcustom notmuch-show-stash-mlarchive-link-alist
'(("Gmane" . "https://mid.gmane.org/")
("MARC" . "https://marc.info/?i=")
(defcustom notmuch-show-stash-mlarchive-link-alist
'(("Gmane" . "https://mid.gmane.org/")
("MARC" . "https://marc.info/?i=")
:type 'boolean
:group 'notmuch-show)
:type 'boolean
:group 'notmuch-show)
(defmacro with-current-notmuch-show-message (&rest body)
"Evaluate body with current buffer set to the text of current message."
`(save-excursion
(defmacro with-current-notmuch-show-message (&rest body)
"Evaluate body with current buffer set to the text of current message."
`(save-excursion
"Enable Visual Line mode."
(visual-line-mode t))
"Enable Visual Line mode."
(visual-line-mode t))
;; DEPRECATED in Notmuch 0.16 since we now have convenient part
;; commands. We'll keep the command around for a version or two in
;; case people want to bind it themselves.
;; DEPRECATED in Notmuch 0.16 since we now have convenient part
;; commands. We'll keep the command around for a version or two in
;; case people want to bind it themselves.
(interactive)
(notmuch-show-with-message-as-text 'notmuch-print-message))
(interactive)
(notmuch-show-with-message-as-text 'notmuch-print-message))
(defun notmuch-show-fontify-header ()
(let ((face (cond
((looking-at "[Tt]o:")
(defun notmuch-show-fontify-header ()
(let ((face (cond
((looking-at "[Tt]o:")
(narrow-to-region start (point-max))
(run-hooks 'notmuch-show-markup-headers-hook)))))
(narrow-to-region start (point-max))
(run-hooks 'notmuch-show-markup-headers-hook)))))
(define-button-type 'notmuch-show-part-button-type
'action 'notmuch-show-part-button-default
'follow-link t
(define-button-type 'notmuch-show-part-button-type
'action 'notmuch-show-part-button-default
'follow-link t
(overlay-put overlay 'invisible (not show))
t)))))))
(overlay-put overlay 'invisible (not show))
t)))))))
-;; Part content ID handling
+;;; Part content ID handling
(defvar notmuch-show--cids nil
"Alist from raw content ID to (MSG PART).")
(defvar notmuch-show--cids nil
"Alist from raw content ID to (MSG PART).")
(gnus-blocked-images notmuch-show-text/html-blocked-images))
(notmuch-show-insert-part-*/* msg part content-type nth depth button))))
(gnus-blocked-images notmuch-show-text/html-blocked-images))
(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 shr-insert-document "shr")
(declare-function libxml-parse-html-region "xml.c")
(declare-function shr-insert-document "shr")
(notmuch-mm-display-part-inline msg part content-type notmuch-show-process-crypto)
t)
(notmuch-mm-display-part-inline msg part content-type notmuch-show-process-crypto)
t)
-;; Functions for determining how to handle MIME parts.
+;;; Functions for determining how to handle MIME parts.
(defun notmuch-show-handlers-for (content-type)
"Return a list of content handlers for a part of type CONTENT-TYPE."
(defun notmuch-show-handlers-for (content-type)
"Return a list of content handlers for a part of type CONTENT-TYPE."
(intern (concat "notmuch-show-insert-part-" content-type))))
result))
(intern (concat "notmuch-show-insert-part-" content-type))))
result))
(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth button)
;; Run the handlers until one of them succeeds.
(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth button)
;; Run the handlers until one of them succeeds.
(notmuch-show-message-visible msg (and (plist-get msg :match)
(not (plist-get msg :excluded))))))
(notmuch-show-message-visible msg (and (plist-get msg :match)
(not (plist-get msg :excluded))))))
(defun notmuch-show-toggle-process-crypto ()
"Toggle the processing of cryptographic MIME parts."
(interactive)
(defun notmuch-show-toggle-process-crypto ()
"Toggle the processing of cryptographic MIME parts."
(interactive)
"Content is not indented."))
(notmuch-show-refresh-view))
"Content is not indented."))
(notmuch-show-refresh-view))
+;;; Main insert functions
+
(defun notmuch-show-insert-tree (tree depth)
"Insert the message tree TREE at depth DEPTH in the current thread."
(let ((msg (car tree))
(defun notmuch-show-insert-tree (tree depth)
"Insert the message tree TREE at depth DEPTH in the current thread."
(let ((msg (car tree))
"Insert the forest of threads FOREST."
(mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))
"Insert the forest of threads FOREST."
(mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))
(defvar notmuch-id-regexp
(concat
;; Match the id: prefix only if it begins a word (to disallow, for
(defvar notmuch-id-regexp
(concat
;; Match the id: prefix only if it begins a word (to disallow, for
'help-echo "Mouse-1, RET: search for this message"
'face goto-address-mail-face)))))
'help-echo "Mouse-1, RET: search for this message"
'face goto-address-mail-face)))))
;;;###autoload
(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.
;;;###autoload
(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.
;; Report back to the caller whether any messages matched.
forest))
;; Report back to the caller whether any messages matched.
forest))
(defun notmuch-show-capture-state ()
"Capture the state of the current buffer.
(defun notmuch-show-capture-state ()
"Capture the state of the current buffer.
(ding)
(message "Refreshing the buffer resulted in no messages!"))))
(ding)
(message "Refreshing the buffer resulted in no messages!"))))
(defvar notmuch-show-stash-map
(let ((map (make-sparse-keymap)))
(define-key map "c" 'notmuch-show-stash-cc)
(defvar notmuch-show-stash-map
(let ((map (make-sparse-keymap)))
(define-key map "c" 'notmuch-show-stash-cc)
map)
"Keymap for \"notmuch show\" buffers.")
map)
"Keymap for \"notmuch show\" buffers.")
(define-derived-mode notmuch-show-mode fundamental-mode "notmuch-show"
"Major mode for viewing a thread with notmuch.
(define-derived-mode notmuch-show-mode fundamental-mode "notmuch-show"
"Major mode for viewing a thread with notmuch.
(setq imenu-extract-index-name-function
#'notmuch-show-imenu-extract-index-name-function))
(setq imenu-extract-index-name-function
#'notmuch-show-imenu-extract-index-name-function))
(defun notmuch-tree-from-show-current-query ()
"Call notmuch tree with the current query."
(interactive)
(defun notmuch-tree-from-show-current-query ()
"Call notmuch tree with the current query."
(interactive)
notmuch-show-query-context
(notmuch-show-get-message-id)))
notmuch-show-query-context
(notmuch-show-get-message-id)))
+;;; Movement related functions.
+
(defun notmuch-show-move-to-message-top ()
(goto-char (notmuch-show-message-top)))
(defun notmuch-show-move-to-message-bottom ()
(goto-char (notmuch-show-message-bottom)))
(defun notmuch-show-move-to-message-top ()
(goto-char (notmuch-show-message-top)))
(defun notmuch-show-move-to-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
;; region a->b is not found when point is at b. We walk backwards
;; until finding the property.
;; 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
;; until finding the property.
(cl-loop do (funcall function)
while (notmuch-show-goto-message-next))))
(cl-loop do (funcall function)
while (notmuch-show-goto-message-next))))
-;; Functions relating to the visibility of messages and their
-;; components.
+;;; Functions relating to the visibility of messages and their components.
(defun notmuch-show-message-visible (props visible-p)
(overlay-put (plist-get props :message-overlay) 'invisible (not 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 :headers-overlay) 'invisible (not visible-p))
(notmuch-show-set-prop :headers-visible visible-p props))
(overlay-put (plist-get props :headers-overlay) 'invisible (not visible-p))
(notmuch-show-set-prop :headers-visible visible-p props))
-;; Functions for setting and getting attributes of the current
-;; message.
+;;; Functions for setting and getting attributes of the current message.
(defun notmuch-show-set-message-properties (props)
(save-excursion
(defun notmuch-show-set-message-properties (props)
(save-excursion
(notmuch-show-refresh-view t)
(notmuch-show-goto-message msg-id)))
(notmuch-show-refresh-view t)
(notmuch-show-goto-message msg-id)))
-;; Functions for getting attributes of several messages in the current
-;; thread.
+;;; Functions for getting attributes of several messages in the current thread.
(defun notmuch-show-get-message-ids-for-open-messages ()
"Return a list of all id: queries for open messages in the current thread."
(defun notmuch-show-get-message-ids-for-open-messages ()
"Return a list of all id: queries for open messages in the current thread."
(setq done (not (notmuch-show-goto-message-next))))
message-ids)))
(setq done (not (notmuch-show-goto-message-next))))
message-ids)))
-;; Commands typically bound to keys.
+;;; Commands typically bound to keys.
(defun notmuch-show-advance ()
"Advance through thread.
(defun notmuch-show-advance ()
"Advance through thread.
(message-resend addresses)
(notmuch-bury-or-kill-this-buffer)))
(message-resend addresses)
(notmuch-bury-or-kill-this-buffer)))
+(defun notmuch-show-message-adjust ()
+ (recenter 0))
+
(defun notmuch-show-next-message (&optional pop-at-end)
"Show the next message.
(defun notmuch-show-next-message (&optional pop-at-end)
"Show the next message.
(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)
"Return a temporary buffer containing the specified part's content."
(defun notmuch-show-generate-part-buffer (msg part)
"Return a temporary buffer containing the specified part's content."
(funcall fn (completing-read prompt urls nil nil nil nil (car urls)))
(message "No URLs found."))))
(funcall fn (completing-read prompt urls nil nil nil nil (car urls)))
(message "No URLs found."))))
(provide 'notmuch-show)
;;; notmuch-show.el ends here
(provide 'notmuch-show)
;;; notmuch-show.el ends here
(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
(declare-function notmuch-tree-tag "notmuch-tree" (tag-changes))
(declare-function notmuch-jump "notmuch-jump" (action-map prompt))
(define-widget 'notmuch-tag-key-type 'list
"A single key tagging binding."
:format "%v"
(define-widget 'notmuch-tag-key-type 'list
"A single key tagging binding."
:format "%v"
:type '(repeat notmuch-tag-key-type)
:group 'notmuch-tag)
:type '(repeat notmuch-tag-key-type)
:group 'notmuch-tag)
(define-widget 'notmuch-tag-format-type 'lazy
"Customize widget for notmuch-tag-format and friends."
:type '(alist :key-type (regexp :tag "Tag")
(define-widget 'notmuch-tag-format-type 'lazy
"Customize widget for notmuch-tag-format and friends."
:type '(alist :key-type (regexp :tag "Tag")
:group 'notmuch-faces
:type 'notmuch-tag-format-type)
:group 'notmuch-faces
:type 'notmuch-tag-format-type)
(defun notmuch-tag-format-image-data (tag data)
"Replace TAG with image DATA, if available.
(defun notmuch-tag-format-image-data (tag data)
"Replace TAG with image DATA, if available.
(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
"Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
"Cache of tag format lookup. Internal to `notmuch-tag-format-tag'.")
(defcustom notmuch-before-tag-hook nil
"Hooks that are run before tags of a message are modified.
(defcustom notmuch-before-tag-hook nil
"Hooks that are run before tags of a message are modified.
:options '(notmuch-hl-line-mode)
:group 'notmuch-hooks)
:options '(notmuch-hl-line-mode)
:group 'notmuch-hooks)
(defvar notmuch-select-tag-history nil
"Variable to store minibuffer history for
`notmuch-select-tag-with-completion' function.")
(defvar notmuch-select-tag-history nil
"Variable to store minibuffer history for
`notmuch-select-tag-with-completion' function.")
nil nil initial-input
'notmuch-read-tag-changes-history))))
nil nil initial-input
'notmuch-read-tag-changes-history))))
(defun notmuch-update-tags (tags tag-changes)
"Return a copy of TAGS with additions and removals from TAG-CHANGES.
(defun notmuch-update-tags (tags tag-changes)
"Return a copy of TAGS with additions and removals from TAG-CHANGES.
(setq action-map (nreverse action-map))
(notmuch-jump action-map "Tag: ")))
(setq action-map (nreverse action-map))
(notmuch-jump action-map "Tag: ")))
(defvar-local notmuch-tree-unthreaded nil
"A buffer local copy of argument unthreaded to the function notmuch-tree.")
(defvar-local notmuch-tree-unthreaded nil
"A buffer local copy of argument unthreaded to the function notmuch-tree.")
(defgroup notmuch-tree nil
"Showing message and thread structure."
:group 'notmuch)
(defgroup notmuch-tree nil
"Showing message and thread structure."
:group 'notmuch)
notmuch-unthreaded-result-format
notmuch-tree-result-format))
notmuch-unthreaded-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
'((t :inherit default))
"Default face used in tree mode face for matching messages"
(defface notmuch-tree-match-face
'((t :inherit default))
"Default face used in tree mode face for matching messages"
:group 'notmuch-tree
:group 'notmuch-faces)
:group 'notmuch-tree
: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
'((t (:foreground "gray")))
"Default face used in tree mode face for non-matching messages."
(defface notmuch-tree-no-match-face
'((t (:foreground "gray")))
"Default face used in tree mode face for non-matching messages."
:group 'notmuch-tree
:group 'notmuch-faces)
:group 'notmuch-tree
:group 'notmuch-faces)
(defvar-local notmuch-tree-previous-subject
"The subject of the most recent result shown during the async display.")
(defvar-local notmuch-tree-previous-subject
"The subject of the most recent result shown during the async display.")
if the user has loaded a different buffer in that window.")
(put 'notmuch-tree-message-buffer 'permanent-local t)
if the user has loaded a different buffer in that window.")
(put 'notmuch-tree-message-buffer 'permanent-local t)
+;;; Tree wrapper commands
+
(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.
(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.
notmuch-tree-view-raw-message
notmuch-show-view-raw-message)
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)
(defvar notmuch-tree-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map notmuch-common-keymap)
map)
"Keymap for \"notmuch tree\" buffers.")
map)
"Keymap for \"notmuch tree\" buffers.")
+;;; Message properties
+
(defun notmuch-tree-get-message-properties ()
"Return the properties of the current message as a plist.
(defun notmuch-tree-get-message-properties ()
"Return the properties of the current message as a plist.
(interactive)
(notmuch-tree-get-prop :match))
(interactive)
(notmuch-tree-get-prop :match))
(defun notmuch-tree-refresh-result ()
"Redisplay the current message line.
(defun notmuch-tree-refresh-result ()
"Redisplay the current message line.
(when (string= tree-msg-id (notmuch-show-get-message-id))
(notmuch-show-update-tags new-tags)))))))
(when (string= tree-msg-id (notmuch-show-get-message-id))
(notmuch-show-update-tags new-tags)))))))
+;;; Commands (and some helper functions used by them)
+
(defun notmuch-tree-tag (tag-changes)
"Change tags for the current message."
(interactive
(defun notmuch-tree-tag (tag-changes)
"Change tags for the current message."
(interactive
(notmuch-tree-tag-thread
(notmuch-tag-change-list notmuch-archive-tags unarchive))))
(notmuch-tree-tag-thread
(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)
"Try to clean a single email ADDRESS for display. Return
(defun notmuch-tree-clean-address (address)
"Try to clean a single email ADDRESS for display. Return
(interactive)
(notmuch-tree query query-context target buffer-name open-target t))
(interactive)
(notmuch-tree query query-context target buffer-name open-target t))
(msg part depth &optional hide))
(defvar notmuch-show-indent-messages-width)
(msg part depth &optional hide))
(defvar notmuch-show-indent-messages-width)
(defgroup notmuch-wash nil
"Cleaning up messages for display."
(defgroup notmuch-wash nil
"Cleaning up messages for display."
(integer :tag "number of characters"))
:group 'notmuch-wash)
(integer :tag "number of characters"))
:group 'notmuch-wash)
(defface notmuch-wash-toggle-button
'((t (:inherit font-lock-comment-face)))
"Face used for buttons toggling the visibility of washed away
(defface notmuch-wash-toggle-button
'((t (:inherit font-lock-comment-face)))
"Face used for buttons toggling the visibility of washed away
:group 'notmuch-wash
:group 'notmuch-faces)
:group 'notmuch-wash
:group 'notmuch-faces)
(defun notmuch-wash-toggle-invisible-action (cite-button)
;; Toggle overlay visibility
(let ((overlay (button-get cite-button 'overlay)))
(defun notmuch-wash-toggle-invisible-action (cite-button)
;; Toggle overlay visibility
(let ((overlay (button-get cite-button 'overlay)))
:type button-type)))
(overlay-put overlay 'notmuch-wash-button button))))))
:type button-type)))
(overlay-put overlay 'notmuch-wash-button button))))))
(defun notmuch-wash-excerpt-citations (msg depth)
"Excerpt citations and up to one signature."
(goto-char (point-min))
(defun notmuch-wash-excerpt-citations (msg depth)
"Excerpt citations and up to one signature."
(goto-char (point-min))
msg sig-start-marker sig-end-marker
"signature"))))))
msg sig-start-marker sig-end-marker
"signature"))))))
(defun notmuch-wash-elide-blank-lines (msg depth)
"Elide leading, trailing and successive blank lines."
;; Algorithm derived from `article-strip-multiple-blank-lines' in
(defun notmuch-wash-elide-blank-lines (msg depth)
"Elide leading, trailing and successive blank lines."
;; Algorithm derived from `article-strip-multiple-blank-lines' in
(when (looking-at "\n")
(delete-region (match-beginning 0) (match-end 0))))
(when (looking-at "\n")
(delete-region (match-beginning 0) (match-end 0))))
(defun notmuch-wash-tidy-citations (msg depth)
"Improve the display of cited regions of a message.
(defun notmuch-wash-tidy-citations (msg depth)
"Improve the display of cited regions of a message.
(while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)
(replace-match "\\2")))
(while (re-search-forward "\\(^>[> ]*\n\\)\\(^$\\|^[^>].*\\)" nil t)
(replace-match "\\2")))
(defun notmuch-wash-wrap-long-lines (msg depth)
"Wrap long lines in the message.
(defun notmuch-wash-wrap-long-lines (msg depth)
"Wrap long lines in the message.
2)))
(coolj-wrap-region (point-min) (point-max))))
2)))
(coolj-wrap-region (point-min) (point-max))))
+;;;; Convert Inline Patches
(delete-region (point-min) (point-max))
(notmuch-show-insert-bodypart nil part depth)))))
(delete-region (point-min) (point-max))
(notmuch-show-insert-bodypart nil part depth)))))
(require 'notmuch-message)
(require 'notmuch-parser)
(require 'notmuch-message)
(require 'notmuch-parser)
(defcustom notmuch-search-result-format
`(("date" . "%12s ")
("count" . "%-7s ")
(defcustom notmuch-search-result-format
`(("date" . "%12s ")
("count" . "%-7s ")
(defvar notmuch-query-history nil
"Variable to store minibuffer history for notmuch queries.")
(defvar notmuch-query-history nil
"Variable to store minibuffer history for notmuch queries.")
(defun notmuch-foreach-mime-part (function mm-handle)
(cond ((stringp (car mm-handle))
(dolist (part (cdr mm-handle))
(defun notmuch-foreach-mime-part (function mm-handle)
(cond ((stringp (car mm-handle))
(dolist (part (cdr mm-handle))
(mm-save-part p))))
mm-handle))
(mm-save-part p))))
mm-handle))
(require 'hl-line)
(defun notmuch-hl-line-mode ()
(require 'hl-line)
(defun notmuch-hl-line-mode ()
(when hl-line-overlay
(overlay-put hl-line-overlay 'priority 1))))
(when hl-line-overlay
(overlay-put hl-line-overlay 'priority 1))))
(defcustom notmuch-search-hook '(notmuch-hl-line-mode)
"List of functions to call when notmuch displays the search results."
:type 'hook
(defcustom notmuch-search-hook '(notmuch-hl-line-mode)
"List of functions to call when notmuch displays the search results."
:type 'hook
:group 'notmuch-search
:group 'notmuch-hooks)
:group 'notmuch-search
:group 'notmuch-hooks)
(defvar notmuch-search-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map notmuch-common-keymap)
(defvar notmuch-search-mode-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map notmuch-common-keymap)
map)
"Keymap for \"notmuch search\" buffers.")
map)
"Keymap for \"notmuch search\" buffers.")
(defvar notmuch-search-stash-map
(let ((map (make-sparse-keymap)))
(define-key map "i" 'notmuch-search-stash-thread-id)
(defvar notmuch-search-stash-map
(let ((map (make-sparse-keymap)))
(define-key map "i" 'notmuch-search-stash-thread-id)
(interactive)
(notmuch-common-do-stash (notmuch-search-get-query)))
(interactive)
(notmuch-common-do-stash (notmuch-search-get-query)))
(defvar notmuch-search-query-string)
(defvar notmuch-search-target-thread)
(defvar notmuch-search-target-line)
(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>")
(defvar notmuch-search-query-string)
(defvar notmuch-search-target-thread)
(defvar notmuch-search-target-line)
(defvar notmuch-search-disjunctive-regexp "\\<[oO][rR]\\>")
(defun notmuch-search-scroll-up ()
"Move forward through search results by one window's worth."
(interactive)
(defun notmuch-search-scroll-up ()
"Move forward through search results by one window's worth."
(interactive)
(interactive)
(goto-char (point-min)))
(interactive)
(goto-char (point-min)))
(defface notmuch-message-summary-face
`((((class color) (background light))
,@(and (>= emacs-major-version 27) '(:extend t))
(defface notmuch-message-summary-face
`((((class color) (background light))
,@(and (>= emacs-major-version 27) '(:extend t))
:group 'notmuch-search
:group 'notmuch-faces)
:group 'notmuch-search
:group 'notmuch-faces)
(define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
"Major mode displaying results of a notmuch search.
(define-derived-mode notmuch-search-mode fundamental-mode "notmuch-search"
"Major mode displaying results of a notmuch search.
(setq imenu-extract-index-name-function
#'notmuch-search-imenu-extract-index-name-function))
(setq imenu-extract-index-name-function
#'notmuch-search-imenu-extract-index-name-function))
(defun notmuch-search-get-result (&optional pos)
"Return the result object for the thread at POS (or point).
(defun notmuch-search-get-result (&optional pos)
"Return the result object for the thread at POS (or point).
(let ((message-id (notmuch-search-find-thread-id)))
(notmuch-mua-new-reply message-id prompt-for-sender nil)))
(let ((message-id (notmuch-search-find-thread-id)))
(notmuch-mua-new-reply message-id prompt-for-sender nil)))
(defun notmuch-search-set-tags (tags &optional pos)
(let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
(notmuch-search-update-result new-result pos)))
(defun notmuch-search-set-tags (tags &optional pos)
(let ((new-result (plist-put (notmuch-search-get-result pos) :tags tags)))
(notmuch-search-update-result new-result pos)))
(when (eq beg end)
(notmuch-search-next-thread)))
(when (eq beg end)
(notmuch-search-next-thread)))
(defun notmuch-search-update-result (result &optional pos)
"Replace the result object of the thread at POS (or point) by
RESULT and redraw it.
(defun notmuch-search-update-result (result &optional pos)
"Replace the result object of the thread at POS (or point) by
RESULT and redraw it.
(notmuch-sexp-parse-partial-list 'notmuch-search-append-result
results-buf)))))
(notmuch-sexp-parse-partial-list 'notmuch-search-append-result
results-buf)))))
+;;; Commands (and some helper functions used by them)
+
(defun notmuch-search-tag-all (tag-changes)
"Add/remove tags from all messages in current search buffer.
(defun notmuch-search-tag-all (tag-changes)
"Add/remove tags from all messages in current search buffer.
(pop-to-buffer-same-window first))
(notmuch))))
(pop-to-buffer-same-window first))
(notmuch))))
(defun notmuch-search-imenu-prev-index-position-function ()
"Move point to previous message in notmuch-search buffer.
(defun notmuch-search-imenu-prev-index-position-function ()
"Move point to previous message in notmuch-search buffer.
(author (notmuch-search-find-authors)))
(format "%s (%s)" subject author)))
(author (notmuch-search-find-authors)))
(format "%s (%s)" subject author)))
(setq mail-user-agent 'notmuch-user-agent)
(provide 'notmuch)
(setq mail-user-agent 'notmuch-user-agent)
(provide 'notmuch)
-;; test-lib.el --- auxiliary stuff for Notmuch Emacs tests.
+;;; test-lib.el --- auxiliary stuff for Notmuch Emacs tests
;;
;; Copyright © Carl Worth
;; Copyright © David Edmondson
;;
;; Copyright © Carl Worth
;; Copyright © David Edmondson
;;
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
;;
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
(require 'cl-lib)
;; Ensure that the dynamic variables that are defined by this library
(require 'cl-lib)
;; Ensure that the dynamic variables that are defined by this library